Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(user registration): resolve registration bug
Browse files Browse the repository at this point in the history
- ensure that a user provide neccessary inputs
- restructure user entity
- refactor other codes depending on user registration logic

[Fixes #39]
aimedivin committed May 3, 2024
1 parent b775d65 commit d9dbd1b
Showing 18 changed files with 240 additions and 206 deletions.
13 changes: 10 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
PORT= ********************************
APP_ENV= ********************************
PDN_DB_NAME= *****************************

TEST_DB_HOST= ********************************
TEST_DB_PORT= ********************************
TEST_DB_USER= ********************************
TEST_DB_PASS= ********************************
TEST_DB_NAME= ********************************

DEV_DB_HOST= ********************************
DEV_DB_PORT= ********************************
DEV_DB_USER= ********************************
DEV_DB_PASS= *****************************
DEV_DB_TYPE= *******************************
DEV_DB_NAME= *******************************

PDN_DB_HOST= ********************************
PDN_DB_PORT= ********************************
PDN_DB_USER= ********************************
PDN_DB_PASS= ********************************
PDN_DB_PASS= ********************************
PDN_DB_NAME= *****************************
15 changes: 9 additions & 6 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -3,10 +3,7 @@ module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended'
],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': [
@@ -28,8 +25,14 @@ module.exports = {
'space-before-function-paren': ['warn', 'always'],
'func-style': ['warn', 'declaration', { allowArrowFunctions: true }],
'camelcase': 'warn',
'@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }],
'@typescript-eslint/explicit-member-accessibility': ['off', { accessibility: 'explicit' }],
'@typescript-eslint/explicit-function-return-type': [
'warn',
{ allowExpressions: true },
],
'@typescript-eslint/explicit-member-accessibility': [
'off',
{ accessibility: 'explicit' },
],
'no-unused-vars': 'warn',
'no-extra-semi': 'warn',
},
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -3,11 +3,11 @@ name: knights-ecomm-be CI
on: [push, pull_request]

env:
DEV_DB_HOST: ${{secrets.DEV_DB_HOST}}
DEV_DB_PORT: ${{secrets.DEV_DB_PORT}}
DEV_DB_USER: ${{secrets.DEV_DB_USER}}
DEV_DB_PASS: ${{secrets.DEV_DB_PASS}}
DEV_DB_NAME: ${{secrets.DEV_DB_NAME}}
TEST_DB_HOST: ${{secrets.TEST_DB_HOST}}
TEST_DB_PORT: ${{secrets.TEST_DB_PORT}}
TEST_DB_USER: ${{secrets.TEST_DB_USER}}
TEST_DB_PASS: ${{secrets.TEST_DB_PASS}}
TEST_DB_NAME: ${{secrets.TEST_DB_NAME}}

