express-generator-typescript 2.4.14 → 2.4.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/express-generator-typescript.js +1 -1
- package/lib/project-files/.eslintignore +1 -0
- package/lib/project-files/README.md +3 -11
- package/lib/project-files/dotenv.config.js +16 -0
- package/lib/project-files/nodemon.json +10 -0
- package/lib/project-files/nodemon.spec.json +6 -0
- package/lib/project-files/package.json +6 -15
- package/lib/project-files/spec/index.ts +3 -24
- package/lib/project-files/spec/tests/users.spec.ts +3 -3
- package/lib/project-files/src/common/classes.ts +32 -0
- package/lib/project-files/src/index.ts +0 -1
- package/lib/project-files/src/models/User.ts +4 -5
- package/lib/project-files/src/routes/UserRoutes.ts +8 -7
- package/lib/project-files/src/routes/common/check.ts +143 -0
- package/lib/project-files/src/routes/common/types.ts +3 -7
- package/lib/project-files/src/routes/index.ts +6 -29
- package/lib/project-files/src/server.ts +1 -1
- package/lib/project-files/src/services/UserService.ts +1 -1
- package/lib/project-files-auth/.eslintignore +1 -0
- package/lib/project-files-auth/README.md +3 -11
- package/lib/project-files-auth/build.ts +2 -2
- package/lib/project-files-auth/dotenv.config.js +16 -0
- package/lib/project-files-auth/nodemon.json +10 -0
- package/lib/project-files-auth/nodemon.spec.json +6 -0
- package/lib/project-files-auth/package.json +6 -15
- package/lib/project-files-auth/spec/index.ts +3 -24
- package/lib/project-files-auth/spec/tests/users.spec.ts +3 -3
- package/lib/project-files-auth/src/common/classes.ts +31 -0
- package/lib/project-files-auth/src/index.ts +0 -1
- package/lib/project-files-auth/src/models/User.ts +2 -3
- package/lib/project-files-auth/src/routes/AuthRoutes.ts +4 -12
- package/lib/project-files-auth/src/routes/UserRoutes.ts +8 -6
- package/lib/project-files-auth/src/routes/common/check.ts +143 -0
- package/lib/project-files-auth/src/routes/common/types.ts +4 -31
- package/lib/project-files-auth/src/routes/index.ts +11 -44
- package/lib/project-files-auth/src/server.ts +3 -3
- package/lib/project-files-auth/src/services/AuthService.ts +1 -1
- package/lib/project-files-auth/src/services/UserService.ts +1 -1
- package/lib/project-files-auth/src/util/SessionUtil.ts +6 -6
- package/package.json +1 -1
- package/lib/project-files/spec/nodemon.json +0 -6
- package/lib/project-files/src/common/RouteError.ts +0 -20
- package/lib/project-files/src/pre-start.ts +0 -37
- package/lib/project-files-auth/src/common/RouteError.ts +0 -20
- package/lib/project-files-auth/src/pre-start.ts +0 -37
|
@@ -20,7 +20,7 @@ const PROJECT_FOLDER_PATH = './project-files';
|
|
|
20
20
|
// Project-folder dependencies
|
|
21
21
|
const DEPENDENCIES = 'express dotenv morgan cookie-parser jet-logger ' +
|
|
22
22
|
'module-alias express-async-errors helmet jsonfile inserturlparams ' +
|
|
23
|
-
'
|
|
23
|
+
'ts-command-line-args jet-paths moment',
|
|
24
24
|
DEPENDENCIES_AUTH = ' bcrypt jsonwebtoken',
|
|
25
25
|
DEV_DEPENDENCIES = 'ts-node typescript nodemon find jasmine supertest ' +
|
|
26
26
|
'@types/node @types/express @types/jasmine @types/find @types/morgan ' +
|
|
@@ -5,22 +5,18 @@ This project was created with [express-generator-typescript](https://github.com/
|
|
|
5
5
|
|
|
6
6
|
## Available Scripts
|
|
7
7
|
|
|
8
|
-
### `npm run dev`
|
|
8
|
+
### `npm run dev` or `npm run dev:hot` (hot reloading)
|
|
9
9
|
|
|
10
10
|
Run the server in development mode.
|
|
11
11
|
|
|
12
|
-
### `npm test`
|
|
12
|
+
### `npm test` or `npm run test:hot` (hot reloading)
|
|
13
13
|
|
|
14
|
-
Run all unit-tests
|
|
14
|
+
Run all unit-tests.
|
|
15
15
|
|
|
16
16
|
### `npm test -- --testFile="name of test file" (i.e. --testFile=Users).`
|
|
17
17
|
|
|
18
18
|
Run a single unit-test.
|
|
19
19
|
|
|
20
|
-
### `npm run test:no-reloading`
|
|
21
|
-
|
|
22
|
-
Run all unit-tests without hot-reloading.
|
|
23
|
-
|
|
24
20
|
### `npm run lint`
|
|
25
21
|
|
|
26
22
|
Check for linting errors.
|
|
@@ -33,10 +29,6 @@ Build the project for production.
|
|
|
33
29
|
|
|
34
30
|
Run the production build (Must be built first).
|
|
35
31
|
|
|
36
|
-
### `npm start -- --env="name of env file" (default is production).`
|
|
37
|
-
|
|
38
|
-
Run production build with a different env file.
|
|
39
|
-
|
|
40
32
|
|
|
41
33
|
## Additional Notes
|
|
42
34
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var dotenv = require('dotenv');
|
|
2
|
+
var path = require('path');
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// Check the env
|
|
6
|
+
var NODE_ENV = process.env.NODE_ENV || 'development';
|
|
7
|
+
|
|
8
|
+
// Configure the file
|
|
9
|
+
const result2 = dotenv.config({
|
|
10
|
+
path: path.join(__dirname, `./env/${NODE_ENV}.env`),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Check for errors
|
|
14
|
+
if (result2.error) {
|
|
15
|
+
throw result2.error;
|
|
16
|
+
}
|
|
@@ -2,23 +2,15 @@
|
|
|
2
2
|
"name": "express-typescript-example",
|
|
3
3
|
"version": "0.0.0",
|
|
4
4
|
"scripts": {
|
|
5
|
+
"_ts": "./node_modules/.bin/ts-node --files -r tsconfig-paths/register -r ./dotenv.config.js",
|
|
5
6
|
"build": "npx ts-node build.ts",
|
|
7
|
+
"dev": "npm run _ts -- ./src",
|
|
8
|
+
"dev:hot": "nodemon",
|
|
6
9
|
"lint": "npx eslint --ext .ts src/",
|
|
7
10
|
"lint:tests": "npx eslint --ext .ts spec/",
|
|
8
|
-
"start": "node -r module-alias/register ./dist
|
|
9
|
-
"
|
|
10
|
-
"test": "nodemon --config ./
|
|
11
|
-
"test:no-reloading": "npx ts-node --files -r tsconfig-paths/register ./spec"
|
|
12
|
-
},
|
|
13
|
-
"nodemonConfig": {
|
|
14
|
-
"watch": [
|
|
15
|
-
"src"
|
|
16
|
-
],
|
|
17
|
-
"ext": "ts, html",
|
|
18
|
-
"ignore": [
|
|
19
|
-
"src/public"
|
|
20
|
-
],
|
|
21
|
-
"exec": "./node_modules/.bin/ts-node --files -r tsconfig-paths/register ./src"
|
|
11
|
+
"start": "NODE_ENV=production node -r module-alias/register -r ./dotenv.config.js ./dist",
|
|
12
|
+
"test": "NODE_ENV=test npm run _ts -- ./spec",
|
|
13
|
+
"test:hot": "nodemon --config ./nodemon.spec.json"
|
|
22
14
|
},
|
|
23
15
|
"_moduleAliases": {
|
|
24
16
|
"@src": "dist"
|
|
@@ -36,7 +28,6 @@
|
|
|
36
28
|
"inserturlparams": "^1.0.1",
|
|
37
29
|
"jet-logger": "^1.3.1",
|
|
38
30
|
"jet-paths": "^1.0.5",
|
|
39
|
-
"jet-validator": "^1.0.3",
|
|
40
31
|
"jsonfile": "^6.1.0",
|
|
41
32
|
"jsonwebtoken": "^8.5.1",
|
|
42
33
|
"module-alias": "^2.2.2",
|
|
@@ -1,40 +1,19 @@
|
|
|
1
|
-
import dotenv from 'dotenv';
|
|
2
1
|
import find from 'find';
|
|
3
2
|
import Jasmine from 'jasmine';
|
|
4
3
|
import { parse } from 'ts-command-line-args';
|
|
5
4
|
import logger from 'jet-logger';
|
|
6
5
|
|
|
7
6
|
|
|
8
|
-
// **** Types **** //
|
|
9
|
-
|
|
10
|
-
interface IArgs {
|
|
11
|
-
testFile: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// **** Setup **** //
|
|
16
|
-
|
|
17
|
-
// ** Init ** //
|
|
18
|
-
|
|
19
|
-
// NOTE: MUST BE FIRST!! Load env vars
|
|
20
|
-
const result2 = dotenv.config({
|
|
21
|
-
path: './env/test.env',
|
|
22
|
-
});
|
|
23
|
-
if (result2.error) {
|
|
24
|
-
throw result2.error;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
7
|
// Setup command line options.
|
|
28
|
-
const args = parse<
|
|
8
|
+
const args = parse<{
|
|
9
|
+
testFile: string;
|
|
10
|
+
}>({
|
|
29
11
|
testFile: {
|
|
30
12
|
type: String,
|
|
31
13
|
defaultValue: '',
|
|
32
14
|
},
|
|
33
15
|
});
|
|
34
16
|
|
|
35
|
-
|
|
36
|
-
// ** Start Jasmine ** //
|
|
37
|
-
|
|
38
17
|
// Init Jasmine
|
|
39
18
|
const jasmine = new Jasmine();
|
|
40
19
|
jasmine.exitOnCompletion = false;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import supertest, { Test } from 'supertest';
|
|
2
2
|
import TestAgent from 'supertest/lib/agent';
|
|
3
|
-
import { defaultErrMsg as ValidatorErr } from 'jet-validator';
|
|
4
3
|
import insertUrlParams from 'inserturlparams';
|
|
5
4
|
|
|
6
5
|
import app from '@src/server';
|
|
@@ -13,6 +12,7 @@ import { USER_NOT_FOUND_ERR } from '@src/services/UserService';
|
|
|
13
12
|
import Paths from 'spec/support/Paths';
|
|
14
13
|
import apiCb from 'spec/support/apiCb';
|
|
15
14
|
import { TApiCb } from 'spec/types/misc';
|
|
15
|
+
import { ValidationErr } from '@src/common/classes';
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
// Dummy users for GET req
|
|
@@ -63,7 +63,7 @@ describe('UserRouter', () => {
|
|
|
63
63
|
// Test add user
|
|
64
64
|
describe(`"POST:${Paths.Users.Add}"`, () => {
|
|
65
65
|
|
|
66
|
-
const ERROR_MSG =
|
|
66
|
+
const ERROR_MSG = ValidationErr.GetMsg('user'),
|
|
67
67
|
DUMMY_USER = getDummyUsers()[0];
|
|
68
68
|
|
|
69
69
|
// Setup API
|
|
@@ -101,7 +101,7 @@ describe('UserRouter', () => {
|
|
|
101
101
|
// Update users
|
|
102
102
|
describe(`"PUT:${Paths.Users.Update}"`, () => {
|
|
103
103
|
|
|
104
|
-
const ERROR_MSG =
|
|
104
|
+
const ERROR_MSG = ValidationErr.GetMsg('user'),
|
|
105
105
|
DUMMY_USER = getDummyUsers()[0];
|
|
106
106
|
|
|
107
107
|
// Setup API
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import HttpStatusCodes from '@src/common/HttpStatusCodes';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Error with status code and message.
|
|
6
|
+
*/
|
|
7
|
+
export class RouteError extends Error {
|
|
8
|
+
|
|
9
|
+
public status: HttpStatusCodes;
|
|
10
|
+
|
|
11
|
+
public constructor(status: HttpStatusCodes, message: string) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.status = status;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* If route validation fails.
|
|
19
|
+
*/
|
|
20
|
+
export class ValidationErr extends RouteError {
|
|
21
|
+
|
|
22
|
+
public static MSG = 'The follow parameter were missing or invalid "';
|
|
23
|
+
|
|
24
|
+
public constructor(paramName: string) {
|
|
25
|
+
super(HttpStatusCodes.BAD_REQUEST, ValidationErr.GetMsg(paramName));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public static GetMsg(param: string) {
|
|
29
|
+
return ValidationErr.MSG + param + '".';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
@@ -40,17 +40,16 @@ function new_(
|
|
|
40
40
|
* Get user instance from object.
|
|
41
41
|
*/
|
|
42
42
|
function from(param: object): IUser {
|
|
43
|
-
if (
|
|
44
|
-
|
|
43
|
+
if (isUser(param)) {
|
|
44
|
+
return new_(param.name, param.email, param.created, param.id);
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
return new_(p.name, p.email, p.created, p.id);
|
|
46
|
+
throw new Error(INVALID_CONSTRUCTOR_PARAM);
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
/**
|
|
51
50
|
* See if the param meets criteria to be a user.
|
|
52
51
|
*/
|
|
53
|
-
function isUser(arg: unknown):
|
|
52
|
+
function isUser(arg: unknown): arg is IUser {
|
|
54
53
|
return (
|
|
55
54
|
!!arg &&
|
|
56
55
|
typeof arg === 'object' &&
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import HttpStatusCodes from '@src/common/HttpStatusCodes';
|
|
2
|
-
|
|
3
2
|
import UserService from '@src/services/UserService';
|
|
4
|
-
import
|
|
3
|
+
import User from '@src/models/User';
|
|
4
|
+
|
|
5
5
|
import { IReq, IRes } from './common/types';
|
|
6
|
+
import check from './common/check';
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
// **** Functions **** //
|
|
@@ -18,8 +19,8 @@ async function getAll(_: IReq, res: IRes) {
|
|
|
18
19
|
/**
|
|
19
20
|
* Add one user.
|
|
20
21
|
*/
|
|
21
|
-
async function add(req: IReq
|
|
22
|
-
const
|
|
22
|
+
async function add(req: IReq, res: IRes) {
|
|
23
|
+
const user = check.isValid(req.body, 'user', User.isUser);
|
|
23
24
|
await UserService.addOne(user);
|
|
24
25
|
return res.status(HttpStatusCodes.CREATED).end();
|
|
25
26
|
}
|
|
@@ -27,8 +28,8 @@ async function add(req: IReq<{user: IUser}>, res: IRes) {
|
|
|
27
28
|
/**
|
|
28
29
|
* Update one user.
|
|
29
30
|
*/
|
|
30
|
-
async function update(req: IReq
|
|
31
|
-
const
|
|
31
|
+
async function update(req: IReq, res: IRes) {
|
|
32
|
+
const user = check.isValid(req.body, 'user', User.isUser);
|
|
32
33
|
await UserService.updateOne(user);
|
|
33
34
|
return res.status(HttpStatusCodes.OK).end();
|
|
34
35
|
}
|
|
@@ -37,7 +38,7 @@ async function update(req: IReq<{user: IUser}>, res: IRes) {
|
|
|
37
38
|
* Delete one user.
|
|
38
39
|
*/
|
|
39
40
|
async function delete_(req: IReq, res: IRes) {
|
|
40
|
-
const id =
|
|
41
|
+
const id = check.isNum(req.params, 'id');
|
|
41
42
|
await UserService.delete(id);
|
|
42
43
|
return res.status(HttpStatusCodes.OK).end();
|
|
43
44
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { ValidationErr } from '@src/common/classes';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
type TReqObj = Record<string, unknown>;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Check that param/s is a string
|
|
9
|
+
*/
|
|
10
|
+
function isStr(reqObj: TReqObj, params: string): string;
|
|
11
|
+
function isStr(reqObj: TReqObj, params: ReadonlyArray<string>): string[];
|
|
12
|
+
function isStr(
|
|
13
|
+
reqObj: TReqObj,
|
|
14
|
+
params: string | ReadonlyArray<string>,
|
|
15
|
+
): string | string[] {
|
|
16
|
+
return _checkWrapper(reqObj, params, _checkStr);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Check validator for string
|
|
21
|
+
*/
|
|
22
|
+
function _checkStr(val: unknown): string | undefined {
|
|
23
|
+
if (!!val && typeof val === 'string') {
|
|
24
|
+
return val;
|
|
25
|
+
} else {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check that param/s is a number.
|
|
32
|
+
*/
|
|
33
|
+
function isNum(reqObj: TReqObj, params: string): number;
|
|
34
|
+
function isNum(reqObj: TReqObj, params: ReadonlyArray<string>): number[];
|
|
35
|
+
function isNum(
|
|
36
|
+
reqObj: TReqObj,
|
|
37
|
+
params: string | ReadonlyArray<string>,
|
|
38
|
+
): number | number[] {
|
|
39
|
+
return _checkWrapper(reqObj, params, _checkNum);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check validator for string
|
|
44
|
+
*/
|
|
45
|
+
function _checkNum(val: unknown): number | undefined {
|
|
46
|
+
const valF = Number(val);
|
|
47
|
+
if (!isNaN(valF)) {
|
|
48
|
+
return valF;
|
|
49
|
+
} else {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Check that param/s is a number
|
|
56
|
+
*/
|
|
57
|
+
function isBool(reqObj: TReqObj, params: string): boolean;
|
|
58
|
+
function isBool(reqObj: TReqObj, params: ReadonlyArray<string>): boolean[];
|
|
59
|
+
function isBool(
|
|
60
|
+
reqObj: TReqObj,
|
|
61
|
+
params: string | ReadonlyArray<string>,
|
|
62
|
+
): boolean | boolean[] {
|
|
63
|
+
return _checkWrapper(reqObj, params, _checkBool);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check validator for string
|
|
68
|
+
*/
|
|
69
|
+
function _checkBool(val: unknown): boolean | undefined {
|
|
70
|
+
if (typeof val === 'boolean') {
|
|
71
|
+
return val;
|
|
72
|
+
} else if (typeof val === 'string') {
|
|
73
|
+
val = val.toLowerCase();
|
|
74
|
+
if (val === 'true') {
|
|
75
|
+
return true;
|
|
76
|
+
} else if (val === 'false') {
|
|
77
|
+
return false;
|
|
78
|
+
} else {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check that param satisfies the validator function.
|
|
88
|
+
*/
|
|
89
|
+
function isValid<T>(
|
|
90
|
+
reqObj: TReqObj,
|
|
91
|
+
param: string,
|
|
92
|
+
validatorFn: (param: unknown) => param is T,
|
|
93
|
+
): T {
|
|
94
|
+
const val = reqObj[param];
|
|
95
|
+
if (validatorFn(val)) {
|
|
96
|
+
return val;
|
|
97
|
+
} else {
|
|
98
|
+
throw new ValidationErr(param);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// **** Shared Helpers **** //
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Do stuff based on whether or not params is an array
|
|
107
|
+
*/
|
|
108
|
+
function _checkWrapper<T>(
|
|
109
|
+
reqObj: TReqObj,
|
|
110
|
+
params: string | ReadonlyArray<string>,
|
|
111
|
+
checkFn: (val: unknown) => T | undefined,
|
|
112
|
+
): T | T[] {
|
|
113
|
+
// If is array
|
|
114
|
+
if (params instanceof Array) {
|
|
115
|
+
const retVal: T[] = [];
|
|
116
|
+
for (const param of params) {
|
|
117
|
+
const val = checkFn(reqObj[param]);
|
|
118
|
+
if (val !== undefined) {
|
|
119
|
+
retVal.push(val);
|
|
120
|
+
} else {
|
|
121
|
+
throw new ValidationErr(param);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return retVal;
|
|
125
|
+
}
|
|
126
|
+
// If not an array
|
|
127
|
+
const val = checkFn(reqObj[params]);
|
|
128
|
+
if (val !== undefined) {
|
|
129
|
+
return val;
|
|
130
|
+
}
|
|
131
|
+
// Throw error
|
|
132
|
+
throw new ValidationErr(params);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
// **** Export Default **** //
|
|
137
|
+
|
|
138
|
+
export default {
|
|
139
|
+
isStr,
|
|
140
|
+
isNum,
|
|
141
|
+
isBool,
|
|
142
|
+
isValid,
|
|
143
|
+
} as const;
|
|
@@ -8,13 +8,9 @@ import { Response, Request } from 'express';
|
|
|
8
8
|
|
|
9
9
|
// **** Express **** //
|
|
10
10
|
|
|
11
|
-
type
|
|
11
|
+
type TObj = Record<string, unknown>;
|
|
12
12
|
|
|
13
|
-
export
|
|
14
|
-
body: T;
|
|
15
|
-
}
|
|
13
|
+
export type IReq = Request<TObj, void, TObj, TObj>;
|
|
16
14
|
|
|
17
|
-
export
|
|
18
|
-
locals: Record<string, unknown>;
|
|
19
|
-
}
|
|
15
|
+
export type IRes = Response<unknown, TObj>
|
|
20
16
|
|
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import jetValidator from 'jet-validator';
|
|
3
2
|
|
|
4
3
|
import Paths from '../common/Paths';
|
|
5
|
-
import User from '@src/models/User';
|
|
6
4
|
import UserRoutes from './UserRoutes';
|
|
7
5
|
|
|
8
6
|
|
|
9
7
|
// **** Variables **** //
|
|
10
8
|
|
|
11
|
-
const apiRouter = Router()
|
|
12
|
-
validate = jetValidator();
|
|
9
|
+
const apiRouter = Router();
|
|
13
10
|
|
|
14
11
|
|
|
15
12
|
// ** Add UserRouter ** //
|
|
16
13
|
|
|
14
|
+
// Init router
|
|
17
15
|
const userRouter = Router();
|
|
18
16
|
|
|
19
17
|
// Get all users
|
|
20
|
-
userRouter.get(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
// Add one user
|
|
26
|
-
userRouter.post(
|
|
27
|
-
Paths.Users.Add,
|
|
28
|
-
validate(['user', User.isUser]),
|
|
29
|
-
UserRoutes.add,
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
// Update one user
|
|
33
|
-
userRouter.put(
|
|
34
|
-
Paths.Users.Update,
|
|
35
|
-
validate(['user', User.isUser]),
|
|
36
|
-
UserRoutes.update,
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
// Delete one user
|
|
40
|
-
userRouter.delete(
|
|
41
|
-
Paths.Users.Delete,
|
|
42
|
-
validate(['id', 'number', 'params']),
|
|
43
|
-
UserRoutes.delete,
|
|
44
|
-
);
|
|
18
|
+
userRouter.get(Paths.Users.Get, UserRoutes.getAll);
|
|
19
|
+
userRouter.post(Paths.Users.Add, UserRoutes.add);
|
|
20
|
+
userRouter.put(Paths.Users.Update, UserRoutes.update);
|
|
21
|
+
userRouter.delete(Paths.Users.Delete, UserRoutes.delete);
|
|
45
22
|
|
|
46
23
|
// Add UserRouter
|
|
47
24
|
apiRouter.use(Paths.Users.Base, userRouter);
|
|
@@ -16,7 +16,7 @@ import BaseRouter from '@src/routes';
|
|
|
16
16
|
import Paths from '@src/common/Paths';
|
|
17
17
|
import EnvVars from '@src/common/EnvVars';
|
|
18
18
|
import HttpStatusCodes from '@src/common/HttpStatusCodes';
|
|
19
|
-
import RouteError from '@src/common/
|
|
19
|
+
import { RouteError } from '@src/common/classes';
|
|
20
20
|
import { NodeEnvs } from '@src/common/misc';
|
|
21
21
|
|
|
22
22
|
|
|
@@ -5,22 +5,18 @@ This project was created with [express-generator-typescript](https://github.com/
|
|
|
5
5
|
|
|
6
6
|
## Available Scripts
|
|
7
7
|
|
|
8
|
-
### `npm run dev`
|
|
8
|
+
### `npm run dev` or `npm run dev:hot` (hot reloading)
|
|
9
9
|
|
|
10
10
|
Run the server in development mode.
|
|
11
11
|
|
|
12
|
-
### `npm test`
|
|
12
|
+
### `npm test` or `npm run test:hot` (hot reloading)
|
|
13
13
|
|
|
14
|
-
Run all unit-tests
|
|
14
|
+
Run all unit-tests.
|
|
15
15
|
|
|
16
16
|
### `npm test -- --testFile="name of test file" (i.e. --testFile=Users).`
|
|
17
17
|
|
|
18
18
|
Run a single unit-test.
|
|
19
19
|
|
|
20
|
-
### `npm run test:no-reloading`
|
|
21
|
-
|
|
22
|
-
Run all unit-tests without hot-reloading.
|
|
23
|
-
|
|
24
20
|
### `npm run lint`
|
|
25
21
|
|
|
26
22
|
Check for linting errors.
|
|
@@ -33,10 +29,6 @@ Build the project for production.
|
|
|
33
29
|
|
|
34
30
|
Run the production build (Must be built first).
|
|
35
31
|
|
|
36
|
-
### `npm start -- --env="name of env file" (default is production).`
|
|
37
|
-
|
|
38
|
-
Run production build with a different env file.
|
|
39
|
-
|
|
40
32
|
|
|
41
33
|
## Additional Notes
|
|
42
34
|
|
|
@@ -14,11 +14,11 @@ import childProcess from 'child_process';
|
|
|
14
14
|
try {
|
|
15
15
|
// Remove current build
|
|
16
16
|
await remove('./dist/');
|
|
17
|
+
// Copy back-end files
|
|
18
|
+
await exec('tsc --build tsconfig.prod.json', './');
|
|
17
19
|
// Copy front-end files
|
|
18
20
|
await copy('./src/public', './dist/public');
|
|
19
21
|
await copy('./src/views', './dist/views');
|
|
20
|
-
// Copy back-end files
|
|
21
|
-
await exec('tsc --build tsconfig.prod.json', './');
|
|
22
22
|
} catch (err) {
|
|
23
23
|
logger.err(err);
|
|
24
24
|
process.exit(1);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var dotenv = require('dotenv');
|
|
2
|
+
var path = require('path');
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// Check the env
|
|
6
|
+
var NODE_ENV = process.env.NODE_ENV || 'development';
|
|
7
|
+
|
|
8
|
+
// Configure the file
|
|
9
|
+
const result2 = dotenv.config({
|
|
10
|
+
path: path.join(__dirname, `./env/${NODE_ENV}.env`),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Check for errors
|
|
14
|
+
if (result2.error) {
|
|
15
|
+
throw result2.error;
|
|
16
|
+
}
|
|
@@ -2,23 +2,15 @@
|
|
|
2
2
|
"name": "express-typescript-example",
|
|
3
3
|
"version": "0.0.0",
|
|
4
4
|
"scripts": {
|
|
5
|
+
"_ts": "./node_modules/.bin/ts-node --files -r tsconfig-paths/register -r ./dotenv.config.js",
|
|
5
6
|
"build": "npx ts-node build.ts",
|
|
7
|
+
"dev": "npm run _ts -- ./src",
|
|
8
|
+
"dev:hot": "nodemon",
|
|
6
9
|
"lint": "npx eslint --ext .ts src/",
|
|
7
10
|
"lint:tests": "npx eslint --ext .ts spec/",
|
|
8
|
-
"start": "node -r module-alias/register ./dist
|
|
9
|
-
"
|
|
10
|
-
"test": "nodemon --config ./
|
|
11
|
-
"test:no-reloading": "npx ts-node --files -r tsconfig-paths/register ./spec"
|
|
12
|
-
},
|
|
13
|
-
"nodemonConfig": {
|
|
14
|
-
"watch": [
|
|
15
|
-
"src"
|
|
16
|
-
],
|
|
17
|
-
"ext": "ts, html",
|
|
18
|
-
"ignore": [
|
|
19
|
-
"src/public"
|
|
20
|
-
],
|
|
21
|
-
"exec": "./node_modules/.bin/ts-node --files -r tsconfig-paths/register ./src"
|
|
11
|
+
"start": "NODE_ENV=production node -r module-alias/register -r ./dotenv.config.js ./dist",
|
|
12
|
+
"test": "NODE_ENV=test npm run _ts -- ./spec",
|
|
13
|
+
"test:hot": "nodemon --config ./nodemon.spec.json"
|
|
22
14
|
},
|
|
23
15
|
"_moduleAliases": {
|
|
24
16
|
"@src": "dist"
|
|
@@ -36,7 +28,6 @@
|
|
|
36
28
|
"inserturlparams": "^1.0.1",
|
|
37
29
|
"jet-logger": "^1.3.1",
|
|
38
30
|
"jet-paths": "^1.0.5",
|
|
39
|
-
"jet-validator": "^1.0.3",
|
|
40
31
|
"jsonfile": "^6.1.0",
|
|
41
32
|
"jsonwebtoken": "^8.5.1",
|
|
42
33
|
"module-alias": "^2.2.2",
|