express-generator-typescript 2.9.0 → 3.0.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 (37) hide show
  1. package/README.md +196 -17
  2. package/lib/template/README.md +33 -15
  3. package/lib/template/package.json +13 -24
  4. package/lib/template/src/common/{utils → classes}/route-errors.ts +1 -1
  5. package/lib/template/src/common/constants/HttpStatusCodes.ts +7 -2
  6. package/lib/template/src/common/constants/{env.ts → env-inv.ts} +13 -9
  7. package/lib/template/src/common/utils/dev-only.ts +25 -0
  8. package/lib/template/src/entities/User/_internal/validators.ts +47 -0
  9. package/lib/template/src/entities/User/index.ts +2 -0
  10. package/lib/template/src/entities/User/module.ts +63 -0
  11. package/lib/template/src/entities/User/types.ts +18 -0
  12. package/lib/template/src/{models → entities}/common/types.ts +1 -1
  13. package/lib/template/src/main.ts +1 -1
  14. package/lib/template/src/public/scripts/HttpClient.js +59 -0
  15. package/lib/template/src/public/scripts/renderUsers.js +43 -5
  16. package/lib/template/src/public/scripts/users.js +75 -14
  17. package/lib/template/src/repos/MockOrm.ts +4 -4
  18. package/lib/template/src/repos/UserRepo.ts +6 -6
  19. package/lib/template/src/repos/common/database.json +2 -2
  20. package/lib/template/src/routes/UserRoutes.ts +2 -2
  21. package/lib/template/src/routes/common/express-types.ts +1 -1
  22. package/lib/template/src/routes/common/parseReq.ts +2 -2
  23. package/lib/template/src/server.ts +17 -5
  24. package/lib/template/src/services/UserService.ts +6 -6
  25. package/lib/template/src/views/users.html +1 -1
  26. package/lib/template/tests/common/comparators.ts +3 -3
  27. package/lib/template/tests/common/supertest-types.ts +2 -2
  28. package/lib/template/tests/frontend.test.ts +1 -1
  29. package/lib/template/tests/support/agent.ts +2 -2
  30. package/lib/template/tests/users.test.ts +11 -11
  31. package/lib/template/tsconfig.json +9 -10
  32. package/lib/template/tsconfig.prod.json +13 -4
  33. package/lib/template/{vitest.config.mts → vitest.config.ts} +6 -4
  34. package/package.json +1 -5
  35. package/lib/template/bs-config.js +0 -8
  36. package/lib/template/src/models/User.model.ts +0 -95
  37. package/lib/template/src/public/scripts/http.js +0 -25
@@ -0,0 +1,59 @@
1
+ // ========================================================================= //
2
+ // TYPES //
3
+ // ========================================================================= //
4
+
5
+ /**
6
+ * Thin wrapper around `fetch` for calling the JSON API. Each method sends and
7
+ * accepts JSON and resolves with the raw `Response`.
8
+ *
9
+ * @typedef {object} HttpClient
10
+ * @property {(path: string) => Promise<Response>} get
11
+ * @property {(path: string, data: unknown) => Promise<Response>} post - `data`
12
+ * is sent as the JSON request body.
13
+ * @property {(path: string, data: unknown) => Promise<Response>} put - `data`
14
+ * is sent as the JSON request body.
15
+ * @property {(path: string) => Promise<Response>} delete
16
+ */
17
+
18
+ // ========================================================================= //
19
+ // EXEC //
20
+ // ========================================================================= //
21
+
22
+ /** @type {HttpClient} */
23
+ var HttpClient = (() => {
24
+ /**
25
+ * Build `fetch` options for a JSON request.
26
+ *
27
+ * Used by:
28
+ * {@link HttpClient.get}
29
+ * {@link HttpClient.post}
30
+ * {@link HttpClient.put}
31
+ * {@link HttpClient.delete}
32
+ *
33
+ * @param {string} verb - HTTP method, e.g. "GET".
34
+ * @param {unknown} [data] - Request body; serialized to JSON when present.
35
+ * @returns {RequestInit}
36
+ */
37
+ var getOptions = (verb, data) => {
38
+ var options = {
39
+ dataType: 'json',
40
+ method: verb,
41
+ headers: {
42
+ Accept: 'application/json',
43
+ 'Content-Type': 'application/json',
44
+ },
45
+ };
46
+ if (!!data) {
47
+ options.body = JSON.stringify(data);
48
+ }
49
+ return options;
50
+ };
51
+
52
+ // Set HttpClient methods
53
+ return {
54
+ get: (path) => fetch(path, getOptions('GET')),
55
+ post: (path, data) => fetch(path, getOptions('POST', data)),
56
+ put: (path, data) => fetch(path, getOptions('PUT', data)),
57
+ delete: (path) => fetch(path, getOptions('DELETE')),
58
+ };
59
+ })();
@@ -8,8 +8,6 @@ const DateFormatter = new Intl.DateTimeFormat('en-US', {
8
8
  day: '2-digit',
9
9
  });
