express-generator-typescript 2.2.9 → 2.3.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 (42) hide show
  1. package/lib/express-generator-typescript.js +12 -12
  2. package/lib/project-files/.eslintrc.json +1 -0
  3. package/lib/project-files/env/development.env +1 -0
  4. package/lib/project-files/env/production.env +1 -0
  5. package/lib/project-files/env/test.env +1 -0
  6. package/lib/project-files/package.json +4 -4
  7. package/lib/project-files/spec/index.ts +32 -12
  8. package/lib/project-files/spec/support/login.ts +43 -0
  9. package/lib/project-files/spec/support/types.ts +1 -0
  10. package/lib/project-files/spec/tests/auth.spec.ts +75 -89
  11. package/lib/project-files/spec/tests/users.spec.ts +133 -212
  12. package/lib/project-files/src/constants/EnvVars.ts +28 -0
  13. package/lib/project-files/src/{declarations/major → constants}/HttpStatusCodes.ts +0 -0
  14. package/lib/project-files/src/{declarations/enums.ts → constants/misc.ts} +2 -6
  15. package/lib/project-files/src/index.ts +6 -4
  16. package/lib/project-files/src/models/User.ts +9 -2
  17. package/lib/project-files/src/{declarations → other}/classes.ts +1 -1
  18. package/lib/project-files/src/other/types.ts +4 -0
  19. package/lib/project-files/src/pre-start.ts +17 -15
  20. package/lib/project-files/src/repos/{mock-orm.ts → MockOrm.ts} +4 -4
  21. package/lib/project-files/src/repos/{user-repo.ts → UserRepo.ts} +4 -4
  22. package/lib/project-files/src/routes/AuthRoutes.ts +47 -0
  23. package/lib/project-files/src/routes/UserRoutes.ts +53 -0
  24. package/lib/project-files/src/routes/api.ts +27 -20
  25. package/lib/project-files/src/routes/constants/FullPaths.ts +40 -0
  26. package/lib/project-files/src/routes/constants/Paths.ts +28 -0
  27. package/lib/project-files/src/routes/{shared → middleware}/adminMw.ts +12 -22
  28. package/lib/project-files/src/{types → routes/types}/express/index.d.ts +0 -0
  29. package/lib/project-files/src/routes/types/express/misc.ts +16 -0
  30. package/lib/project-files/src/routes/{shared → types}/types.ts +1 -1
  31. package/lib/project-files/src/routes/user-routes.ts +2 -8
  32. package/lib/project-files/src/server.ts +28 -21
  33. package/lib/project-files/src/services/{auth-service.ts → AuthService.ts} +16 -14
  34. package/lib/project-files/src/services/{user-service.ts → UserService.ts} +12 -12
  35. package/lib/project-files/src/util/{jwt-util.ts → JwtUtil.ts} +8 -8
  36. package/lib/project-files/src/util/{pwd-util.ts → PwdUtil.ts} +3 -3
  37. package/lib/project-files/src/{declarations/functions.ts → util/misc.ts} +1 -0
  38. package/package.json +1 -1
  39. package/lib/project-files/spec/load-env.ts +0 -12
  40. package/lib/project-files/spec/support/login-agent.ts +0 -46
  41. package/lib/project-files/src/declarations/major/EnvVars.ts +0 -22
  42. package/lib/project-files/src/routes/auth-routes.ts +0 -57
@@ -1,300 +1,221 @@
1
1
  import supertest, { SuperTest, Test, Response } from 'supertest';
2
- import { defaultErrMsg } from 'jet-validator';
3
- import logger from 'jet-logger';
2
+ import { defaultErrMsg as ValidatorErr } from 'jet-validator';
3
+ import insertUrlParams from 'inserturlparams';
4
4
 
5
5
  import app from '@src/server';
6
- import userRepo from '@src/repos/user-repo';
7
- import User, { IUser } from '@src/models/User';
8
- import userRoutes from '@src/routes/user-routes';
9
- import HttpStatusCodes from '@src/declarations/major/HttpStatusCodes';
10
- import loginAgent from '../support/login-agent';
11
- import { userNotFoundErr } from '@src/services/user-service';
6
+
7
+ import UserRepo from '@src/repos/UserRepo';
8
+ import User from '@src/models/User';
9
+ import HttpStatusCodes from '@src/constants/HttpStatusCodes';
10
+ import { USER_NOT_FOUND_ERR } from '@src/services/UserService';
11
+ import FullPaths from '@src/routes/constants/FullPaths';
12
+
13
+ import login from '../support/login';
14
+ import { TReqBody } from 'spec/support/types';
12
15
 
