express-generator-typescript 2.7.9 → 2.7.10
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/bin/cli.js +1 -1
- package/lib/project-files/package.json +1 -1
- package/lib/project-files/src/common/util/route-errors.ts +2 -2
- package/lib/project-files/src/models/User.ts +4 -2
- package/lib/project-files/src/repos/UserRepo.ts +4 -5
- package/lib/project-files/src/repos/database.test.json +1 -1
- package/lib/project-files/src/routes/common/util/index.ts +2 -2
- package/lib/project-files/tests/common/utils.ts +2 -2
- package/lib/project-files/tests/users.test.ts +43 -53
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ParseError } from 'jet-validators/utils';
|
|
2
2
|
|
|
3
3
|
import HTTP_STATUS_CODES, {
|
|
4
4
|
HttpStatusCodes,
|
|
@@ -28,7 +28,7 @@ export class ValidationError extends RouteError {
|
|
|
28
28
|
public static MESSAGE = 'The parseObj() function discovered one or ' +
|
|
29
29
|
'more errors.';
|
|
30
30
|
|
|
31
|
-
public constructor(errors:
|
|
31
|
+
public constructor(errors: ParseError[]) {
|
|
32
32
|
const msg = JSON.stringify({
|
|
33
33
|
message: ValidationError.MESSAGE,
|
|
34
34
|
errors,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isString, isUnsignedInteger } from 'jet-validators';
|
|
2
|
-
import { parseObject,
|
|
2
|
+
import { parseObject, OnErrorCallback } from 'jet-validators/utils';
|
|
3
3
|
|
|
4
4
|
import { transformIsDate } from '@src/common/util/validators';
|
|
5
5
|
import { IModel } from './common/types';
|
|
@@ -54,7 +54,9 @@ function __new__(user?: Partial<IUser>): IUser {
|
|
|
54
54
|
/**
|
|
55
55
|
* Check is a user object. For the route validation.
|
|
56
56
|
*/
|
|
57
|
-
|
|
57
|
+
|
|
58
|
+
// because this isn't marked with the symbol, the errors are not bubbling up
|
|
59
|
+
function test(arg: unknown, errCb?: OnErrorCallback): arg is IUser {
|
|
58
60
|
return !!parseUser(arg, errCb);
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -72,7 +72,7 @@ async function update(user: IUser): Promise<void> {
|
|
|
72
72
|
/**
|
|
73
73
|
* Delete one user.
|
|
74
74
|
*/
|
|
75
|
-
async function
|
|
75
|
+
async function __delete__(id: number): Promise<void> {
|
|
76
76
|
const db = await orm.openDb();
|
|
77
77
|
for (let i = 0; i < db.users.length; i++) {
|
|
78
78
|
if (db.users[i].id === id) {
|
|
@@ -82,7 +82,6 @@ async function delete_(id: number): Promise<void> {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
86
85
|
// **** Unit-Tests Only **** //
|
|
87
86
|
|
|
88
87
|
/**
|
|
@@ -104,7 +103,7 @@ async function deleteAllUsers(): Promise<void> {
|
|
|
104
103
|
* @internal
|
|
105
104
|
* Test-only helper. Do not use in production code.
|
|
106
105
|
*/
|
|
107
|
-
async function
|
|
106
|
+
async function insertMultiple(
|
|
108
107
|
users: IUser[] | readonly IUser[],
|
|
109
108
|
): Promise<IUser[]> {
|
|
110
109
|
const db = await orm.openDb(),
|
|
@@ -128,7 +127,7 @@ export default {
|
|
|
128
127
|
getAll,
|
|
129
128
|
add,
|
|
130
129
|
update,
|
|
131
|
-
delete:
|
|
130
|
+
delete: __delete__,
|
|
132
131
|
deleteAllUsers,
|
|
133
|
-
|
|
132
|
+
insertMultiple,
|
|
134
133
|
} as const;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"users":[{"id":
|
|
1
|
+
{"users":[{"id":169238117092,"name":"Bill","email":"sean.maxwell@gmail.com","created":"2026-01-01T23:26:38.953Z"},{"id":463030566103,"name":"John Smith","email":"john.smith@gmail.com","created":"2026-01-01T23:26:38.953Z"},{"id":420935775197,"name":"Gordan Freeman","email":"gordan.freeman@gmail.com","created":"2026-01-01T23:26:38.953Z"}]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseObject,
|
|
1
|
+
import { parseObject, Schema } from 'jet-validators/utils';
|
|
2
2
|
import { ValidationError } from '@src/common/util/route-errors';
|
|
3
3
|
|
|
4
4
|
/******************************************************************************
|
|
@@ -9,7 +9,7 @@ import { ValidationError } from '@src/common/util/route-errors';
|
|
|
9
9
|
* Throw a "ParseObjError" when "parseObject" fails. Also extract a nested
|
|
10
10
|
* "ParseObjError" and add it to the nestedErrors array.
|
|
11
11
|
*/
|
|
12
|
-
export function parseReq<U extends
|
|
12
|
+
export function parseReq<U extends Schema>(schema: U) {
|
|
13
13
|
return parseObject(schema, errors => {
|
|
14
14
|
throw new ValidationError(errors);
|
|
15
15
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ParseError, parseJson } from 'jet-validators/utils';
|
|
2
2
|
import { isString } from 'jet-validators';
|
|
3
3
|
import { IUser } from '@src/models/User';
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ type TUserArray = IUser[] | readonly IUser[];
|
|
|
10
10
|
|
|
11
11
|
interface IValidationError {
|
|
12
12
|
message: string;
|
|
13
|
-
errors:
|
|
13
|
+
errors: ParseError[];
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/******************************************************************************
|
|
@@ -14,13 +14,19 @@ import { TRes } from './common/types';
|
|
|
14
14
|
Constants
|
|
15
15
|
******************************************************************************/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
const DB_USERS = [
|
|
17
|
+
const DUMMY_USERS = [
|
|
19
18
|
User.new({ name: 'Sean Maxwell', email: 'sean.maxwell@gmail.com' }),
|
|
20
19
|
User.new({ name: 'John Smith', email: 'john.smith@gmail.com' }),
|
|
21
20
|
User.new({ name: 'Gordan Freeman', email: 'gordan.freeman@gmail.com' }),
|
|
22
21
|
] as const;
|
|
23
22
|
|
|
23
|
+
const {
|
|
24
|
+
BadRequest,
|
|
25
|
+
Created,
|
|
26
|
+
Ok: OK,
|
|
27
|
+
NotFound,
|
|
28
|
+
} = HTTP_STATUS_CODES;
|
|
29
|
+
|
|
24
30
|
/******************************************************************************
|
|
25
31
|
Tests
|
|
26
32
|
IMPORTANT: Following TypeScript best practices, we test all scenarios that
|
|
@@ -32,101 +38,85 @@ describe('UserRouter', () => {
|
|
|
32
38
|
|
|
33
39
|
let dbUsers: IUser[] = [];
|
|
34
40
|
|
|
35
|
-
// Run before all tests
|
|
36
41
|
beforeEach(async () => {
|
|
37
42
|
await UserRepo.deleteAllUsers();
|
|
38
|
-
dbUsers = await UserRepo.
|
|
43
|
+
dbUsers = await UserRepo.insertMultiple(DUMMY_USERS);
|
|
39
44
|
});
|
|
40
45
|
|
|
41
|
-
// Get all users
|
|
42
46
|
describe(`"GET:${Paths.Users.Get}"`, () => {
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`of "${HTTP_STATUS_CODES.Ok}" if the request was successful.`, async () => {
|
|
48
|
+
it('should return a JSON object with all the users and a status code of ' +
|
|
49
|
+
`"${OK}" if the request was successful.`, async () => {
|
|
47
50
|
const res: TRes<{ users: IUser[]}> = await agent.get(Paths.Users.Get);
|
|
48
|
-
expect(res.status).toBe(
|
|
49
|
-
expect(compareUserArrays(res.body.users,
|
|
51
|
+
expect(res.status).toBe(OK);
|
|
52
|
+
expect(compareUserArrays(res.body.users, DUMMY_USERS)).toBeTruthy();
|
|
50
53
|
});
|
|
51
54
|
});
|
|
52
55
|
|
|
53
|
-
// Test add user
|
|
54
56
|
describe(`"POST:${Paths.Users.Add}"`, () => {
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
'the request was successful.', async () => {
|
|
58
|
+
it(`should return a status code of "${Created}" if the request was ` +
|
|
59
|
+
'successful.', async () => {
|
|
59
60
|
const user = User.new({ name: 'a', email: 'a@a.com' }),
|
|
60
61
|
res = await agent.post(Paths.Users.Add).send({ user });
|
|
61
|
-
expect(res.status).toBe(
|
|
62
|
+
expect(res.status).toBe(Created);
|
|
62
63
|
});
|
|
63
64
|
|
|
64
|
-
// Missing param
|
|
65
65
|
it('should return a JSON object with an error message of and a status ' +
|
|
66
|
-
`code of "${
|
|
67
|
-
'missing.', async () => {
|
|
66
|
+
`code of "${BadRequest}" if the user param was missing.`, async () => {
|
|
68
67
|
const res: TRes = await agent.post(Paths.Users.Add).send({ user: null });
|
|
69
|
-
expect(res.status).toBe(
|
|
70
|
-
const
|
|
71
|
-
expect(
|
|
72
|
-
expect(
|
|
68
|
+
expect(res.status).toBe(BadRequest);
|
|
69
|
+
const errorObject = parseValidationError(res.body.error);
|
|
70
|
+
expect(errorObject.message).toBe(ValidationError.MESSAGE);
|
|
71
|
+
expect(errorObject.errors[0].key).toStrictEqual('user');
|
|
73
72
|
});
|
|
74
73
|
});
|
|
75
74
|
|
|
76
|
-
// Update users
|
|
77
75
|
describe(`"PUT:${Paths.Users.Update}"`, () => {
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
});
|
|
77
|
+
it(`should return a status code of "${OK}" if the request was successfull`,
|
|
78
|
+
async () => {
|
|
79
|
+
const user = DUMMY_USERS[0];
|
|
80
|
+
user.name = 'Bill';
|
|
81
|
+
const res = await agent.put(Paths.Users.Update).send({ user });
|
|
82
|
+
expect(res.status).toBe(OK);
|
|
83
|
+
});
|
|
87
84
|
|
|
88
|
-
// Id is the wrong data type
|
|
89
85
|
it('should return a JSON object with an error message and a status code ' +
|
|
90
|
-
`of "${
|
|
91
|
-
async () => {
|
|
86
|
+
`of "${BadRequest}" if id is the wrong data type`, async () => {
|
|
92
87
|
const user = User.new();
|
|
93
88
|
user.id = ('5' as unknown as number);
|
|
94
89
|
const res: TRes = await agent.put(Paths.Users.Update).send({ user });
|
|
95
|
-
expect(res.status).toBe(
|
|
90
|
+
expect(res.status).toBe(BadRequest);
|
|
96
91
|
const errorObj = parseValidationError(res.body.error);
|
|
97
92
|
expect(errorObj.message).toBe(ValidationError.MESSAGE);
|
|
98
|
-
expect(errorObj.errors[0].
|
|
99
|
-
expect(errorObj.errors[0].children?.[0].prop).toBe('id');
|
|
93
|
+
expect(errorObj.errors[0].keyPath).toStrictEqual(['user', 'id']);
|
|
100
94
|
});
|
|
101
95
|
|
|
102
|
-
// User not found
|
|
103
96
|
it('should return a JSON object with the error message of ' +
|
|
104
|
-
`"${USER_NOT_FOUND_ERR}" and a status code of ` +
|
|
105
|
-
|
|
97
|
+
`"${USER_NOT_FOUND_ERR}" and a status code of "${NotFound}" if the id ` +
|
|
98
|
+
'was not found.', async () => {
|
|
106
99
|
const user = User.new({ id: 4, name: 'a', email: 'a@a.com' }),
|
|
107
100
|
res: TRes = await agent.put(Paths.Users.Update).send({ user });
|
|
108
|
-
expect(res.status).toBe(
|
|
101
|
+
expect(res.status).toBe(NotFound);
|
|
109
102
|
expect(res.body.error).toBe(USER_NOT_FOUND_ERR);
|
|
110
103
|
});
|
|
111
104
|
});
|
|
112
105
|
|
|
113
|
-
// Delete User
|
|
114
106
|
describe(`"DELETE:${Paths.Users.Delete()}"`, () => {
|
|
115
107
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
res
|
|
121
|
-
|
|
122
|
-
});
|
|
108
|
+
it(`should return a status code of "${OK}" if the request was successful.`,
|
|
109
|
+
async () => {
|
|
110
|
+
const id = dbUsers[0].id,
|
|
111
|
+
res = await agent.delete(Paths.Users.Delete(id));
|
|
112
|
+
expect(res.status).toBe(OK);
|
|
113
|
+
});
|
|
123
114
|
|
|
124
|
-
// User not found
|
|
125
115
|
it('should return a JSON object with the error message of ' +
|
|
126
|
-
`"${USER_NOT_FOUND_ERR}" and a status code of ` +
|
|
127
|
-
|
|
116
|
+
`"${USER_NOT_FOUND_ERR}" and a status code of "${NotFound}" if the id ` +
|
|
117
|
+
'was not found.', async () => {
|
|
128
118
|
const res: TRes = await agent.delete(Paths.Users.Delete(-1));
|
|
129
|
-
expect(res.status).toBe(
|
|
119
|
+
expect(res.status).toBe(NotFound);
|
|
130
120
|
expect(res.body.error).toBe(USER_NOT_FOUND_ERR);
|
|
131
121
|
});
|
|
132
122
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-generator-typescript",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.10",
|
|
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",
|