10
10
 
11
- const formatDate = (date) => DateFormatter.format(new Date(date));
12
-
13
11
  const HTML_ESCAPES = {
14
12
  '&': '&amp;',
15
13
  '<': '&lt;',
@@ -18,15 +16,29 @@ const HTML_ESCAPES = {
18
16
  "'": '&#39;',
19
17
  };
20
18
 
21
- // User data is untrusted, so escape it before it goes into innerHTML
22
- const esc = (val) => String(val).replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch]);
19
+ // ========================================================================= //
20
+ // TYPES //
21
+ // ========================================================================= //
22
+
23
+ /**
24
+ * A user record as returned by the API.
25
+ *
26
+ * @typedef {object} User
27
+ * @property {string} id
28
+ * @property {string} name
29
+ * @property {string} email
30
+ * @property {string} created - ISO 8601 date string.
31
+ */
23
32
 
24
33
  // ========================================================================= //
25
34
  // FUNCTIONS //
26
35
  // ========================================================================= //
27
36
 
28
37
  /**
29
- * Render users
38
+ * Build the HTML for the users list, including each user's edit form.
39
+ *
40
+ * @param {User[]} users
41
+ * @returns {string} HTML to assign to `innerHTML`.
30
42
  */
31
43
  function renderUsers(users) {
32
44
  return users
@@ -88,3 +100,29 @@ function renderUsers(users) {
88
100
  })
89
101
  .join('');
90
102
  }
