express-generator-typescript 2.0.14 → 2.1.1

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.
@@ -14,9 +14,9 @@
14
14
  },
15
15
  "rules": {
16
16
  "max-len": [
17
- "error",
17
+ "warn",
18
18
  {
19
- "code": 100
19
+ "code": 80
20
20
  }
21
21
  ],
22
22
  "comma-dangle": ["warn", "always-multiline"],
@@ -0,0 +1,38 @@
1
+ ## About
2
+
3
+ This project was created with [express-generator-typescript](https://github.com/seanpmaxwell/express-generator-typescript).
4
+
5
+
6
+ ## Available Scripts
7
+
8
+ ### `npm run dev`
9
+
10
+ Run the server in development mode.
11
+
12
+ ### `npm test`
13
+
14
+ Run all unit-tests with hot-reloading.
15
+
16
+ ### `npm test -- --testFile="name of test file" (i.e. --testFile=Users).`
17
+
18
+ Run a single unit-test.
19
+
20
+ ### `npm run test:no-reloading`
21
+
22
+ Run all unit-tests without hot-reloading.
23
+
24
+ ### `npm run lint`
25
+
26
+ Check for linting errors.
27
+
28
+ ### `npm run build`
29
+
30
+ Build the project for production.
31
+
32
+ ### `npm start`
33
+
34
+ Run the production build (Must be built first).
35
+
36
+ ### `npm start -- --env="name of env file" (default is production).`
37
+
38
+ Run production build with a different env file.
@@ -1,13 +1,13 @@
1
1
  import bcrypt from 'bcrypt';
2
2
  import StatusCodes from 'http-status-codes';
3
3
  import supertest, { SuperTest, Test, Response } from 'supertest';
4
+ import logger from 'jet-logger';
4
5
 
5
6
  import app from '@server';
6
7
  import userRepo from '@repos/user-repo';
7
8
  import envVars from '@shared/env-vars';
8
9
  import User, { UserRoles } from '@models/user-model';
9
10
  import { p as paths } from '@routes/auth-router';
10
- import { pErr } from '@shared/functions';
11
11
  import { pwdSaltRounds } from 'spec/support/login-agent';
12
12
  import { UnauthorizedError } from '@shared/errors';
13
13
 
@@ -22,14 +22,15 @@ const authPath = ('/api' + paths.basePath),
22
22
 
23
23
  // Test message
24
24
  const msgs = {
25
- goodLogin: `should return a response with a status of ${OK} and a cookie with a jwt if the login
26
- was successful.`,
27
- emailNotFound: `should return a response with a status of ${UNAUTHORIZED} and a json with the
28
- "error ${UnauthorizedError.Msg}" if the email was not found.`,
29
- pwdFailed: `should return a response with a status of ${UNAUTHORIZED} and a json with the error
30
- "${UnauthorizedError.Msg}" if the password failed.`,
31
- fallbackErr: `should return a response with a status of ${BAD_REQUEST} and a json with an error
32
- for all other bad responses.`,
25
+ goodLogin: `should return a response with a status of ${OK} and a cookie
26
+ with a jwt if the login was successful.`,
27
+ emailNotFound: `should return a response with a status of ${UNAUTHORIZED}
28
+ and a json with the "error ${UnauthorizedError.Msg}" if the email was
29
+ not found.`,
30
+ pwdFailed: `should return a response with a status of ${UNAUTHORIZED} and a
31
+ json with the error "${UnauthorizedError.Msg}" if the password failed.`,
32
+ fallbackErr: `should return a response with a status of ${BAD_REQUEST} and
33
+ a json with an error for all other bad responses.`,
33
34
  goodLogout: `should return a response with a status of ${OK}.`,
34
35
  } as const;
35
36
 
@@ -37,7 +38,7 @@ const msgs = {
37
38
  const loginCreds = {
38
39
  email: 'jsmith@gmail.com',
39
40
  password: 'Password@1',
40
- } as const;
41
+ } as const;
41
42
 
42
43
 
43
44
  // **** Types **** //
@@ -73,7 +74,7 @@ describe('auth-router', () => {
73
74
  // Call API
74
75
  callApi(loginCreds)
75
76
  .end((err: Error, res: Response) => {
76
- pErr(err);
77
+ !!err && logger.err(err);
77
78
  expect(res.status).toBe(OK);
78
79
  const cookie = res.headers['set-cookie'][0];
79
80
  expect(cookie).toContain(envVars.cookieProps.key);
@@ -86,7 +87,7 @@ describe('auth-router', () => {
86
87
  spyOn(userRepo, 'getOne').and.returnValue(Promise.resolve(null));
87
88
  callApi(loginCreds)
88
89
  .end((err: Error, res: Response) => {
89
- pErr(err);
90
+ !!err && logger.err(err);
90
91
  expect(res.status).toBe(UNAUTHORIZED);
91
92
  expect(res.body.error).toBe(UnauthorizedError.Msg);
92
93
  done();
@@ -102,7 +103,7 @@ describe('auth-router', () => {
102
103
  // Call API
103
104
  callApi(loginCreds)
104
105
  .end((err: Error, res: Response) => {
105
- pErr(err);
106
+ !!err && logger.err(err);
106
107
  expect(res.status).toBe(UNAUTHORIZED);
107
108
  expect(res.body.error).toBe(UnauthorizedError.Msg);
108
109
  done();
@@ -114,7 +115,7 @@ describe('auth-router', () => {
114
115
  spyOn(userRepo, 'getOne').and.throwError('Database query failed.');
115
116
  callApi(loginCreds)
116
117
  .end((err: Error, res: Response) => {
117
- pErr(err);
118
+ !!err && logger.err(err);
118
119
  expect(res.status).toBe(BAD_REQUEST);
119
120
  expect(res.body.error).toBeTruthy();
120
121
  done();
@@ -129,7 +130,7 @@ describe('auth-router', () => {
129
130
  it(msgs.goodLogout, (done) => {
130
131
  agent.get(logoutPath)
131
132
  .end((err: Error, res: Response) => {
132
- pErr(err);
133
+ !!err && logger.err(err);
133
134
  expect(res.status).toBe(OK);
134
135
  done();
135
136
  });
@@ -1,14 +1,19 @@
1
1
  import supertest from 'supertest';
2
2
  import StatusCodes from 'http-status-codes';
3
3
  import { SuperTest, Test, Response } from 'supertest';
4
+ import logger from 'jet-logger';
4
5
 
5
6
  import app from '@server';
6
7
  import userRepo from '@repos/user-repo';
7
8
  import User, { IUser } from '@models/user-model';
8
- import { pErr } from '@shared/functions';
9
+
9
10
  import { p as userPaths } from '@routes/user-router';
11
+ import {
12
+ ParamMissingError,
13
+ UserNotFoundError,
14
+ ValidatorFnError,
15
+ } from '@shared/errors';
10
16
  import loginAgent from '../support/login-agent';
11
- import { ParamMissingError, UserNotFoundError, ValidatorFnError } from '@shared/errors';
12
17
 
13
18
 
14
19
  // **** Variables **** //
@@ -35,31 +40,34 @@ const dummyUserData = {
35
40
 
36
41
  // Test messages
37
42
  const msgs = {
38
- getUsersSuccess: `should return a JSON object with all the users and a status code of
39
- "${OK}" if the request was successful.`,
40
- getUsersBad: `should return a JSON object containing an error message and a status code of
41
- "${BAD_REQUEST}" if the request was unsuccessful.`,
42
- addUserSuccess: `should return a status code of "${CREATED}" if the request was successful.`,
43
- addUserFailedMissingParam: `should return a JSON object with an error message of
44
- "${ParamMissingError.Msg}" and a status code of "${BAD_REQUEST}" if the user param was
45
- missing.`,
46
- addUserFallbackErr: `should return a JSON object with an error message and a status code
47
- of "${BAD_REQUEST}" if the request was unsuccessful.`,
48
- updateSuccess: `should return a status code of "${OK}" if the request was successful.`,
43
+ getUsersSuccess: `should return a JSON object with all the users and a
44
+ status code of "${OK}" if the request was successful.`,
45
+ getUsersBad: `should return a JSON object containing an error message and a
46
+ status code of "${BAD_REQUEST}" if the request was unsuccessful.`,
47
+ addUserSuccess: `should return a status code of "${CREATED}" if the request
48
+ was successful.`,
49
+ addUserFailedMissingParam: `should return a JSON object with an error
50
+ message of "${ParamMissingError.Msg}" and a status code of "${BAD_REQUEST}"
51
+ if the user param was missing.`,
52
+ addUserFallbackErr: `should return a JSON object with an error message and a
53
+ status code of "${BAD_REQUEST}" if the request was unsuccessful.`,
54
+ updateSuccess: `should return a status code of "${OK}" if the request was
55
+ successful.`,
49
56
  updateParamMissing: `should return a JSON object with an error message of
50
- "${ParamMissingError.Msg}" and a status code of "${BAD_REQUEST}" if the user param was
51
- missing.`,
57
+ "${ParamMissingError.Msg}" and a status code of "${BAD_REQUEST}" if the
58
+ user param was missing.`,
52
59
  updateUserNotFound: `should return a JSON object with the error message of
53
- ${UserNotFoundError.Msg} and a status code of "${UserNotFoundError.HttpStatus}" if the id
54
- was not found.`,
55
- updateFallbackErr: `should return a JSON object with an error message and a status code of
56
- "${BAD_REQUEST}" if the request was unsuccessful.`,
57
- deleteSuccessful: `should return a status code of "${OK}" if the request was successful.`,
60
+ ${UserNotFoundError.Msg} and a status code of
61
+ "${UserNotFoundError.HttpStatus}" if the id was not found.`,
62
+ updateFallbackErr: `should return a JSON object with an error message and a
63
+ status code of "${BAD_REQUEST}" if the request was unsuccessful.`,
64
+ deleteSuccessful: `should return a status code of "${OK}" if the request was
65
+ successful.`,
58
66
  deleteUserNotFound: `should return a JSON object with the error message of
59
- ${UserNotFoundError.Msg} and a status code of "${UserNotFoundError.HttpStatus}" if the id was
60
- not found.`,
61
- deleteFallbackErr: `should return a JSON object with an error message and a status code of
62
- "${BAD_REQUEST}" if the request was unsuccessful.`,
67
+ ${UserNotFoundError.Msg} and a status code of
68
+ "${UserNotFoundError.HttpStatus}" if the id was not found.`,
69
+ deleteFallbackErr: `should return a JSON object with an error message and a
70
+ status code of "${BAD_REQUEST}" if the request was unsuccessful.`,
63
71
  };
64
72
 
65
73
 
@@ -98,7 +106,7 @@ describe('user-router', () => {
98
106
  spyOn(userRepo, 'getAll').and.returnValue(ret);
99
107
  // Call API
100
108
  callApi().end((err: Error, res: Response) => {
101
- pErr(err);
109
+ !!err && logger.err(err);
102
110
  expect(res.status).toBe(OK);
103
111
  // Caste instance-objects to 'User' objects
104
112
  const respUsers = res.body.users;
@@ -116,7 +124,7 @@ describe('user-router', () => {
116
124
  // Call API
117
125
  callApi()
118
126
  .end((err: Error, res: Response) => {
119
- pErr(err);
127
+ !!err && logger.err(err);
120
128
  expect(res.status).toBe(BAD_REQUEST);
121
129
  expect(res.body.error).toBe(errMsg);
122
130
  done();
@@ -139,7 +147,7 @@ describe('user-router', () => {
139
147
  spyOn(userRepo, 'add').and.returnValue(Promise.resolve());
140
148
  callApi(dummyUserData)
141
149
  .end((err: Error, res: Response) => {
142
- pErr(err);
150
+ !!err && logger.err(err);
143
151
  expect(res.status).toBe(CREATED);
144
152
  expect(res.body.error).toBeUndefined();
145
153
  done();
@@ -150,7 +158,7 @@ describe('user-router', () => {
150
158
  it(msgs.addUserFailedMissingParam, (done) => {
151
159
  callApi({})
152
160
  .end((err: Error, res: Response) => {
153
- pErr(err);
161
+ !!err && logger.err(err);
154
162
  expect(res.status).toBe(BAD_REQUEST);
155
163
  expect(res.body.error).toBe(ValidatorFnError.Msg + 'instanceOf');
156
164
  done();
@@ -164,7 +172,7 @@ describe('user-router', () => {
164
172
  // Call API
165
173
  callApi(dummyUserData)
166
174
  .end((err: Error, res: Response) => {
167
- pErr(err);
175
+ !!err && logger.err(err);
168
176
  expect(res.status).toBe(BAD_REQUEST);
169
177
  expect(res.body.error).toBe(errMsg);
170
178
  done();
@@ -187,7 +195,7 @@ describe('user-router', () => {
187
195
  // Call api
188
196
  callApi(dummyUserData)
189
197
  .end((err: Error, res: Response) => {
190
- pErr(err);
198
+ !!err && logger.err(err);
191
199
  expect(res.status).toBe(OK);
192
200
  expect(res.body.error).toBeUndefined();
193
201
  done();
@@ -198,7 +206,7 @@ describe('user-router', () => {
198
206
  it(msgs.updateParamMissing, (done) => {
199
207
  callApi({})
200
208
  .end((err: Error, res: Response) => {
201
- pErr(err);
209
+ !!err && logger.err(err);
202
210
  expect(res.status).toBe(BAD_REQUEST);
203
211
  expect(res.body.error).toBe(ValidatorFnError.Msg + 'instanceOf');
204
212
  done();
@@ -209,7 +217,7 @@ describe('user-router', () => {
209
217
  it(msgs.updateUserNotFound, (done) => {
210
218
  callApi(dummyUserData)
211
219
  .end((err: Error, res: Response) => {
212
- pErr(err);
220
+ !!err && logger.err(err);
213
221
  expect(res.status).toBe(UserNotFoundError.HttpStatus);
214
222
  expect(res.body.error).toBe(UserNotFoundError.Msg);
215
223
  done();
@@ -224,7 +232,7 @@ describe('user-router', () => {
224
232
  // Call API
225
233
  callApi(dummyUserData)
226
234
  .end((err: Error, res: Response) => {
227
- pErr(err);
235
+ !!err && logger.err(err);
228
236
  expect(res.status).toBe(BAD_REQUEST);
229
237
  expect(res.body.error).toBe(updateErrMsg);
230
238
  done();
@@ -248,7 +256,7 @@ describe('user-router', () => {
248
256
  // Call api
249
257
  callApi(5)
250
258
  .end((err: Error, res: Response) => {
251
- pErr(err);
259
+ !!err && logger.err(err);
252
260
  expect(res.status).toBe(OK);
253
261
  expect(res.body.error).toBeUndefined();
254
262
  done();
@@ -259,7 +267,7 @@ describe('user-router', () => {
259
267
  it(msgs.deleteUserNotFound, (done) => {
260
268
  callApi(-1)
261
269
  .end((err: Error, res: Response) => {
262
- pErr(err);
270
+ !!err && logger.err(err);
263
271
  expect(res.status).toBe(UserNotFoundError.HttpStatus);
264
272
  expect(res.body.error).toBe(UserNotFoundError.Msg);
265
273
  done();
@@ -274,7 +282,7 @@ describe('user-router', () => {
274
282
  // Call API
275
283
  callApi(1)
276
284
  .end((err: Error, res: Response) => {
277
- pErr(err);
285
+ !!err && logger.err(err);
278
286
  expect(res.status).toBe(BAD_REQUEST);
279
287
  expect(res.body.error).toBe(deleteErrMsg);
280
288
  done();
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Pre-start is where we want to place things that must run BEFORE the express server is started.
3
- * This is useful for environment variables, command-line arguments, and cron-jobs.
2
+ * Pre-start is where we want to place things that must run BEFORE the express
3
+ * server is started. This is useful for environment variables, command-line
4
+ * arguments, and cron-jobs.
4
5
  */
5
6
 
6
7
  import path from 'path';
@@ -1,5 +1,5 @@
1
1
  import { IUser } from '@models/user-model';
2
- import { getRandomInt } from '@shared/functions';
2
+ import sharedFns from '@shared/functions';
3
3
  import orm from './mock-orm';
4
4
 
5
5
 
@@ -44,7 +44,7 @@ async function getAll(): Promise<IUser[]> {
44
44
  */
45
45
  async function add(user: IUser): Promise<void> {
46
46
  const db = await orm.openDb();
47
- user.id = getRandomInt();
47
+ user.id = sharedFns.getRandomInt();
48
48
  db.users.push(user);
49
49
  return orm.saveDb(db);
50
50
  }
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Put other validator functions here too that may be passed to the validate() function
2
+ * Put other validator functions here too that may be passed to the validate()
3
+ * function.
3
4
  */
4
5
 
5
6
  import { ParamInvalidError, ValidatorFnError } from '@shared/errors';
@@ -15,11 +16,13 @@ type TParamFull = TParam | TValidatorFn;
15
16
  // **** Functions **** //
16
17
 
17
18
  /**
18
- * Make sure parameter is of the specified type. If the type is not provided then 'string' is
19
- * used as the default type. Instead of a type you can also pass a validator function
20
- * which must return 'true' or 'false'. Return false if invalid.
19
+ * Make sure parameter is of the specified type. If the type is not provided
20
+ * then 'string' is used as the default type. Instead of a type you can also
21
+ * pass a validator function which must return 'true' or 'false'. Return false
22
+ * if invalid.
21
23
  *
22
- * Example argument: [id, 'number'], id is the incoming variable, 'number' is the type.
24
+ * Example argument: [id, 'number'], id is the incoming variable, 'number' is
25
+ * the type.
23
26
  *
24
27
  * Example 1: validate(email, [user, 'object'], [isAdmin, 'boolean'])
25
28
  * Example 2: validate(password) // will check that password is a string
@@ -40,11 +40,22 @@ if (envVars.nodeEnv === 'production') {
40
40
  // Add APIs
41
41
  app.use('/api', BaseRouter);
42
42
 
43
- // Error handling
44
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
- app.use((err: Error | CustomError, req: Request, res: Response, _: NextFunction) => {
43
+ // Setup error handler
44
+ app.use((
45
+ err: Error | CustomError,
46
+ _: Request,
47
+ res: Response,
48
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
49
+ __: NextFunction,
50
+ ) => {
46
51
  logger.err(err, true);
47
- const status = (err instanceof CustomError ? err.HttpStatus : StatusCodes.BAD_REQUEST);
52
+ // Status
53
+ const status = (
54
+ err instanceof CustomError
55
+ ? err.HttpStatus
56
+ : StatusCodes.BAD_REQUEST
57
+ );
58
+ // Return
48
59
  return res.status(status).json({
49
60
  error: err.message,
50
61
  });
@@ -13,7 +13,8 @@ export abstract class CustomError extends Error {
13
13
 
14
14
  export class ParamMissingError extends CustomError {
15
15
 
16
- public static readonly Msg = 'One or more of the required parameters was missing.';
16
+ public static readonly Msg = 'One or more of the required parameters ' +
17
+ 'was missing.';
17
18
  public static readonly HttpStatus = HttpStatusCodes.BAD_REQUEST;
18
19
 
19
20
  constructor() {
@@ -23,7 +24,8 @@ export class ParamMissingError extends CustomError {
23
24
 
24
25
  export class ParamInvalidError extends CustomError {
25
26
 
26
- public static readonly Msg = 'One or more of the required was missing or invalid.';
27
+ public static readonly Msg = 'One or more of the required was missing ' +
28
+ 'or invalid.';
27
29
  public static readonly HttpStatus = HttpStatusCodes.BAD_REQUEST;
28
30
 
29
31
  constructor() {
@@ -43,7 +45,8 @@ export class ValidatorFnError extends CustomError {
43
45
 
44
46
  export class UserNotFoundError extends CustomError {
45
47
 
46
- public static readonly Msg = 'A user with the given id does not exists in the database.';
48
+ public static readonly Msg = 'A user with the given id does not exists ' +
49
+ 'in the database.';
47
50
  public static readonly HttpStatus = HttpStatusCodes.NOT_FOUND;
48
51
 
49
52
  constructor() {
@@ -1,20 +1,13 @@
1
- import logger from 'jet-logger';
2
-
3
-
4
- // **** Functions **** //
5
-
6
- /**
7
- * Print an error object if it's truthy. Useful for testing.
8
- */
9
- export function pErr(err?: Error): void {
10
- if (!!err) {
11
- logger.err(err);
12
- }
13
- }
14
-
15
1
  /**
16
2
  * Get a random number between 1 and 1,000,000,000,000
17
3
  */
18
- export function getRandomInt(): number {
4
+ function getRandomInt(): number {
19
5
  return Math.floor(Math.random() * 1_000_000_000_000);
20
6
  }
7
+
8
+
9
+ // **** Export default **** //
10
+
11
+ export default {
12
+ getRandomInt,
13
+ } as const;
@@ -1,4 +1,4 @@
1
- import jsonwebtoken, { JwtPayload } from 'jsonwebtoken';
1
+ import jsonwebtoken from 'jsonwebtoken';
2
2
  import envVars from '../shared/env-vars';
3
3
 
4
4
 
@@ -31,7 +31,7 @@ function sign(data: string | object | Buffer): Promise<string> {
31
31
  /**
32
32
  * Decrypt JWT and extract client data.
33
33
  */
34
- async function decode<T extends JwtPayload>(jwt: string): Promise<string | undefined | T> {
34
+ async function decode<T>(jwt: string): Promise<string | undefined | T> {
35
35
  return new Promise((res, rej) => {
36
36
  jsonwebtoken.verify(jwt, envVars.jwt.secret, (err, decoded) => {
37
37
  return err ? rej(errors.validation) : res(decoded as T);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-generator-typescript",
3
- "version": "2.0.14",
3
+ "version": "2.1.1",
4
4
  "description": "Generate new Express applications similar to express-generate which but sets it up to use TypeScript instead",
5
5
  "scripts": {
6
6
  "express-generator-typescript": "node bin/cli.js",