jobs:
build-lint-test-coverage:
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# E-commerse Backend API
[![knights-ecomm-be CI](https://github.com/atlp-rwanda/knights-ecomm-be/actions/workflows/ci.yml/badge.svg)](https://github.com/atlp-rwanda/knights-ecomm-be/actions/workflows/ci.yml)    [![Coverage Status](https://coveralls.io/repos/github/atlp-rwanda/knights-ecomm-be/badge.svg?branch=ch-ci-setup)](https://coveralls.io/github/atlp-rwanda/knights-ecomm-be?branch=ch-ci-setup)    [![Version](https://img.shields.io/badge/version-1.0.0-blue)](https://github.com/your-username/your-repo-name/releases/tag/v1.0.0)

[![knights-ecomm-be CI](https://github.com/atlp-rwanda/knights-ecomm-be/actions/workflows/ci.yml/badge.svg)](https://github.com/atlp-rwanda/knights-ecomm-be/actions/workflows/ci.yml)
  
[![Coverage Status](https://coveralls.io/repos/github/atlp-rwanda/knights-ecomm-be/badge.svg?branch=ch-ci-setup)](https://coveralls.io/github/atlp-rwanda/knights-ecomm-be?branch=ch-ci-setup)
  
[![Version](https://img.shields.io/badge/version-1.0.0-blue)](https://github.com/your-username/your-repo-name/releases/tag/v1.0.0)

## Description

18 changes: 8 additions & 10 deletions migrations/1714595134552-UserMigration.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { MigrationInterface, QueryRunner } from "typeorm";
import { MigrationInterface, QueryRunner } from 'typeorm';

export class CreateUserMigration1614495123940 implements MigrationInterface {

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
public async up (queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
CREATE TABLE "user" (
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
"firstName" character varying NOT NULL,
@@ -22,10 +21,9 @@ export class CreateUserMigration1614495123940 implements MigrationInterface {
CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id")
)
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "user"`);
}
}

}
public async down (queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "user"`);
}
}
63 changes: 39 additions & 24 deletions ormconfig.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
module.exports = {
"type": "postgres",
"host": `${process.env.DEV_DB_HOST}`,
"port": `${process.env.DEV_DB_PORT}`,
"username": `${process.env.DEV_DB_USER}`,
"password": `${process.env.DEV_DB_PASS}`,
"database": `${process.env.DEV_DB_NAME}`,
"synchronize": true,
"logging": false,
"entities": [
"src/entities/**/*.ts"
],
"migrations": [
"src/migrations/**/*.ts"
],
"subscribers": [
"src/subscribers/**/*.ts"
],
"cli": {
"entitiesDir": "src/entities",
"migrationsDir": "src/migrations",
"subscribersDir": "src/subscribers"
}
};
const devConfig = {
type: 'postgres',
host: process.env.DEV_DB_HOST,
port: process.env.DEV_DB_PORT,
username: process.env.DEV_DB_USER,
password: process.env.DEV_DB_PASS,
database: process.env.DEV_DB_NAME,
synchronize: true,
logging: false,
entities: ['src/entities/**/*.ts'],
migrations: ['src/migrations/**/*.ts'],
subscribers: ['src/subscribers/**/*.ts'],
cli: {
entitiesDir: 'src/entities',
migrationsDir: 'src/migrations',
subscribersDir: 'src/subscribers',
},
};

const testConfig = {
type: 'postgres',
host: process.env.TEST_DB_HOST,
port: process.env.TEST_DB_PORT,
username: process.env.TEST_DB_USER,
password: process.env.TEST_DB_PASS,
database: process.env.TEST_DB_NAME,
synchronize: true,
logging: false,
entities: ['src/entities/**/*.ts'],
migrations: ['src/migrations/**/*.ts'],
subscribers: ['src/subscribers/**/*.ts'],
cli: {
entitiesDir: 'src/entities',
migrationsDir: 'src/migrations',
subscribersDir: 'src/subscribers',
},
};

module.exports = process.env.NODE_ENV === 'test' ? testConfig : devConfig;
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@
"description": "E-commerce backend",
"main": "index.js",
"scripts": {
"test": "jest --coverage --detectOpenHandles --verbose --runInBand",
"dev": "nodemon src/index.ts",
"test": "cross-env APP_ENV=test jest --coverage --detectOpenHandles --verbose --runInBand ",
"dev": "cross-env APP_ENV=dev nodemon src/index.ts",
"build": "tsc -p .",
"start": "node dist/index.js",
"lint": "eslint .",
@@ -24,6 +24,7 @@
"bcrypt": "^5.1.1",
"class-validator": "^0.14.1",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-winston": "^4.2.0",
@@ -75,4 +76,4 @@
"typescript": "^5.4.5",
"typescript-eslint": "^7.7.1"
}
}
}
58 changes: 31 additions & 27 deletions src/__test__/route.test.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
import request from 'supertest';
import { app, server } from '../index'; // update this with the path to your app file
import { app, server } from '../index';
import { createConnection, getConnection, getConnectionOptions } from 'typeorm';
import { User } from '../entities/User';
import { getRepository, Repository } from 'typeorm';

beforeAll(async () => {
// Connect to the test database
const connectionOptions = await getConnectionOptions();

await createConnection({ ...connectionOptions, name: 'testConnection' });
});

afterAll(async () => {
await getConnection('testConnection').close();
server.close();
});
const connection = getConnection('testConnection');
const userRepository = connection.getRepository(User);

// Delete all records from the User
await userRepository.clear();

// Close the connection to the test database
await connection.close();

server.close();
});

describe('GET /', () => {
it('This is a testing route that returns', done => {
request(app)
.get('/api/v1/status')
.expect(200)
.expect('Content-Type', /json/)
.expect({
status: 'success',
data: {
code: 202,
message: 'This is a testing route that returns: 202'
}
}, done);
.expect(
{
status: 'success',
data: {
code: 200,
message: 'This is a testing route.',
},
},
done
);
});
});
describe('POST /user/register', () => {
it('should register a new user and then delete it', async () => {
it('should register a new user', async () => {
// Arrange
const newUser = {
firstName: 'John',
@@ -43,25 +52,20 @@ describe('POST /user/register', () => {
gender: 'Male',
phoneNumber: '1234567890',
userType: 'Buyer',
status: 'active',
verified: true,
photoUrl: 'https://example.com/photo.jpg',
};

// Act
const res = await request(app)
.post('/user/register')
.send(newUser);
const res = await request(app).post('/user/register').send(newUser);

// Assert
expect(res.status).toBe(201);
expect(res.body).toEqual({ message: 'User registered successfully' });

// Clean up: delete the test user
const userRepository = getRepository(User);
const user = await userRepository.findOne({ where: { email: newUser.email } });
if (user) {
await userRepository.remove(user);
}
expect(res.body).toEqual({
status: 'success',
data: {
code: 201,
message: 'User registered successfully',
},
});
});
});
});
91 changes: 48 additions & 43 deletions src/controllers/authController.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,54 @@
import { Request, Response } from 'express';
import { User } from '../entities/User';;
import { User } from '../entities/User';
import bcrypt from 'bcrypt';
import { getRepository } from 'typeorm';

import { responseError, responseServerError, responseSuccess } from '../utils/response.utils';
import { validate } from 'class-validator';

Check warning on line 6 in src/controllers/authController.ts

GitHub Actions / build-lint-test-coverage

'validate' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 6 in src/controllers/authController.ts

GitHub Actions / build-lint-test-coverage

'validate' is defined but never used

Check warning on line 6 in src/controllers/authController.ts

GitHub Actions / build-lint-test-coverage

'validate' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 6 in src/controllers/authController.ts

GitHub Actions / build-lint-test-coverage

'validate' is defined but never used

class UserController {
static registerUser = async (req: Request, res: Response) => {
const { firstName, lastName, email, password, gender, phoneNumber, userType, status, verified, photoUrl } = req.body;

// Validate user input
if (!(firstName && lastName && email && password && gender && phoneNumber && verified && photoUrl)) {
return res.status(400).json({ error: 'Please fill all the fields' });
}

const userRepository = getRepository(User);


// Check for existing user
const existingUser = await userRepository.findOneBy({ email });
const existingUserNumber = await userRepository.findOneBy({ phoneNumber });

if (existingUser || existingUserNumber) {
return res.status(400).json({ error: 'Email or phone number already in use' });
}

const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Create user
const user = new User();
user.firstName = firstName;
user.lastName = lastName;
user.email = email;
user.password = hashedPassword;
user.userType = userType;
user.gender = gender;
user.phoneNumber = phoneNumber;
user.photoUrl = photoUrl;
user.status = status ? status : 'active';
user.verified = verified;

// Save user
await userRepository.save(user);

return res.status(201).json({ message: 'User registered successfully' });
};
static registerUser = async (req: Request, res: Response) => {

Check warning on line 9 in src/controllers/authController.ts

GitHub Actions / build-lint-test-coverage

Missing return type on function

Check warning on line 9 in src/controllers/authController.ts

GitHub Actions / build-lint-test-coverage

Missing return type on function
const { firstName, lastName, email, password, gender, phoneNumber, userType } = req.body;

// Validate user input
if (!firstName || !lastName || !email || !password || !gender || !phoneNumber) {
return responseError(res, 400, 'Please fill all the required fields');
}

const userRepository = getRepository(User);

try {
// Check for existing user
const existingUser = await userRepository.findOneBy({ email });
const existingUserNumber = await userRepository.findOneBy({ phoneNumber });

if (existingUser || existingUserNumber) {
return responseError(res, 409, 'Email or phone number already in use');
}

const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Create user
const user = new User();
user.firstName = firstName;
user.lastName = lastName;
user.email = email;
user.password = hashedPassword;
user.userType = userType;
user.gender = gender;
user.phoneNumber = phoneNumber;

// Save user
await userRepository.save(user);

return responseSuccess(res, 201, 'User registered successfully');
} catch (error) {
if (error instanceof Error) {
return responseServerError(res, error.message);
}

return responseServerError(res, 'Unknown error occurred');
}
};
}
export { UserController };
export { UserController };
2 changes: 1 addition & 1 deletion src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { UserController } from './authController';

export{UserController};
export { UserController };
131 changes: 62 additions & 69 deletions src/entities/User.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,62 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
Unique,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';
import { IsEmail, IsNotEmpty, IsString, IsBoolean, IsIn } from 'class-validator';

@Entity()
@Unique(['email'])
export class User {
@PrimaryGeneratedColumn('uuid')
@IsNotEmpty()
id!: string;

@Column()
@IsNotEmpty()
@IsString()
firstName!: string;

@Column()
@IsNotEmpty()
@IsString()
lastName!: string;

@Column()
@IsNotEmpty()
@IsEmail()
email!: string;

@Column()
@IsNotEmpty()
password!: string;

@Column()
@IsNotEmpty()
@IsString()
gender!: string;

@Column()
@IsNotEmpty()
phoneNumber!: string;

@Column({ nullable: true })
photoUrl?: string;

@Column()
@IsNotEmpty()
@IsBoolean()
verified!: boolean;

@Column()
@IsNotEmpty()
@IsIn(['active', 'suspended'])
status!: 'active' | 'suspended';

@Column({ default: "Buyer" })
@IsNotEmpty()
@IsIn(['Admin', 'Buyer', 'Vendor'])
userType!: 'Admin' | 'Buyer' | 'Vendor';

@CreateDateColumn()
createdAt!: Date;

@UpdateDateColumn()
updatedAt!: Date;
}
import { Entity, PrimaryGeneratedColumn, Column, Unique, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { IsEmail, IsNotEmpty, IsString, IsBoolean, IsIn } from 'class-validator';

@Entity()
@Unique(['email'])
export class User {
@PrimaryGeneratedColumn('uuid')
@IsNotEmpty()
id!: string;

@Column()
@IsNotEmpty()
@IsString()
firstName!: string;

@Column()
@IsNotEmpty()
@IsString()
lastName!: string;

@Column()
@IsNotEmpty()
@IsEmail()
email!: string;

@Column()
@IsNotEmpty()
password!: string;

@Column()
@IsNotEmpty()
@IsString()
gender!: string;

@Column()
@IsNotEmpty()
phoneNumber!: string;

@Column({ nullable: true })
photoUrl?: string;

@Column({ default: false })
@IsNotEmpty()
@IsBoolean()
isVerified!: boolean;

@Column({ default: 'active' })
@IsNotEmpty()
@IsIn(['active', 'suspended'])
status!: 'active' | 'suspended';

@Column({ default: 'Buyer' })
@IsNotEmpty()
@IsIn(['Admin', 'Buyer', 'Vendor'])
userType!: 'Admin' | 'Buyer' | 'Vendor';

@CreateDateColumn()
createdAt!: Date;

@UpdateDateColumn()
updatedAt!: Date;
}
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
import { addDocumentation } from './startups/docs';
import 'reflect-metadata';


import { CustomError, errorHandler } from './middlewares/errorHandler';
import morgan from 'morgan';
import { dbConnection } from './startups/dbConnection';
@@ -18,7 +17,7 @@
app.use(cors({ origin: '*' }));
app.use(router);
addDocumentation(app);
app.all('*', (req: Request, res: Response, next) => {

Check warning on line 20 in src/index.ts

GitHub Actions / build-lint-test-coverage

'res' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 20 in src/index.ts

GitHub Actions / build-lint-test-coverage

'res' is defined but never used. Allowed unused args must match /^_/u
const error = new CustomError(`Can't find ${req.originalUrl} on the server!`, 404);
error.status = 'fail';
next(error);
@@ -26,6 +25,7 @@
app.use(errorHandler);

// Start database connection

dbConnection();

//morgan
@@ -34,4 +34,4 @@

export const server = app.listen(port, () => {
console.log(`[server]: Server is running at http://localhost:${port}`);
});
});
2 changes: 1 addition & 1 deletion src/middlewares/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
}
}

const errorHandler = (err: CustomError, req: Request, res: Response,next: NextFunction) => {
const errorHandler = (err: CustomError, req: Request, res: Response, next: NextFunction) => {

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

'req' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

'next' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

'next' is defined but never used

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

Missing return type on function

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

'req' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

'next' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

'next' is defined but never used

Check warning on line 15 in src/middlewares/errorHandler.ts

GitHub Actions / build-lint-test-coverage

Missing return type on function
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
res.status(err.statusCode).json({
5 changes: 2 additions & 3 deletions src/routes/UserRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Router } from 'express';
import { Router } from 'express';
import { UserController } from '../controllers/index';


const { registerUser } = UserController;

const router = Router();

router.post('/register', registerUser);

export default router;
export default router;
2 changes: 1 addition & 1 deletion src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@

const router = Router();

router.get('/api/v1/status', (req: Request, res: Response) => {

Check warning on line 7 in src/routes/index.ts

GitHub Actions / build-lint-test-coverage

'req' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 7 in src/routes/index.ts

GitHub Actions / build-lint-test-coverage

'req' is defined but never used. Allowed unused args must match /^_/u
return responseSuccess(res, 202, 'This is a testing route that returns: 202');
return responseSuccess(res, 200, 'This is a testing route.');
});

router.use('/user', userRoutes);
5 changes: 3 additions & 2 deletions src/startups/dbConnection.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { createConnection } from "typeorm";
import { createConnection } from 'typeorm';

const dbConnection = async () => {

Check warning on line 3 in src/startups/dbConnection.ts

GitHub Actions / build-lint-test-coverage

Missing return type on function

Check warning on line 3 in src/startups/dbConnection.ts

GitHub Actions / build-lint-test-coverage

Missing return type on function
try {
const connection = await createConnection();
console.log('Connected to the database');
console.log(`Connected to the ${process.env.APP_ENV} database`);
return connection;
} catch (error) {
console.error('Error connecting to the database:', error);
}
4 changes: 2 additions & 2 deletions src/utils/response.utils.ts
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ export const responseSuccess = (
message: string,
data?: any
): Response<ApiResponse> => {
return res.status(200).json(
return res.status(statusCode).json(
jsend.success({
code: statusCode,
message,
@@ -28,7 +28,7 @@ export const responseError = (
message: string,
data?: any
): Response<ApiResponse> => {
return res.status(400).json(
return res.status(statusCode).json(
jsend.error({
code: statusCode,
message,
9 changes: 6 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
"experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
"emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
"experimentalDecorators": true /* Enable experimental support for legacy experimental decorators. */,
"emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */,
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
@@ -29,7 +29,10 @@
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
"types": ["node", "jest"] /* Specify type package names to be included without being referenced in a source file. */,
"types": [
"node",
"jest"
] /* Specify type package names to be included without being referenced in a source file. */,
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */

0 comments on commit d9dbd1b

Please sign in to comment.