103
+
104
+ // ================================ Helpers ================================ //
105
+
106
+ /**
107
+ * Format a date as MM/DD/YYYY.
108
+ *
109
+ * Used by: {@link renderUsers}
110
+ *
111
+ * @param {string | number | Date} date - Anything `new Date()` accepts.
112
+ * @returns {string}
113
+ */
114
+ function formatDate(date) {
115
+ return DateFormatter.format(new Date(date));
116
+ }
117
+
118
+ /**
119
+ * User data is untrusted, so escape it before it goes into innerHTML.
120
+ *
121
+ * Used by: {@link renderUsers}
122
+ *
123
+ * @param {unknown} val - Converted to a string before escaping.
124
+ * @returns {string}
125
+ */
126
+ function esc(val) {
127
+ return String(val).replace(/[&<>"']/g, (ch) => HTML_ESCAPES[ch]);
128
+ }
@@ -2,18 +2,25 @@
2
2
  // EXEC //
3
3
  // ========================================================================= //
4
4
 
5
- // Start
6
5
  displayUsers();
6
+ document.addEventListener('click', onDocumentClick);
7
7
 
8
8
  // ========================================================================= //
9
9
  // FUNCTIONS //
10
10
  // ========================================================================= //
11
11
 
12
12
  /**
13
- * Call api
13
+ * Fetch all users and render them into the page.
14
+ *
15
+ * Used by: @EXEC
16
+ * {@link addUser}
17
+ * {@link submitEdit}
18
+ * {@link deleteUser}
19
+ *
20
+ * @returns {void}
14
21
  */
15
22
  function displayUsers() {
16
- Http.get('/api/users/all')
23
+ HttpClient.get('/api/users/all')
17
24
  .then(checkResponse)
18
25
  .then((resp) => resp.json())
19
26
  .then((resp) => {
@@ -23,8 +30,16 @@ function displayUsers() {
23
30
  .catch(showError);
24
31
  }
25
32
 
26
- // Setup event listener for button click
27
- document.addEventListener('click', (event) => {
33
+ // =========================== `onDocumentClick` =========================== //
34
+
35
+ /**
36
+ * Route clicks on the page's buttons to their handlers.
37
+ *
38
+ * @listens click
39
+ * @param {MouseEvent} event
40
+ * @returns {void}
41
+ */
42
+ function onDocumentClick(event) {
28
43
  var ele = event.target;
29
44
  if (ele.matches('#add-user-btn')) {
30
45
  addUser();
@@ -37,10 +52,14 @@ document.addEventListener('click', (event) => {
37
52
  } else if (ele.matches('.delete-user-btn')) {
38
53
  deleteUser(ele);
39
54
  }
40
- });
55
+ }
41
56
 
42
57
  /**
43
- * Add a new user.
58
+ * Create a user from the "Add User" form, then refresh the list.
59
+ *
60
+ * Used by: {@link onDocumentClick}
61
+ *
62
+ * @returns {void}
44
63
  */
45
64
  function addUser() {
46
65
  var nameInput = document.getElementById('name-input');
@@ -54,7 +73,7 @@ function addUser() {
54
73
  email: emailInput.value,
55
74
  },
56
75
  };
57
- Http.post('/api/users/add', data)
76
+ HttpClient.post('/api/users/add', data)
58
77
  .then(checkResponse)
59
78
  .then(() => {
60
79
  nameInput.value = '';
@@ -65,7 +84,12 @@ function addUser() {
65
84
  }
66
85
 
67
86
  /**
68
- * Show edit view.
87
+ * Switch a user's row to its edit form.
88
+ *
89
+ * Used by: {@link onDocumentClick}
90
+ *
91
+ * @param {HTMLElement} userEle - The `.user-display-ele` wrapper for the user.
92
+ * @returns {void}
69
93
  */
70
94
  function showEditView(userEle) {
71
95
  var normalView = userEle.getElementsByClassName('normal-view')[0];
@@ -75,7 +99,12 @@ function showEditView(userEle) {
75
99
  }
76
100
 
77
101
  /**
78
- * Cancel edit.
102
+ * Close a user's edit form without saving.
103
+ *
104
+ * Used by: {@link onDocumentClick}
105
+ *
106
+ * @param {HTMLElement} userEle - The `.user-display-ele` wrapper for the user.
107
+ * @returns {void}
79
108
  */
80
109
  function cancelEdit(userEle) {
81
110
  var normalView = userEle.getElementsByClassName('normal-view')[0];
@@ -85,7 +114,13 @@ function cancelEdit(userEle) {
85
114
  }
86
115
 
87
116
  /**
88
- * Submit edit.
117
+ * Save a user's edit form, then refresh the list.
118
+ *
119
+ * Used by: {@link onDocumentClick}
120
+ *
121
+ * @param {HTMLElement} ele - The clicked "Submit" button; carries the user's
122
+ * id and created date in data attributes.
123
+ * @returns {void}
89
124
  */
90
125
  function submitEdit(ele) {
91
126
  var userEle = ele.parentNode.parentNode;
@@ -102,25 +137,42 @@ function submitEdit(ele) {
102
137
  created: ele.getAttribute('data-user-created'),
103
138
  },
104
139
  };
105
- Http.put('/api/users/update', data)
140
+ HttpClient.put('/api/users/update', data)
106
141
  .then(checkResponse)
107
142
  .then(() => displayUsers())
108
143
  .catch(showError);
109
144
  }
110
145
 
111
146
  /**
112
- * Delete a user
147
+ * Delete a user, then refresh the list.
148
+ *
149
+ * Used by: {@link onDocumentClick}
150
+ *
151
+ * @param {HTMLElement} ele - The clicked "Delete" button; carries the user's
152
+ * id in `data-user-id`.
153
+ * @returns {void}
113
154
  */
114
155
  function deleteUser(ele) {
115
156
  var id = ele.getAttribute('data-user-id');
116
- Http.delete('/api/users/delete?id=' + encodeURIComponent(id))
157
+ HttpClient.delete('/api/users/delete?id=' + encodeURIComponent(id))
117
158
  .then(checkResponse)
118
159
  .then(() => displayUsers())
119
160
  .catch(showError);
120
161
  }
121
162
 
163
+ // ============================= Shared Helpers ============================ //
164
+
122
165
  /**
123
166
  * Reject non-2xx responses with the server's error message.
167
+ *
168
+ * Used by:
169
+ * {@link displayUsers}
170
+ * {@link addUser}
171
+ * {@link submitEdit}
172
+ * {@link deleteUser}
173
+ *
174
+ * @param {Response} resp
175
+ * @returns {Response | Promise<never>} The response when it succeeded.
124
176
  */
125
177
  function checkResponse(resp) {
126
178
  if (resp.ok) {
@@ -136,6 +188,15 @@ function checkResponse(resp) {
136
188
 
137
189
  /**
138
190
  * Surface a failed request to the user.
191
+ *
192
+ * Used by:
193
+ * {@link displayUsers}
194
+ * {@link addUser}
195
+ * {@link submitEdit}
196
+ * {@link deleteUser}
197
+ *
198
+ * @param {Error} err
199
+ * @returns {void}
139
200
  */
140
201
  function showError(err) {
141
202
  alert(err.message);
@@ -2,15 +2,15 @@ import fs from 'fs/promises';
2
2
  import jsonfile from 'jsonfile';
3
3
  import path from 'path';
4
4
 
5
- import EnvVars, { NodeEnvs } from '@src/common/constants/env';
6
- import { IUser } from '@src/models/User.model';
5
+ import { EnvVars, NodeEnvs } from '@src/common/constants/env-inv';
6
+ import type { UserEntity } from '@src/entities/User';
7
7
 
8
8
  // ========================================================================= //
9
9
  // CONSTANTS //
10
10
  // ========================================================================= //
11
11
 
12
12
  const DATABASE_FILE_PATH = path.join(
13
- __dirname,
13
+ import.meta.dirname,
14
14
  'common',
15
15
  EnvVars.NodeEnv === NodeEnvs.TEST ? 'database.test.json' : 'database.json',
16
16
  );
@@ -20,7 +20,7 @@ const DATABASE_FILE_PATH = path.join(
20
20
  // ========================================================================= //
21
21
 
22
22
  type Database = {
23
- users: IUser[];
23
+ users: UserEntity[];
24
24
  };
25
25
 
26
26
  // ========================================================================= //
@@ -1,7 +1,7 @@
1
1
  import jetid from 'jet-id';
2
2
 
3
3
  import { getISOString } from '@src/common/utils/date-utils';
4
- import { IUser } from '@src/models/User.model';
4
+ import type { UserEntity } from '@src/entities/User';
5
5
 
6
6
  import orm from './MockOrm';
7
7
 
@@ -25,7 +25,7 @@ async function persists(id: string): Promise<boolean> {
25
25
  /**
26
26
  * Get all users.
27
27
  */
28
- async function getAll(): Promise<IUser[]> {
28
+ async function getAll(): Promise<UserEntity[]> {
29
29
  const db = await orm.openDb();
30
30
  return db.users;
31
31
  }
@@ -33,7 +33,7 @@ async function getAll(): Promise<IUser[]> {
33
33
  /**
34
34
  * Add one user.
35
35
  */
36
- async function add(user: IUser): Promise<void> {
36
+ async function add(user: UserEntity): Promise<void> {
37
37
  const db = await orm.openDb();
38
38
  db.users.push(user);
39
39
  return orm.saveDb(db);
@@ -42,7 +42,7 @@ async function add(user: IUser): Promise<void> {
42
42
  /**
43
43
  * Update a user.
44
44
  */
45
- async function update(user: IUser): Promise<void> {
45
+ async function update(user: UserEntity): Promise<void> {
46
46
  const db = await orm.openDb();
47
47
  for (let i = 0; i < db.users.length; i++) {
48
48
  if (db.users[i].id === user.id) {
@@ -89,8 +89,8 @@ async function deleteAllUsers(): Promise<void> {
89
89
  * Insert copies of `users` with fresh ids; the inputs are not modified.
90
90
  */
91
91
  async function insertMultiple(
92
- users: IUser[] | readonly IUser[],
93
- ): Promise<IUser[]> {
92
+ users: UserEntity[] | readonly UserEntity[],
93
+ ): Promise<UserEntity[]> {
94
94
  const db = await orm.openDb();
95
95
  const inserted = users.map((user) => ({
96
96
  ...user,
@@ -19,10 +19,10 @@
19
19
  "created": "2024-03-22T05:42:18.895Z"
20
20
  },
21
21
  {
22
- "id": "NEQXY1EYZ-66K6S-AMGXW-BWKYAY",
22
+ "id": "1S0KVJXSP-A7PXE-P15HN-KKFFNM",
23
23
  "name": "asdf",
24
24
  "email": "asdf",
25
- "created": "2026-09-25T22:31:30.844Z"
25
+ "created": "2026-09-27T01:07:01.857Z"
26
26
  }
27
27
  ]
28
28
  }
@@ -1,8 +1,8 @@
1
1
  import HttpStatusCodes from '@src/common/constants/HttpStatusCodes';
2
- import User from '@src/models/User.model';
2
+ import User from '@src/entities/User';
3
3
  import UserService from '@src/services/UserService';
4
4
 
5
- import { Req, Res } from './common/express-types';
5
+ import type { Req, Res } from './common/express-types';
6
6
  import parseReq from './common/parseReq';
7
7
 
8
8
  // ========================================================================= //
@@ -1,4 +1,4 @@
1
- import { Request, Response } from 'express';
1
+ import type { Request, Response } from 'express';
2
2
 
3
3
  // ========================================================================= //
4
4
  // TYPES //
@@ -1,6 +1,6 @@
1
- import { parseObject, Schema } from 'jet-validators/utils';
1
+ import { parseObject, type Schema } from 'jet-validators/utils';
2
2
 
3
- import { ValidationError } from '@src/common/utils/route-errors';
3
+ import { ValidationError } from '@src/common/classes/route-errors';
4
4
 
5
5
  // ========================================================================= //
6
6
  // FUNCTIONS //
@@ -1,4 +1,8 @@
1
- import express, { NextFunction, Request, Response } from 'express';
1
+ import express, {
2
+ type NextFunction,
3
+ type Request,
4
+ type Response,
5
+ } from 'express';
2
6
  import helmet from 'helmet';
3
7
  import logger from 'jet-logger';
4
8
  import morgan from 'morgan';
@@ -6,10 +10,10 @@ import path from 'path';
6
10
 
7
11
  import HttpStatusCodes from '@src/common/constants/HttpStatusCodes';
8
12
  import Paths from '@src/common/constants/Paths';
9
- import { RouteError } from '@src/common/utils/route-errors';
13
+ import { RouteError } from '@src/common/classes/route-errors';
10
14
  import BaseRouter from '@src/routes/apiRouter';
11
15
 
12
- import EnvVars, { NodeEnvs } from './common/constants/env';
16
+ import { EnvVars, NodeEnvs } from './common/constants/env-inv';
13
17
 
14
18
  // ========================================================================= //
15
19
  // EXEC //
@@ -55,10 +59,18 @@ app.use((err: Error, _: Request, res: Response, _next: NextFunction) => {
55
59
  // =========================== Front-end Content =========================== //
56
60
 
57
61
  // Views directory (html)
58
- const viewsDir = path.join(__dirname, 'views');
62
+ const viewsDir = path.join(import.meta.dirname, 'views');
59
63
 
60
64
  // Set static directory (js and css).
61
- const staticDir = path.join(__dirname, 'public');
65
+ const staticDir = path.join(import.meta.dirname, 'public');
66
+
67
+ // Refresh the browser on changes. Imported lazily because livereload is a
68
+ // dev dependency and isn't installed in production.
69
+ if (EnvVars.NodeEnv === NodeEnvs.DEV) {
70
+ const { setupLiveReload } = await import('@src/common/utils/dev-only');
71
+ setupLiveReload(app, [staticDir, viewsDir]);
72
+ }
73
+
62
74
  app.use(express.static(staticDir));
63
75
 
64
76
  // Nav to users pg by default
@@ -1,6 +1,6 @@
1
1
  import HttpStatusCodes from '@src/common/constants/HttpStatusCodes';
2
- import { RouteError } from '@src/common/utils/route-errors';
3
- import User, { IUser, IUserInput } from '@src/models/User.model';
2
+ import { RouteError } from '@src/common/classes/route-errors';
3
+ import User, { type UserEntity, type UserInput } from '@src/entities/User';
4
4
  import UserRepo from '@src/repos/UserRepo';
5
5
 
6
6
  // ========================================================================= //
@@ -18,15 +18,15 @@ const Errors = {
18
18
  /**
19
19
  * Get all users.
20
20
  */
21
- function getAll(): Promise<IUser[]> {
21
+ function getAll(): Promise<UserEntity[]> {
22
22
  return UserRepo.getAll();
23
23
  }
24
24
 
25
25
  /**
26
26
  * Create a user from client input; the id and created date are set here.
27
27
  */
28
- async function addOne(input: IUserInput): Promise<IUser> {
29
- const user = User.new(input);
28
+ async function addOne(input: UserInput): Promise<UserEntity> {
29
+ const user = User.create(input);
30
30
  await UserRepo.add(user);
31
31
  return user;
32
32
  }
@@ -34,7 +34,7 @@ async function addOne(input: IUserInput): Promise<IUser> {
34
34
  /**
35
35
  * Update one user.
36
36
  */
37
- async function updateOne(user: IUser): Promise<void> {
37
+ async function updateOne(user: UserEntity): Promise<void> {
38
38
  const persists = await UserRepo.persists(user.id);
39
39
  if (!persists) {
40
40
  throw new RouteError(HttpStatusCodes.NOT_FOUND, Errors.USER_NOT_FOUND);
@@ -50,7 +50,7 @@
50
50
  <div id="all-users-anchor"></div>
51
51
  </div>
52
52
 
53
- <script src="/scripts/http.js"></script>
53
+ <script src="/scripts/HttpClient.js"></script>
54
54
  <script src="/scripts/renderUsers.js"></script>
55
55
  <script src="/scripts/users.js"></script>
56
56
  </body>
@@ -1,10 +1,10 @@
1
- import { IUser } from '@src/models/User.model';
1
+ import type { UserEntity } from '@src/entities/User';
2
2
 
3
3
  // ========================================================================= //
4
4
  // TYPES //
5
5
  // ========================================================================= //
6
6
 
7
- type UserArray = IUser[] | readonly IUser[];
7
+ type UserArray = UserEntity[] | readonly UserEntity[];
8
8
 
9
9
  // ========================================================================= //
10
10
  // FUNCTIONS //
@@ -31,7 +31,7 @@ export function compareUserArrays(a: UserArray, b: UserArray): boolean {
31
31
  /**
32
32
  * Sort user array by email.
33
33
  */
34
- function sortByEmail(arr: UserArray): IUser[] {
34
+ function sortByEmail(arr: UserArray): UserEntity[] {
35
35
  return [...arr].sort((x, y) => {
36
36
  return x.email.localeCompare(y.email);
37
37
  });
@@ -1,5 +1,5 @@
1
- import { ParseError } from 'jet-validators/utils';
2
- import { Response } from 'supertest';
1
+ import type { ParseError } from 'jet-validators/utils';
2
+ import type { Response } from 'supertest';
3
3
 
4
4
  // ========================================================================= //
5
5
  // TYPES //
@@ -20,7 +20,7 @@ describe('Front-end content', () => {
20
20
  });
21
21
 
22
22
  it.each([
23
- '/scripts/http.js',
23
+ '/scripts/HttpClient.js',
24
24
  '/scripts/renderUsers.js',
25
25
  '/scripts/users.js',
26
26
  '/scripts/lib/bootstrap.bundle.min.js',
@@ -1,5 +1,5 @@
1
- import supertest, { Test } from 'supertest';
2
- import TestAgent from 'supertest/lib/agent';
1
+ import supertest, { type Test } from 'supertest';
2
+ import type TestAgent from 'supertest/lib/agent.js';
3
3
  import { beforeAll } from 'vitest';
4
4
 
5
5
  import MockOrm from '@src/repos/MockOrm';
@@ -2,13 +2,13 @@ import jetid from 'jet-id';
2
2
 
3
3
  import HttpStatusCodes from '@src/common/constants/HttpStatusCodes';
4
4
  import Paths from '@src/common/constants/Paths';
5
- import { ValidationError } from '@src/common/utils/route-errors';
6
- import User, { IUser } from '@src/models/User.model';
5
+ import { ValidationError } from '@src/common/classes/route-errors';
6
+ import User, { type UserEntity } from '@src/entities/User';
7
7
  import UserRepo from '@src/repos/UserRepo';
8
8
  import UserService from '@src/services/UserService';
9
9
 
10
10
  import { compareUserArrays } from './common/comparators';
11
- import { TestRes } from './common/supertest-types';
11
+ import type { TestRes } from './common/supertest-types';
12
12
  import { agent } from './support/agent';
13
13
 
14
14
  // ========================================================================= //
@@ -16,9 +16,9 @@ import { agent } from './support/agent';
16
16
  // ========================================================================= //
17
17
 
18
18
  const DUMMY_USERS = [
19
- User.new({ name: 'Sean Maxwell', email: 'sean.maxwell@gmail.com' }),
20
- User.new({ name: 'John Smith', email: 'john.smith@gmail.com' }),
21
- User.new({ name: 'Gordan Freeman', email: 'gordan.freeman@gmail.com' }),
19
+ User.of('Sean Maxwell', 'sean.maxwell@gmail.com'),
20
+ User.of('John Smith', 'john.smith@gmail.com'),
21
+ User.of('Gordan Freeman', 'gordan.freeman@gmail.com'),
22
22
  ] as const;
23
23
 
24
24
  const { BAD_REQUEST, CREATED, INTERNAL_SERVER_ERROR, OK, NOT_FOUND } =
@@ -32,7 +32,7 @@ const { BAD_REQUEST, CREATED, INTERNAL_SERVER_ERROR, OK, NOT_FOUND } =
32
32
  // scenarios (i.e. a failed database connection).
33
33
 
34
34
  describe('UserRouter', () => {
35
- let dbUsers: IUser[] = [];
35
+ let dbUsers: UserEntity[] = [];
36
36
 
37
37
  beforeEach(async () => {
38
38
  await UserRepo.deleteAllUsers();
@@ -49,7 +49,7 @@ describe('UserRouter', () => {
49
49
  'should return a JSON object with all the users and a status code of ' +
50
50
  `"${OK}" if the request was successful.`,
51
51
  async () => {
52
- const res: TestRes<{ users: IUser[] }> = await agent.get(
52
+ const res: TestRes<{ users: UserEntity[] }> = await agent.get(
53
53
  Paths.Users.Get(),
54
54
  );
55
55
  expect(res.status).toBe(OK);
@@ -79,7 +79,7 @@ describe('UserRouter', () => {
79
79
  async () => {
80
80
  // Same payload shape the front-end sends
81
81
  const input = { name: 'a', email: 'a@a.com' };
82
- const res: TestRes<{ user: IUser }> = await agent
82
+ const res: TestRes<{ user: UserEntity }> = await agent
83
83
  .post(Paths.Users.Add())
84
84
  .send({ user: input });
85
85
  expect(res.status).toBe(CREATED);
@@ -134,7 +134,7 @@ describe('UserRouter', () => {
134
134
  'should return a JSON object with an error message and a status code ' +
135
135
  `of "${BAD_REQUEST}" if id is not a valid id`,
136
136
  async () => {
137
- const user = { ...User.new(), name: 'a', email: 'a@a.com', id: '5' };
137
+ const user = { ...User.create(), name: 'a', email: 'a@a.com', id: '5' };
138
138
  const res: TestRes = await agent
139
139
  .put(Paths.Users.Update())
140
140
  .send({ user });
@@ -149,7 +149,7 @@ describe('UserRouter', () => {
149
149
  `"${UserService.Errors.USER_NOT_FOUND}" and a status code of ` +
150
150
  `"${NOT_FOUND}" if the id was not found.`,
151
151
  async () => {
152
- const user = User.new({ id: jetid(), name: 'a', email: 'a@a.com' }),
152
+ const user = User.create({ id: jetid(), name: 'a', email: 'a@a.com' }),
153
153
  res: TestRes = await agent.put(Paths.Users.Update()).send({ user });
154
154
  expect(res.status).toBe(NOT_FOUND);
155
155
  expect(res.body.error).toBe(UserService.Errors.USER_NOT_FOUND);