express-generator-typescript 2.1.12 → 2.2.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.
Files changed (26) hide show
  1. package/lib/express-generator-typescript.js +15 -11
  2. package/lib/project-files/package.json +2 -2
  3. package/lib/project-files/spec/support/login-agent.ts +2 -4
  4. package/lib/project-files/spec/tests/auth.spec.ts +29 -34
  5. package/lib/project-files/spec/tests/users.spec.ts +55 -56
  6. package/lib/project-files/src/{shared → configurations}/EnvVars.ts +0 -0
  7. package/lib/project-files/src/configurations/HttpStatusCodes.ts +386 -0
  8. package/lib/project-files/src/declarations/classes.ts +13 -0
  9. package/lib/project-files/src/{shared → declarations}/enums.ts +0 -0
  10. package/lib/project-files/src/{shared → declarations}/functions.ts +1 -0
  11. package/lib/project-files/src/{shared → declarations}/types.ts +0 -0
  12. package/lib/project-files/src/index.ts +1 -1
  13. package/lib/project-files/src/models/User.ts +1 -1
  14. package/lib/project-files/src/repos/user-repo.ts +1 -1
  15. package/lib/project-files/src/routes/auth-routes.ts +5 -8
  16. package/lib/project-files/src/routes/middlware/adminMw.ts +26 -27
  17. package/lib/project-files/src/routes/middlware/validate.ts +29 -25
  18. package/lib/project-files/src/routes/user-routes.ts +6 -9
  19. package/lib/project-files/src/server.ts +11 -17
  20. package/lib/project-files/src/services/auth-service.ts +21 -6
  21. package/lib/project-files/src/services/user-service.ts +17 -3
  22. package/lib/project-files/src/util/jwt-util.ts +1 -1
  23. package/lib/project-files/src/util/pwd-util.ts +39 -0
  24. package/lib/project-files/tsconfig.json +5 -2
  25. package/package.json +1 -1
  26. package/lib/project-files/src/shared/errors.ts +0 -54
@@ -1,15 +1,12 @@
1
- import StatusCodes from 'http-status-codes';
1
+ import HttpStatusCodes from '@configurations/HttpStatusCodes';
2
2
 
3
3
  import userService from '@services/user-service';
4
4
  import { IUser } from '@models/User';
5
- import { IReq, IRes } from '@shared/types';
5
+ import { IReq, IRes } from '@declarations/types';
6
6
 
7
7
 
8
8
  // **** Variables **** //
9
9
 
10
- // Misc
11
- const { CREATED, OK } = StatusCodes;
12
-
13
10
  // Paths