13
16
 
14
17
  // **** Variables **** //
15
18
 
16
- // Misc
17
- const { paths } = userRoutes,
18
- usersPath = ('/api' + paths.basePath),
19
- getUsersPath = `${usersPath}${paths.get}`,
20
- addUsersPath = `${usersPath}${paths.add}`,
21
- updateUserPath = `${usersPath}${paths.update}`,
22
- deleteUserPath = `${usersPath}${paths.delete}`;
19
+ // Paths
20
+ const {
21
+ Get,
22
+ Add,
23
+ Update,
24
+ Delete,
25
+ } = FullPaths.Users;
26
+
27
+ // StatusCodes
28
+ const {
29
+ OK,
30
+ CREATED,
31
+ NOT_FOUND,
32
+ BAD_REQUEST,
33
+ } = HttpStatusCodes;
23
34
 
24
35
  // Dummy users for GET req
25
- const dummyGetAllUsers = [
36
+ const DummyGetAllUsers = [
26
37
  User.new('Sean Maxwell', 'sean.maxwell@gmail.com'),
27
38
  User.new('John Smith', 'john.smith@gmail.com'),
28
39
  User.new('Gordan Freeman', 'gordan.freeman@gmail.com'),
29
40
  ] as const;
30
41
 
31
42
  // Dummy update user
32
- const dummyUserData = {
43
+ const DummyUserData = {
33
44
  user: User.new('Gordan Freeman', 'gordan.freeman@gmail.com'),
34
45
  } as const;
35
46
 
36
- // Test messages
37
- const msgs = {
38
- getUsersSuccess: 'should return a JSON object with all the users and a ' +
39
- `status code of "${HttpStatusCodes.OK}" if the request was successful.`,
40
- getUsersBad: 'should return a JSON object containing an error message ' +
41
- `and a status code of "${HttpStatusCodes.BAD_REQUEST}" if the request ` +
42
- 'was unsuccessful.',
43
- addUserSuccess: 'should return a status code of ' +
44
- `"${HttpStatusCodes.CREATED}" if the request was successful.`,
45
- addUserFailedMissingParam: 'should return a JSON object with an error ' +
46
- `message of "${defaultErrMsg}" and a status code of ` +
47
- `"${HttpStatusCodes.BAD_REQUEST}" if the user param was missing.`,
48
- addUserFallbackErr: 'should return a JSON object with an error message ' +
49
- `and a status code of "${HttpStatusCodes.BAD_REQUEST}" if the request ` +
50
- 'was unsuccessful.',
51
- updateSuccess: `should return a status code of "${HttpStatusCodes.OK}" if ` +
52
- 'the request was successful.',
53
- updateParamMissing: 'should return a JSON object with an error message ' +
54
- `of "${defaultErrMsg}" and a status code of ` +
55
- `"${HttpStatusCodes.BAD_REQUEST}" if the user param was missing.`,
56
- updateUserNotFound: 'should return a JSON object with the error message ' +
57
- `of "${userNotFoundErr}" and a status code of ` +
58
- `"${HttpStatusCodes.NOT_FOUND}" if the id was not found.`,
59
- updateFallbackErr: 'should return a JSON object with an error message ' +
60
- `and a status code of "${HttpStatusCodes.BAD_REQUEST}" if the request ` +
61
- 'was unsuccessful.',
62
- deleteSuccessful: `should return a status code of "${HttpStatusCodes.OK}" ` +
63
- 'if the request was successful.',
64
- deleteUserNotFound: 'should return a JSON object with the error message ' +
65
- `of "${userNotFoundErr}" and a status code of ` +
66
- `"${HttpStatusCodes.NOT_FOUND}" if the id was not found.`,
67
- deleteFallbackErr: 'should return a JSON object with an error message ' +
68
- `and a status code of "${HttpStatusCodes.BAD_REQUEST}" if the request ` +
69
- 'was unsuccessful.',
70
- } as const;
71
-
72
-
73
- // **** Types **** //
74
-
75
- type TReqBody = string | object | undefined;
76
-
77
47
 
78
48
  // **** Tests **** //
79
49
 
80
- describe('user-router', () => {
81
-
82
- let agent: SuperTest<Test>;
83
- let jwtCookie: string;
50
+ describe('UserRouter', () => {
84
51
 
52
+ let agent: SuperTest<Test>,
53
+ jwtCookie: string;
85
54
 
86
55
  // Run before all tests
87
56
  beforeAll((done) => {
88
57
  agent = supertest.agent(app);
89
- loginAgent.login(agent, (cookie: string) => {
58
+ login(agent, (cookie: string) => {
90
59
  jwtCookie = cookie;
91
60
  done();
92
61
  });
93
62
  });
94
63
 
95
- // Test get users
96
- describe(`"GET:${getUsersPath}"`, () => {
64
+ // ** Get all users ** //
65
+ describe(`"GET:${Get}"`, () => {
97
66
 
98
67
  const callApi = () =>
99
- agent.get(getUsersPath)
68
+ agent
69
+ .get(Get)
100
70
  .set('Cookie', jwtCookie);
101
71
 
102
- // Get all users
103
- it(msgs.getUsersSuccess, (done) => {
104
- const ret = Promise.resolve([...dummyGetAllUsers]);
105
- spyOn(userRepo, 'getAll').and.returnValue(ret);
106
- // Call API
107
- callApi().end((err: Error, res: Response) => {
108
- !!err && logger.err(err);
109
- expect(res.status).toBe(HttpStatusCodes.OK);
110
- // Caste instance-objects to 'User' objects
111
- const respUsers = res.body.users;
112
- const retUsers = respUsers.map((user: IUser) => User.copy(user));
113
- expect(retUsers).toEqual(dummyGetAllUsers);
114
- expect(res.body.error).toBeUndefined();
115
- done();
116
- });
117
- });
118
-
119
- // Get all users bad
120
- it(msgs.getUsersBad, (done) => {
121
- const errMsg = 'Could not fetch users.';
122
- spyOn(userRepo, 'getAll').and.throwError(errMsg);
72
+ // Success
73
+ it('should return a JSON object with all the users and a status code ' +
74
+ `of "${OK}" if the request was successful.`, (done) => {
75
+ // Add spy
76
+ spyOn(UserRepo, 'getAll').and.resolveTo([...DummyGetAllUsers]);
123
77
  // Call API
124
78
  callApi()
125
- .end((err: Error, res: Response) => {
126
- !!err && logger.err(err);
127
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
128
- expect(res.body.error).toBe(errMsg);
79
+ .end((_: Error, res: Response) => {
80
+ expect(res.status).toBe(OK);
81
+ for (let i = 0; i < res.body.users.length; i++) {
82
+ expect(res.body.users[i]).toEqual(DummyGetAllUsers[i]);
83
+ }
129
84
  done();
130
85
  });
131
86
  });
132
87
  });
133
88
 
134
89
  // Test add user
135
- describe(`"POST:${addUsersPath}"`, () => {
90
+ describe(`"POST:${Add}"`, () => {
136
91
 
137
- // Consts
138
- const callApi = (reqBody: TReqBody) => {
139
- return agent.post(addUsersPath)
92
+ const callApi = (reqBody: TReqBody) =>
93
+ agent
94
+ .post(Add)
140
95
  .set('Cookie', jwtCookie)
141
96
  .type('form').send(reqBody);
142
- };
143
97
 
144
98
  // Test add user success
145
- it(msgs.addUserSuccess, (done) => {
146
- spyOn(userRepo, 'add').and.returnValue(Promise.resolve());
147
- callApi(dummyUserData)
148
- .end((err: Error, res: Response) => {
149
- !!err && logger.err(err);
150
- expect(res.status).toBe(HttpStatusCodes.CREATED);
99
+ it(`should return a status code of "${CREATED}" if the request was ` +
100
+ 'successful.', (done) => {
101
+ // Spy
102
+ spyOn(UserRepo, 'add').and.resolveTo();
103
+ // Call api
104
+ callApi(DummyUserData)
105
+ .end((_: Error, res: Response) => {
106
+ expect(res.status).toBe(CREATED);
151
107
  expect(res.body.error).toBeUndefined();
152
108
  done();
153
109
  });
154
110
  });
155
111
 
156
- // Test add user failed due to missing param
157
- it(msgs.addUserFailedMissingParam, (done) => {
112
+ // Missing param
113
+ it('should return a JSON object with an error message of ' +
114
+ `"${ValidatorErr}" and a status code of "${BAD_REQUEST}" if the user ` +
115
+ 'param was missing.', (done) => {
116
+ // Call api
158
117
  callApi({})
159
- .end((err: Error, res: Response) => {
160
- !!err && logger.err(err);
161
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
162
- expect(res.body.error).toBe(defaultErrMsg);
163
- done();
164
- });
165
- });
166
-
167
- // Default error
168
- it(msgs.addUserFallbackErr, (done) => {
169
- const errMsg = 'Could not add user.';
170
- spyOn(userRepo, 'add').and.throwError(errMsg);
171
- // Call API
172
- callApi(dummyUserData)
173
- .end((err: Error, res: Response) => {
174
- !!err && logger.err(err);
175
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
176
- expect(res.body.error).toBe(errMsg);
118
+ .end((_: Error, res: Response) => {
119
+ expect(res.status).toBe(BAD_REQUEST);
120
+ expect(res.body.error).toBe(ValidatorErr);
177
121
  done();
178
122
  });
179
123
  });
180
124
  });
181
125
 
182
- // Test update users
183
- describe(`"PUT:${updateUserPath}"`, () => {
126
+ // ** Update users ** //
127
+ describe(`"PUT:${Update}"`, () => {
184
128
 
185
129
  const callApi = (reqBody: TReqBody) =>
186
- agent.put(updateUserPath)
130
+ agent
131
+ .put(Update)
187
132
  .set('Cookie', jwtCookie)
188
133
  .type('form').send(reqBody);
189
134
 
190
- // Test updating a user success
191
- it(msgs.updateSuccess, (done) => {
192
- spyOn(userRepo, 'update').and.returnValue(Promise.resolve());
193
- spyOn(userRepo, 'persists').and.returnValue(Promise.resolve(true));
194
- // Call api
195
- callApi(dummyUserData)
196
- .end((err: Error, res: Response) => {
197
- !!err && logger.err(err);
198
- expect(res.status).toBe(HttpStatusCodes.OK);
199
- expect(res.body.error).toBeUndefined();
200
- done();
201
- });
202
- });
135
+ // Success
136
+ it(`should return a status code of "${OK}" if the request was successful.`,
137
+ (done) => {
138
+ // Setup spies
139
+ spyOn(UserRepo, 'update').and.resolveTo();
140
+ spyOn(UserRepo, 'persists').and.resolveTo(true);
141
+ // Call api
142
+ callApi(DummyUserData)
143
+ .end((_: Error, res: Response) => {
144
+ expect(res.status).toBe(OK);
145
+ expect(res.body.error).toBeUndefined();
146
+ done();
147
+ });
148
+ });
203
149
 
204
- // Test updating a user failed because a param was missing
205
- it(msgs.updateParamMissing, (done) => {
150
+ // Param missing
151
+ it('should return a JSON object with an error message of ' +
152
+ `"${ValidatorErr}" and a status code of "${BAD_REQUEST}" if the user ` +
153
+ 'param was missing.', (done) => {
154
+ // Call api
206
155
  callApi({})
207
- .end((err: Error, res: Response) => {
208
- !!err && logger.err(err);
209
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
210
- expect(res.body.error).toBe(defaultErrMsg);
156
+ .end((_: Error, res: Response) => {
157
+ expect(res.status).toBe(BAD_REQUEST);
158
+ expect(res.body.error).toBe(ValidatorErr);
211
159
  done();
212
160
  });
213
161
  });
214
162
 
215
- // Update user not found
216
- it(msgs.updateUserNotFound, (done) => {
217
- callApi(dummyUserData)
218
- .end((err: Error, res: Response) => {
219
- !!err && logger.err(err);
220
- expect(res.status).toBe(HttpStatusCodes.NOT_FOUND);
221
- expect(res.body.error).toBe(userNotFoundErr);
222
- done();
223
- });
224
- });
225
-
226
- // Update fallback error
227
- it(msgs.updateFallbackErr, (done) => {
228
- const updateErrMsg = 'Could not update user.';
229
- spyOn(userRepo, 'persists').and.returnValue(Promise.resolve(true));
230
- spyOn(userRepo, 'update').and.throwError(updateErrMsg);
231
- // Call API
232
- callApi(dummyUserData)
233
- .end((err: Error, res: Response) => {
234
- !!err && logger.err(err);
235
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
236
- expect(res.body.error).toBe(updateErrMsg);
163
+ // User not found
164
+ it('should return a JSON object with the error message of ' +
165
+ `"${USER_NOT_FOUND_ERR}" and a status code of "${NOT_FOUND}" if the id ` +
166
+ 'was not found.', (done) => {
167
+ // Call api
168
+ callApi(DummyUserData)
169
+ .end((_: Error, res: Response) => {
170
+ expect(res.status).toBe(NOT_FOUND);
171
+ expect(res.body.error).toBe(USER_NOT_FOUND_ERR);
237
172
  done();
238
173
  });
239
174
  });
240
175
  });
241
176
 
242
- // Test delete user
243
- describe(`"DELETE:${deleteUserPath}"`, () => {
177
+ // ** Delete user ** //
178
+ describe(`"DELETE:${Delete}"`, () => {
244
179
 
245
- const callApi = (id: number) => {
246
- const path = deleteUserPath.replace(':id', id.toString());
247
- return agent.delete(path)
180
+ const callApi = (id: number) =>
181
+ agent
182
+ .delete(insertUrlParams(Delete, { id }))
248
183
  .set('Cookie', jwtCookie);
249
- };
250
184
 
251
- // Delete user successful
252
- it(msgs.deleteSuccessful, (done) => {
253
- spyOn(userRepo, 'delete').and.returnValue(Promise.resolve());
254
- spyOn(userRepo, 'persists').and.returnValue(Promise.resolve(true));
255
- // Call api
256
- callApi(5)
257
- .end((err: Error, res: Response) => {
258
- !!err && logger.err(err);
259
- expect(res.status).toBe(HttpStatusCodes.OK);
260
- expect(res.body.error).toBeUndefined();
261
- done();
262
- });
263
- });
185
+ // Success
186
+ it(`should return a status code of "${OK}" if the request was successful.`,
187
+ (done) => {
188
+ // Setup spies
189
+ spyOn(UserRepo, 'delete').and.resolveTo();
190
+ spyOn(UserRepo, 'persists').and.resolveTo(true);
191
+ // Call api
192
+ callApi(5)
193
+ .end((_: Error, res: Response) => {
194
+ expect(res.status).toBe(OK);
195
+ expect(res.body.error).toBeUndefined();
196
+ done();
197
+ });
198
+ });
264
199
 
265
- // Delete, user not found error
266
- it(msgs.deleteUserNotFound, (done) => {
200
+ // User not found
201
+ it('should return a JSON object with the error message of ' +
202
+ `"${USER_NOT_FOUND_ERR}" and a status code of "${NOT_FOUND}" if the id ` +
203
+ 'was not found.', (done) => {
267
204
  callApi(-1)
268
- .end((err: Error, res: Response) => {
269
- !!err && logger.err(err);
270
- expect(res.status).toBe(HttpStatusCodes.NOT_FOUND);
271
- expect(res.body.error).toBe(userNotFoundErr);
205
+ .end((_: Error, res: Response) => {
206
+ expect(res.status).toBe(NOT_FOUND);
207
+ expect(res.body.error).toBe(USER_NOT_FOUND_ERR);
272
208
  done();
273
209
  });
274
210
  });
275
211
 
276
- // Delete, not a valid number error
277
- it(msgs.deleteUserNotFound, (done) => {
212
+ // Invalid param
213
+ it(`should return a status code of "${BAD_REQUEST}" and return an error ` +
214
+ `message of "${ValidatorErr}" if the id was not a valid number`, (done) => {
278
215
  callApi('horse' as unknown as number)
279
- .end((err: Error, res: Response) => {
280
- !!err && logger.err(err);
281
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
282
- expect(res.body.error).toBe(defaultErrMsg);
283
- done();
284
- });
285
- });
286
-
287
- // Delete user fallback error
288
- it(msgs.deleteFallbackErr, (done) => {
289
- spyOn(userRepo, 'persists').and.returnValue(Promise.resolve(true));
290
- const deleteErrMsg = 'Could not delete user.';
291
- spyOn(userRepo, 'delete').and.throwError(deleteErrMsg);
292
- // Call API
293
- callApi(1)
294
- .end((err: Error, res: Response) => {
295
- !!err && logger.err(err);
296
- expect(res.status).toBe(HttpStatusCodes.BAD_REQUEST);
297
- expect(res.body.error).toBe(deleteErrMsg);
216
+ .end((_: Error, res: Response) => {
217
+ expect(res.status).toBe(BAD_REQUEST);
218
+ expect(res.body.error).toBe(ValidatorErr);
298
219
  done();
299
220
  });
300
221
  });
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Environments variables declared here.
3
+ */
4
+
5
+ /* eslint-disable node/no-process-env */
6
+
7
+
8
+ export default {
9
+ NodeEnv: (process.env.NODE_ENV ?? ''),
10
+ Port: (process.env.PORT ?? 0),
11
+ CookieProps: {
12
+ Key: 'ExpressGeneratorTs',
13
+ Secret: (process.env.COOKIE_SECRET ?? ''),
14
+ // Casing to match express cookie options
15
+ Options: {
16
+ httpOnly: true,
17
+ signed: true,
18
+ path: (process.env.COOKIE_PATH ?? ''),
19
+ maxAge: Number(process.env.COOKIE_EXP ?? 0),
20
+ domain: (process.env.COOKIE_DOMAIN ?? ''),
21
+ secure: (process.env.SECURE_COOKIE === 'true'),
22
+ },
23
+ },
24
+ Jwt: {
25
+ Secret: (process.env.JWT_SECRET ?? ''),
26
+ Exp: (process.env.COOKIE_EXP ?? ''), // exp at the same time as the cookie
27
+ },
28
+ } as const;
@@ -1,9 +1,5 @@
1
- /**
2
- * Miscellaneous shared enums go here.
3
- */
4
-
5
1
  export enum NodeEnvs {
6
2
  Dev = 'development',
7
- Staging = 'staging',
3
+ Test = 'test',
8
4
  Production = 'production'
9
- }
5
+ }
@@ -1,11 +1,13 @@
1
1
  import './pre-start'; // Must be the first import
2
2
  import logger from 'jet-logger';
3
3
 
4
- import EnvVars from '@src/declarations/major/EnvVars';
4
+ import EnvVars from '@src/constants/EnvVars';
5
5
  import server from './server';
6
6
 
7
7
 
8
- // **** Start server **** //
8
+ // **** Run **** //
9
9
 
10
- const msg = ('Express server started on port: ' + EnvVars.port.toString());
11
- server.listen(EnvVars.port, () => logger.info(msg));
10
+ const SERVER_START_MSG = ('Express server started on port: ' +
11
+ EnvVars.Port.toString());
12
+
13
+ server.listen(EnvVars.Port, () => logger.info(SERVER_START_MSG));
@@ -19,13 +19,20 @@ export interface IUser {
19
19
  role?: UserRoles;
20
20
  }
21
21
 
22
+ export interface ISessionUser {
23
+ id: number;
24
+ email: string;
25
+ name: string;
26
+ role: IUser['role'];
27
+ }
28
+
22
29
 
23
30
  // **** Functions **** //
24
31
 
25
32
  /**
26
33
  * Get a new User object.
27
34
  */
28
- function _new(
35
+ function new_(
29
36
  name: string,
30
37
  email: string,
31
38
  role?: UserRoles,
@@ -71,7 +78,7 @@ function instanceOf(arg: TAll): boolean {
71
78
  // **** Export default **** //
72
79
 
73
80
  export default {
74
- new: _new,
81
+ new: new_,
75
82
  copy,
76
83
  instanceOf,
77
84
  } as const;
@@ -2,7 +2,7 @@
2
2
  * Miscellaneous shared classes go here.
3
3
  */
4
4
 
5
- import HttpStatusCodes from '@src/declarations/major/HttpStatusCodes';
5
+ import HttpStatusCodes from '@src/constants/HttpStatusCodes';
6
6
 
7
7
 
8
8
  /**
@@ -0,0 +1,4 @@
1
+
2
+ export type Immutable<T> = {
3
+ readonly [K in keyof T]: Immutable<T[K]>;
4
+ };
@@ -4,32 +4,34 @@
4
4
  * arguments, and cron-jobs.
5
5
  */
6
6
 
7
+ // NOTE: DO NOT IMPORT ANY SOURCE CODE HERE
7
8
  import path from 'path';
8
9
  import dotenv from 'dotenv';
9
- import commandLineArgs from 'command-line-args';
10
+ import { parse } from 'ts-command-line-args';
10
11
 
11
- // **NOTE** Do not import any local paths here, or any libraries dependent
12
- // on environment variables.
13
12
 
13
+ // **** Types **** //
14
14
 
15
- // **** Setup command line options **** //
15
+ interface IArgs {
16
+ env: string;
17
+ }
16
18
 
17
- const options = commandLineArgs([
18
- {
19
- name: 'env',
20
- alias: 'e',
21
- defaultValue: 'development',
22
- type: String,
23
- },
24
- ]);
25
19
 
20
+ // **** Setup **** //
26
21
 
27
- // **** Set the env file **** //
22
+ // Command line arguments
23
+ const args = parse<IArgs>({
24
+ env: {
25
+ type: String,
26
+ defaultValue: 'development',
27
+ alias: 'e',
28
+ },
29
+ });
28
30
 
31
+ // Set the env file
29
32
  const result2 = dotenv.config({
30
- path: path.join(__dirname, `../env/${String(options.env)}.env`),
33
+ path: path.join(__dirname, `../env/${args.env}.env`),
31
34
  });
32
-
33
35
  if (result2.error) {
34
36
  throw result2.error;
35
37
  }
@@ -1,4 +1,4 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-return */
1
+
2
2
 
3
3
  import jsonfile from 'jsonfile';
4
4
 
@@ -7,7 +7,7 @@ import { IUser } from '@src/models/User';
7
7
 
8
8
  // **** Variables **** //
9
9
 
10
- const dbFileName = 'database.json';
10
+ const DB_FILE_NAME = 'database.json';
11
11
 
12
12
 
13
13
  // **** Types **** //
@@ -23,14 +23,14 @@ interface IDb {
23
23
  * Fetch the json from the file.
24
24
  */
25
25
  function openDb(): Promise<IDb> {
26
- return jsonfile.readFile(__dirname + '/' + dbFileName);
26
+ return jsonfile.readFile(__dirname + '/' + DB_FILE_NAME) as Promise<IDb>;
27
27
  }
28
28
 
29
29
  /**
30
30
  * Update the file.
31
31
  */
32
32
  function saveDb(db: IDb): Promise<void> {
33
- return jsonfile.writeFile((__dirname + '/' + dbFileName), db);
33
+ return jsonfile.writeFile((__dirname + '/' + DB_FILE_NAME), db);
34
34
  }
35
35
 
36
36
 
@@ -1,6 +1,6 @@
1
1
  import { IUser } from '@src/models/User';
2
- import { getRandomInt } from '@src/declarations/functions';
3
- import orm from './mock-orm';
2
+ import { getRandomInt } from '@src/util/misc';
3
+ import orm from './MockOrm';
4
4
 
5
5
 
6
6
  // **** Functions **** //
@@ -65,7 +65,7 @@ async function update(user: IUser): Promise<void> {
65
65
  /**
66
66
  * Delete one user.
67
67
  */
68
- async function _delete(id: number): Promise<void> {
68
+ async function delete_(id: number): Promise<void> {
69
69
  const db = await orm.openDb();
70
70
  for (let i = 0; i < db.users.length; i++) {
71
71
  if (db.users[i].id === id) {
@@ -84,5 +84,5 @@ export default {
84
84
  getAll,
85
85
  add,
86
86
  update,
87
- delete: _delete,
87
+ delete: delete_,
88
88
  } as const;