14
11
  const paths = {
15
12
  basePath: '/users',
@@ -27,7 +24,7 @@ const paths = {
27
24
  */
28
25
  async function getAll(_: IReq, res: IRes) {
29
26
  const users = await userService.getAll();
30
- return res.status(OK).json({ users });
27
+ return res.status(HttpStatusCodes.OK).json({ users });
31
28
  }
32
29
 
33
30
  /**
@@ -36,7 +33,7 @@ async function getAll(_: IReq, res: IRes) {
36
33
  async function add(req: IReq<{user: IUser}>, res: IRes) {
37
34
  const { user } = req.body;
38
35
  await userService.addOne(user);
39
- return res.status(CREATED).end();
36
+ return res.status(HttpStatusCodes.CREATED).end();
40
37
  }
41
38
 
42
39
  /**
@@ -45,7 +42,7 @@ async function add(req: IReq<{user: IUser}>, res: IRes) {
45
42
  async function update(req: IReq<{user: IUser}>, res: IRes) {
46
43
  const { user } = req.body;
47
44
  await userService.updateOne(user);
48
- return res.status(OK).end();
45
+ return res.status(HttpStatusCodes.OK).end();
49
46
  }
50
47
 
51
48
  /**
@@ -54,7 +51,7 @@ async function update(req: IReq<{user: IUser}>, res: IRes) {
54
51
  async function _delete(req: IReq, res: IRes) {
55
52
  const id = +req.params.id;
56
53
  await userService.delete(id);
57
- return res.status(OK).end();
54
+ return res.status(HttpStatusCodes.OK).end();
58
55
  }
59
56
 
60
57
 
@@ -2,17 +2,16 @@ import cookieParser from 'cookie-parser';
2
2
  import morgan from 'morgan';
3
3
  import path from 'path';
4
4
  import helmet from 'helmet';
5
- import StatusCodes from 'http-status-codes';
6
5
  import express, { Request, Response, NextFunction } from 'express';
7
6
 
8
7
  import 'express-async-errors';
9
8
 
10
9
  import BaseRouter from './routes/api';
11
10
  import logger from 'jet-logger';
12
- import EnvVars from '@shared/EnvVars';
13
- import { CustomError } from '@shared/errors';
14
-
15
- import { NodeEnvs } from '@shared/enums';
11
+ import EnvVars from '@configurations/EnvVars';
12
+ import HttpStatusCodes from '@configurations/HttpStatusCodes';
13
+ import { NodeEnvs } from '@declarations/enums';
14
+ import { RouteError } from '@declarations/classes';
16
15
 
17
16
 
18
17
  // **** Init express **** //
@@ -44,23 +43,18 @@ app.use('/api', BaseRouter);
44
43
 
45
44
  // Setup error handler
46
45
  app.use((
47
- err: Error | CustomError,
46
+ err: Error,
48
47
  _: Request,
49
48
  res: Response,
50
49
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
51
- __: NextFunction,
50
+ next: NextFunction,
52
51
  ) => {
53
52
  logger.err(err, true);
54
- // Status
55
- const status = (
56
- err instanceof CustomError
57
- ? err.HttpStatus
58
- : StatusCodes.BAD_REQUEST
59
- );
60
- // Return
61
- return res.status(status).json({
62
- error: err.message,
63
- });
53
+ let status = HttpStatusCodes.BAD_REQUEST;
54
+ if (err instanceof RouteError) {
55
+ status = err.status;
56
+ }
57
+ return res.status(status).json({ error: err.message });
64
58
  });
65
59
 
66
60
 
@@ -1,8 +1,17 @@
1
- import bcrypt from 'bcrypt';
2
-
3
1
  import userRepo from '@repos/user-repo';
4
2
  import jwtUtil from '@util/jwt-util';
5
- import { UnauthorizedError } from '@shared/errors';
3
+ import pwdUtil from '@util/pwd-util';
4
+ import HttpStatusCodes from '@configurations/HttpStatusCodes';
5
+ import { RouteError } from '@declarations/classes';
6
+
7
+
8
+ // **** Variables **** //
9
+
10
+ // Errors
11
+ export const errors = {
12
+ unauth: 'Unauthorized',
13
+ emailNotFound: (email: string) => `User with email "${email}" not found`,
14
+ } as const;
6
15
 
7
16
 
8
17
  // **** Functions **** //
@@ -14,13 +23,19 @@ async function getJwt(email: string, password: string): Promise<string> {
14
23
  // Fetch user
15
24
  const user = await userRepo.getOne(email);
16
25
  if (!user) {
17
- throw new UnauthorizedError();
26
+ throw new RouteError(
27
+ HttpStatusCodes.UNAUTHORIZED,
28
+ errors.emailNotFound(email),
29
+ );
18
30
  }
19
31
  // Check password
20
32
  const hash = (user.pwdHash ?? '');
21
- const pwdPassed = await bcrypt.compare(password, hash);
33
+ const pwdPassed = await pwdUtil.compare(password, hash);
22
34
  if (!pwdPassed) {
23
- throw new UnauthorizedError();
35
+ throw new RouteError(
36
+ HttpStatusCodes.UNAUTHORIZED,
37
+ errors.unauth,
38
+ );
24
39
  }
25
40
  // Setup Admin Cookie
26
41
  return jwtUtil.sign({
@@ -1,6 +1,12 @@
1
1
  import userRepo from '@repos/user-repo';
2
2
  import { IUser } from '@models/User';
3
- import { UserNotFoundError } from '@shared/errors';
3
+ import { RouteError } from '@declarations/classes';
4
+ import HttpStatusCodes from '@configurations/HttpStatusCodes';
5
+
6
+
7
+ // **** Variables **** //
8
+
9
+ export const userNotFoundErr = 'User not found';
4
10
 
5
11
 
6
12
  // **** Functions **** //
@@ -25,8 +31,12 @@ function addOne(user: IUser): Promise<void> {
25
31
  async function updateOne(user: IUser): Promise<void> {
26
32
  const persists = await userRepo.persists(user.id);
27
33
  if (!persists) {
28
- throw new UserNotFoundError();
34
+ throw new RouteError(
35
+ HttpStatusCodes.NOT_FOUND,
36
+ userNotFoundErr,
37
+ );
29
38
  }
39
+ // Return user
30
40
  return userRepo.update(user);
31
41
  }
32
42
 
@@ -36,8 +46,12 @@ async function updateOne(user: IUser): Promise<void> {
36
46
  async function _delete(id: number): Promise<void> {
37
47
  const persists = await userRepo.persists(id);
38
48
  if (!persists) {
39
- throw new UserNotFoundError();
49
+ throw new RouteError(
50
+ HttpStatusCodes.NOT_FOUND,
51
+ userNotFoundErr,
52
+ );
40
53
  }
54
+ // Delete user
41
55
  return userRepo.delete(id);
42
56
  }
43
57
 
@@ -1,5 +1,5 @@
1
1
  import jsonwebtoken from 'jsonwebtoken';
2
- import EnvVars from '../shared/EnvVars';
2
+ import EnvVars from '../configurations/EnvVars';
3
3
 
4
4
 
5
5
  // **** Variables **** //
@@ -0,0 +1,39 @@
1
+ import bcrypt from 'bcrypt';
2
+
3
+
4
+ // **** Variables **** //
5
+
6
+ const saltRounds = 12;
7
+
8
+
9
+ // **** Functions **** //
10
+
11
+ /**
12
+ * Get a hash from the password.
13
+ */
14
+ function getHash(pwd: string): Promise<string> {
15
+ return bcrypt.hash(pwd, saltRounds);
16
+ }
17
+
18
+ /**
19
+ * Useful for testing.
20
+ */
21
+ function hashSync(pwd: string): string {
22
+ return bcrypt.hashSync(pwd, saltRounds);
23
+ }
24
+
25
+ /**
26
+ * See if a password passes the hash.
27
+ */
28
+ function compare(pwd: string, hash: string): Promise<boolean> {
29
+ return bcrypt.compare(pwd, hash);
30
+ }
31
+
32
+
33
+ // **** Export Default **** //
34
+
35
+ export default {
36
+ getHash,
37
+ hashSync,
38
+ compare,
39
+ } as const;
@@ -72,8 +72,11 @@
72
72
  "@models/*": [
73
73
  "src/models/*"
74
74
  ],
75
- "@shared/*": [
76
- "src/shared/*"
75
+ "@declarations/*": [
76
+ "src/declarations/*"
77
+ ],
78
+ "@configurations/*": [
79
+ "src/configurations/*"
77
80
  ],
78
81
  "@server": [
79
82
  "src/server"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-generator-typescript",
3
- "version": "2.1.12",
3
+ "version": "2.2.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",
@@ -1,54 +0,0 @@
1
- import HttpStatusCodes from 'http-status-codes';
2
-
3
-
4
- export abstract class CustomError extends Error {
5
-
6
- public readonly HttpStatus = HttpStatusCodes.BAD_REQUEST;
7
-
8
- constructor(msg: string, httpStatus: number) {
9
- super(msg);
10
- this.HttpStatus = httpStatus;
11
- }
12
- }
13
-
14
- export class ParamInvalidError extends CustomError {
15
-
16
- public static readonly Msg = 'One or more of the required was missing ' +
17
- 'or invalid.';
18
- public static readonly HttpStatus = HttpStatusCodes.BAD_REQUEST;
19
-
20
- constructor() {
21
- super(ParamInvalidError.Msg, ParamInvalidError.HttpStatus);
22
- }
23
- }
24
-
25
- export class ValidatorFnError extends CustomError {
26
-
27
- public static readonly Msg = 'Validator function failed. function name: ';
28
- public static readonly HttpStatus = HttpStatusCodes.BAD_REQUEST;
29
-
30
- constructor(fnName: string) {
31
- super(ValidatorFnError.Msg + fnName, ValidatorFnError.HttpStatus);
32
- }
33
- }
34
-
35
- export class UserNotFoundError extends CustomError {
36
-
37
- public static readonly Msg = 'A user with the given id does not exists ' +
38
- 'in the database.';
39
- public static readonly HttpStatus = HttpStatusCodes.NOT_FOUND;
40
-
41
- constructor() {
42
- super(UserNotFoundError.Msg, UserNotFoundError.HttpStatus);
43
- }
44
- }
45
-
46
- export class UnauthorizedError extends CustomError {
47
-
48
- public static readonly Msg = 'Login failed';
49
- public static readonly HttpStatus = HttpStatusCodes.UNAUTHORIZED;
50
-
51
- constructor() {
52
- super(UnauthorizedError.Msg, UnauthorizedError.HttpStatus);
53
- }
54
- }