express-generator-typescript 2.8.1 → 2.9.0
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/README.md +6 -7
- package/bin/cli.js +91 -32
- package/lib/express-generator-typescript.js +125 -151
- package/lib/{project-files → template}/.prettierignore +2 -4
- package/lib/template/README.md +50 -0
- package/lib/template/bs-config.js +8 -0
- package/lib/{project-files → template}/config/.env.development +4 -6
- package/lib/{project-files → template}/config/.env.production +4 -5
- package/lib/{project-files → template}/config/.env.test +4 -5
- package/lib/{project-files → template}/eslint.config.ts +4 -0
- package/lib/template/gitignore +10 -0
- package/lib/{project-files → template}/package.json +31 -35
- package/lib/{project-files → template}/src/common/constants/HttpStatusCodes.ts +7 -8
- package/lib/template/src/common/constants/Paths.ts +22 -0
- package/lib/template/src/common/constants/env.ts +28 -0
- package/lib/template/src/common/types/utility-types.ts +5 -0
- package/lib/template/src/common/utils/date-utils.ts +29 -0
- package/lib/template/src/common/utils/route-errors.ts +37 -0
- package/lib/template/src/main.ts +24 -0
- package/lib/template/src/models/User.model.ts +95 -0
- package/lib/template/src/models/common/types.ts +10 -0
- package/lib/template/src/public/scripts/http.js +25 -0
- package/lib/template/src/public/scripts/lib/bootstrap.bundle.min.js +4229 -0
- package/lib/template/src/public/scripts/renderUsers.js +90 -0
- package/lib/template/src/public/scripts/users.js +142 -0
- package/lib/template/src/public/stylesheets/lib/bootstrap.min.css +11798 -0
- package/lib/template/src/repos/MockOrm.ts +71 -0
- package/lib/{project-files → template}/src/repos/UserRepo.ts +21 -35
- package/lib/template/src/repos/common/database.json +28 -0
- package/lib/{project-files → template}/src/routes/UserRoutes.ts +15 -18
- package/lib/template/src/routes/apiRouter.ts +28 -0
- package/lib/template/src/routes/common/express-types.ts +9 -0
- package/lib/template/src/routes/common/parseReq.ts +23 -0
- package/lib/{project-files → template}/src/server.ts +23 -18
- package/lib/template/src/services/UserService.ts +66 -0
- package/lib/{project-files → template}/src/views/users.html +13 -6
- package/lib/{project-files → template}/tests/common/comparators.ts +6 -6
- package/lib/template/tests/common/supertest-types.ts +11 -0
- package/lib/template/tests/frontend.test.ts +33 -0
- package/lib/template/tests/support/agent.ts +23 -0
- package/lib/template/tests/users.test.ts +205 -0
- package/lib/{project-files → template}/tsconfig.json +1 -3
- package/lib/{project-files → template}/tsconfig.prod.json +3 -9
- package/lib/{project-files → template}/vitest.config.mts +2 -0
- package/package.json +69 -52
- package/lib/cli.js +0 -33
- package/lib/project-files/README.md +0 -39
- package/lib/project-files/gitignore +0 -4
- package/lib/project-files/src/common/constants/Paths.ts +0 -15
- package/lib/project-files/src/common/constants/env.ts +0 -28
- package/lib/project-files/src/common/types/structure-utils.ts +0 -2
- package/lib/project-files/src/common/utils/number-utils.ts +0 -10
- package/lib/project-files/src/common/utils/route-errors.ts +0 -35
- package/lib/project-files/src/common/utils/validators.ts +0 -14
- package/lib/project-files/src/main.ts +0 -24
- package/lib/project-files/src/models/User.model.ts +0 -72
- package/lib/project-files/src/models/common/types.ts +0 -4
- package/lib/project-files/src/public/stylesheets/lib/bootstrap.min.css +0 -6
- package/lib/project-files/src/repos/MockOrm.ts +0 -63
- package/lib/project-files/src/repos/common/database.json +0 -1
- package/lib/project-files/src/repos/common/database.test.json +0 -1
- package/lib/project-files/src/routes/apiRouter.ts +0 -28
- package/lib/project-files/src/routes/common/express-types.ts +0 -8
- package/lib/project-files/src/routes/common/parseReq.ts +0 -19
- package/lib/project-files/src/services/UserService.ts +0 -64
- package/lib/project-files/tests/common/error-utils.ts +0 -25
- package/lib/project-files/tests/common/supertest-types.ts +0 -15
- package/lib/project-files/tests/support/agent.ts +0 -23
- package/lib/project-files/tests/users.test.ts +0 -131
- /package/lib/{project-files → template}/.prettierrc.json +0 -0
- /package/lib/{project-files → template}/src/public/stylesheets/users.css +0 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import jetid from 'jet-id';
|
|
2
|
+
|
|
3
|
+
import HttpStatusCodes from '@src/common/constants/HttpStatusCodes';
|
|
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';
|
|
7
|
+
import UserRepo from '@src/repos/UserRepo';
|
|
8
|
+
import UserService from '@src/services/UserService';
|
|
9
|
+
|
|
10
|
+
import { compareUserArrays } from './common/comparators';
|
|
11
|
+
import { TestRes } from './common/supertest-types';
|
|
12
|
+
import { agent } from './support/agent';
|
|
13
|
+
|
|
14
|
+
// ========================================================================= //
|
|
15
|
+
// CONSTANTS //
|
|
16
|
+
// ========================================================================= //
|
|
17
|
+
|
|
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' }),
|
|
22
|
+
] as const;
|
|
23
|
+
|
|
24
|
+
const { BAD_REQUEST, CREATED, INTERNAL_SERVER_ERROR, OK, NOT_FOUND } =
|
|
25
|
+
HttpStatusCodes;
|
|
26
|
+
|
|
27
|
+
// ========================================================================= //
|
|
28
|
+
// TESTS //
|
|
29
|
+
// ========================================================================= //
|
|
30
|
+
// IMPORTANT: Following TypeScript best practices, we test all scenarios that
|
|
31
|
+
// can be triggered by a user under normal circumstances. Not all theoretically
|
|
32
|
+
// scenarios (i.e. a failed database connection).
|
|
33
|
+
|
|
34
|
+
describe('UserRouter', () => {
|
|
35
|
+
let dbUsers: IUser[] = [];
|
|
36
|
+
|
|
37
|
+
beforeEach(async () => {
|
|
38
|
+
await UserRepo.deleteAllUsers();
|
|
39
|
+
dbUsers = await UserRepo.insertMultiple(DUMMY_USERS);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
afterEach(() => {
|
|
43
|
+
vi.restoreAllMocks();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// ---- `Get`
|
|
47
|
+
describe(`"GET:${Paths.Users.Get()}"`, () => {
|
|
48
|
+
it(
|
|
49
|
+
'should return a JSON object with all the users and a status code of ' +
|
|
50
|
+
`"${OK}" if the request was successful.`,
|
|
51
|
+
async () => {
|
|
52
|
+
const res: TestRes<{ users: IUser[] }> = await agent.get(
|
|
53
|
+
Paths.Users.Get(),
|
|
54
|
+
);
|
|
55
|
+
expect(res.status).toBe(OK);
|
|
56
|
+
expect(compareUserArrays(res.body.users, DUMMY_USERS)).toBeTruthy();
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
it(
|
|
61
|
+
`should return a JSON error and a status code of ` +
|
|
62
|
+
`"${INTERNAL_SERVER_ERROR}" if an unexpected error is thrown.`,
|
|
63
|
+
async () => {
|
|
64
|
+
vi.spyOn(UserService, 'getAll').mockRejectedValueOnce(
|
|
65
|
+
new Error('boom'),
|
|
66
|
+
);
|
|
67
|
+
const res: TestRes = await agent.get(Paths.Users.Get());
|
|
68
|
+
expect(res.status).toBe(INTERNAL_SERVER_ERROR);
|
|
69
|
+
expect(res.body.error).toBe('Internal Server Error');
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// ---- `Add`
|
|
75
|
+
describe(`"POST:${Paths.Users.Add()}"`, () => {
|
|
76
|
+
it(
|
|
77
|
+
`should return a status code of "${CREATED}" and persist the user ` +
|
|
78
|
+
'with a server-generated id if the request was successful.',
|
|
79
|
+
async () => {
|
|
80
|
+
// Same payload shape the front-end sends
|
|
81
|
+
const input = { name: 'a', email: 'a@a.com' };
|
|
82
|
+
const res: TestRes<{ user: IUser }> = await agent
|
|
83
|
+
.post(Paths.Users.Add())
|
|
84
|
+
.send({ user: input });
|
|
85
|
+
expect(res.status).toBe(CREATED);
|
|
86
|
+
expect(User.isId(res.body.user.id)).toBe(true);
|
|
87
|
+
const all = await UserRepo.getAll();
|
|
88
|
+
expect(all).toHaveLength(DUMMY_USERS.length + 1);
|
|
89
|
+
expect(all).toContainEqual(res.body.user);
|
|
90
|
+
},
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
it(
|
|
94
|
+
'should return a JSON object with an error message and a status ' +
|
|
95
|
+
`code of "${BAD_REQUEST}" if the user param was missing.`,
|
|
96
|
+
async () => {
|
|
97
|
+
const res: TestRes = await agent
|
|
98
|
+
.post(Paths.Users.Add())
|
|
99
|
+
.send({ user: null });
|
|
100
|
+
expect(res.status).toBe(BAD_REQUEST);
|
|
101
|
+
expect(res.body.error).toBe(ValidationError.MESSAGE);
|
|
102
|
+
expect(res.body.errors?.[0].key).toStrictEqual('user');
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
it(
|
|
107
|
+
`should return a status code of "${BAD_REQUEST}" if the name is ` +
|
|
108
|
+
'empty.',
|
|
109
|
+
async () => {
|
|
110
|
+
const res: TestRes = await agent
|
|
111
|
+
.post(Paths.Users.Add())
|
|
112
|
+
.send({ user: { name: '', email: 'a@a.com' } });
|
|
113
|
+
expect(res.status).toBe(BAD_REQUEST);
|
|
114
|
+
expect(await UserRepo.getAll()).toHaveLength(DUMMY_USERS.length);
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// ---- `Update`
|
|
120
|
+
describe(`"PUT:${Paths.Users.Update()}"`, () => {
|
|
121
|
+
it(
|
|
122
|
+
`should return a status code of "${OK}" and save the change if the ` +
|
|
123
|
+
'request was successful.',
|
|
124
|
+
async () => {
|
|
125
|
+
const user = { ...dbUsers[0], name: 'Bill' };
|
|
126
|
+
const res = await agent.put(Paths.Users.Update()).send({ user });
|
|
127
|
+
expect(res.status).toBe(OK);
|
|
128
|
+
const saved = (await UserRepo.getAll()).find((u) => u.id === user.id);
|
|
129
|
+
expect(saved?.name).toBe('Bill');
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
it(
|
|
134
|
+
'should return a JSON object with an error message and a status code ' +
|
|
135
|
+
`of "${BAD_REQUEST}" if id is not a valid id`,
|
|
136
|
+
async () => {
|
|
137
|
+
const user = { ...User.new(), name: 'a', email: 'a@a.com', id: '5' };
|
|
138
|
+
const res: TestRes = await agent
|
|
139
|
+
.put(Paths.Users.Update())
|
|
140
|
+
.send({ user });
|
|
141
|
+
expect(res.status).toBe(BAD_REQUEST);
|
|
142
|
+
expect(res.body.error).toBe(ValidationError.MESSAGE);
|
|
143
|
+
expect(res.body.errors?.[0].keyPath).toStrictEqual(['user', 'id']);
|
|
144
|
+
},
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
it(
|
|
148
|
+
'should return a JSON object with the error message of ' +
|
|
149
|
+
`"${UserService.Errors.USER_NOT_FOUND}" and a status code of ` +
|
|
150
|
+
`"${NOT_FOUND}" if the id was not found.`,
|
|
151
|
+
async () => {
|
|
152
|
+
const user = User.new({ id: jetid(), name: 'a', email: 'a@a.com' }),
|
|
153
|
+
res: TestRes = await agent.put(Paths.Users.Update()).send({ user });
|
|
154
|
+
expect(res.status).toBe(NOT_FOUND);
|
|
155
|
+
expect(res.body.error).toBe(UserService.Errors.USER_NOT_FOUND);
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// ---- `Delete`
|
|
161
|
+
describe(`"DELETE:${Paths.Users.Delete()}"`, () => {
|
|
162
|
+
it(
|
|
163
|
+
`should return a status code of "${OK}" and remove the user if the ` +
|
|
164
|
+
'request was successful.',
|
|
165
|
+
async () => {
|
|
166
|
+
const id = dbUsers[0].id,
|
|
167
|
+
res = await agent.delete(Paths.Users.Delete({ id }));
|
|
168
|
+
expect(res.status).toBe(OK);
|
|
169
|
+
expect(await UserRepo.persists(id)).toBe(false);
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
it(
|
|
174
|
+
'should return a JSON object with the error message of ' +
|
|
175
|
+
`"${UserService.Errors.USER_NOT_FOUND}" and a status code of ` +
|
|
176
|
+
`"${NOT_FOUND}" if the id was not found.`,
|
|
177
|
+
async () => {
|
|
178
|
+
const res: TestRes = await agent.delete(
|
|
179
|
+
Paths.Users.Delete({ id: jetid() }),
|
|
180
|
+
);
|
|
181
|
+
expect(res.status).toBe(NOT_FOUND);
|
|
182
|
+
expect(res.body.error).toBe(UserService.Errors.USER_NOT_FOUND);
|
|
183
|
+
},
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
it(
|
|
187
|
+
`should return a status code of "${BAD_REQUEST}" if the id is not a ` +
|
|
188
|
+
'valid id.',
|
|
189
|
+
async () => {
|
|
190
|
+
const res = await agent.delete(Paths.Users.Delete({ id: -1 }));
|
|
191
|
+
expect(res.status).toBe(BAD_REQUEST);
|
|
192
|
+
},
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
it(
|
|
196
|
+
`should return a status code of "${BAD_REQUEST}" if the id query ` +
|
|
197
|
+
'param is missing.',
|
|
198
|
+
async () => {
|
|
199
|
+
const res: TestRes = await agent.delete(Paths.Users.Delete());
|
|
200
|
+
expect(res.status).toBe(BAD_REQUEST);
|
|
201
|
+
expect(res.body.errors?.[0].key).toStrictEqual('id');
|
|
202
|
+
},
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
"module": "commonjs",
|
|
5
5
|
"lib": ["ES2020"],
|
|
6
6
|
"strict": true,
|
|
7
|
-
"baseUrl": "./",
|
|
8
7
|
"esModuleInterop": true,
|
|
9
8
|
"skipLibCheck": true,
|
|
10
9
|
"forceConsistentCasingInFileNames": true,
|
|
11
10
|
"paths": {
|
|
12
|
-
"@src/*": ["src/*"]
|
|
11
|
+
"@src/*": ["./src/*"]
|
|
13
12
|
},
|
|
14
13
|
"useUnknownInCatchVariables": false,
|
|
15
14
|
"types": ["vitest/globals"]
|
|
@@ -21,7 +20,6 @@
|
|
|
21
20
|
"include": [
|
|
22
21
|
"src/**/*.ts",
|
|
23
22
|
"tests/**/*.ts",
|
|
24
|
-
"scripts",
|
|
25
23
|
"eslint.config.ts",
|
|
26
24
|
"vitest.config.mts"
|
|
27
25
|
],
|
|
@@ -4,24 +4,18 @@
|
|
|
4
4
|
"module": "CommonJS",
|
|
5
5
|
"lib": ["ES2020"],
|
|
6
6
|
"strict": true,
|
|
7
|
-
"
|
|
7
|
+
"rootDir": "./src",
|
|
8
8
|
"outDir": "dist",
|
|
9
9
|
"esModuleInterop": true,
|
|
10
10
|
"skipLibCheck": true,
|
|
11
11
|
"forceConsistentCasingInFileNames": true,
|
|
12
12
|
"paths": {
|
|
13
|
-
"@src/*": ["src/*"]
|
|
13
|
+
"@src/*": ["./src/*"]
|
|
14
14
|
},
|
|
15
15
|
"useUnknownInCatchVariables": false,
|
|
16
16
|
"sourceMap": false,
|
|
17
17
|
"removeComments": true
|
|
18
18
|
},
|
|
19
19
|
"include": ["src/**/*.ts"],
|
|
20
|
-
"exclude": [
|
|
21
|
-
"tests",
|
|
22
|
-
"src/public/",
|
|
23
|
-
"scripts",
|
|
24
|
-
"eslint.config.ts",
|
|
25
|
-
"vitest.config.js"
|
|
26
|
-
]
|
|
20
|
+
"exclude": ["src/public/"]
|
|
27
21
|
}
|
|
@@ -7,6 +7,8 @@ const config = defineConfig({
|
|
|
7
7
|
environment: 'node',
|
|
8
8
|
setupFiles: ['dotenv/config', './tests/support/agent.ts'],
|
|
9
9
|
isolate: true,
|
|
10
|
+
// All test files share one JSON database file, so run them one at a time
|
|
11
|
+
fileParallelism: false,
|
|
10
12
|
env: {
|
|
11
13
|
DOTENV_CONFIG_PATH: 'config/.env.test',
|
|
12
14
|
},
|
package/package.json
CHANGED
|
@@ -1,52 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "express-generator-typescript",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Generate new Express applications similar to express-generate which but sets it up to use TypeScript instead",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
},
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "express-generator-typescript",
|
|
3
|
+
"version": "2.9.0",
|
|
4
|
+
"description": "Generate new Express applications similar to express-generate which but sets it up to use TypeScript instead",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"commit": "git add -A && git commit -m \"dev commit\"",
|
|
7
|
+
"commit:push": "npm run commit && git push",
|
|
8
|
+
"install:clean": "rm -rf node_modules && rm -rf package-lock.json && npm i",
|
|
9
|
+
"prepack": "npm run readme:swap",
|
|
10
|
+
"postpack": "npm run readme:restore",
|
|
11
|
+
"readme:swap": "node scripts/readme.js swap",
|
|
12
|
+
"readme:restore": "node scripts/readme.js restore",
|
|
13
|
+
"test": "node --test \"tests/**/*.test.js\"",
|
|
14
|
+
"test:e2e": "node scripts/e2e.js"
|
|
15
|
+
},
|
|
16
|
+
"main": "lib/express-generator-typescript.js",
|
|
17
|
+
"bin": {
|
|
18
|
+
"express-generator-typescript": "bin/cli.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"bin/",
|
|
22
|
+
"lib/",
|
|
23
|
+
"!lib/template/node_modules/",
|
|
24
|
+
"!lib/template/package-lock.json",
|
|
25
|
+
"!lib/template/dist/",
|
|
26
|
+
"!lib/template/.vscode/",
|
|
27
|
+
"!lib/template/tsconfig.tsbuildinfo",
|
|
28
|
+
"!lib/template/**/*.log",
|
|
29
|
+
"!lib/template/src/repos/common/database.test.json"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=22.12.0"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/seanpmaxwell/express-generator-typescript.git"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"express",
|
|
40
|
+
"express-generator",
|
|
41
|
+
"express-generator-typescript",
|
|
42
|
+
"typescript",
|
|
43
|
+
"typescript-express",
|
|
44
|
+
"api",
|
|
45
|
+
"rest",
|
|
46
|
+
"rest-api",
|
|
47
|
+
"scaffold",
|
|
48
|
+
"scaffolding",
|
|
49
|
+
"cli",
|
|
50
|
+
"generator",
|
|
51
|
+
"nodejs",
|
|
52
|
+
"backend",
|
|
53
|
+
"boilerplate",
|
|
54
|
+
"starter",
|
|
55
|
+
"template",
|
|
56
|
+
"express-ts",
|
|
57
|
+
"express5",
|
|
58
|
+
"server",
|
|
59
|
+
"tooling",
|
|
60
|
+
"vitest",
|
|
61
|
+
"eslint"
|
|
62
|
+
],
|
|
63
|
+
"author": "sean maxwell",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/seanpmaxwell/express-generator-typescript/issues"
|
|
67
|
+
},
|
|
68
|
+
"homepage": "https://github.com/seanpmaxwell/express-generator-typescript#readme"
|
|
69
|
+
}
|
package/lib/cli.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const path = require('path'),
|
|
4
|
-
expressGenTs = require('../lib/express-generator-typescript');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/******************************************************************************
|
|
8
|
-
Run
|
|
9
|
-
******************************************************************************/
|
|
10
|
-
|
|
11
|
-
// Init
|
|
12
|
-
console.log('Setting up new Express/TypeScript project...');
|
|
13
|
-
const args = process.argv.slice(2);
|
|
14
|
-
|
|
15
|
-
// Setup use yarn
|
|
16
|
-
let useYarn = false;
|
|
17
|
-
const useYarnIdx = args.indexOf('--use-yarn');
|
|
18
|
-
if (useYarnIdx > -1) {
|
|
19
|
-
useYarn = true;
|
|
20
|
-
args.splice(useYarnIdx, 1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Setup destination
|
|
24
|
-
let destination = 'express-gen-ts';
|
|
25
|
-
if (args.length > 0) {
|
|
26
|
-
destination = args[0];
|
|
27
|
-
}
|
|
28
|
-
destination = path.join(process.cwd(), destination);
|
|
29
|
-
|
|
30
|
-
// Creating new project finished
|
|
31
|
-
expressGenTs(destination, useYarn).then(() => {
|
|
32
|
-
console.log('Project setup complete!');
|
|
33
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
## About
|
|
2
|
-
|
|
3
|
-
This project was created with [express-generator-typescript](https://github.com/seanpmaxwell/express-generator-typescript).
|
|
4
|
-
|
|
5
|
-
## Available Scripts
|
|
6
|
-
|
|
7
|
-
### `npm run clean-install`
|
|
8
|
-
|
|
9
|
-
Remove the existing `node_modules/` folder, `package-lock.json`, and reinstall all library modules.
|
|
10
|
-
|
|
11
|
-
### `npm run dev`
|
|
12
|
-
|
|
13
|
-
Run the server in development with hot reloading and browser refresh (see `package.json` for all `npm run dev` variations)<br/>
|
|
14
|
-
|
|
15
|
-
**IMPORTANT** development mode uses `swc` for performance reasons which DOES NOT check for typescript errors. Run `npm run type-check` to check for type errors. NOTE: you should use your IDE to prevent most type errors.
|
|
16
|
-
|
|
17
|
-
### `npm test`
|
|
18
|
-
|
|
19
|
-
Run unit-tests with <a href="https://vitest.dev/guide/">vitest</a>.
|
|
20
|
-
|
|
21
|
-
### `npm run lint`
|
|
22
|
-
|
|
23
|
-
Check for linting errors.
|
|
24
|
-
|
|
25
|
-
### `npm run build`
|
|
26
|
-
|
|
27
|
-
Build the project for production.
|
|
28
|
-
|
|
29
|
-
### `npm start`
|
|
30
|
-
|
|
31
|
-
Run the production build (Must be built first).
|
|
32
|
-
|
|
33
|
-
### `npm run type-check`
|
|
34
|
-
|
|
35
|
-
Check for typescript errors.
|
|
36
|
-
|
|
37
|
-
## Additional Notes
|
|
38
|
-
|
|
39
|
-
- If `npm run dev` gives you issues with bcrypt on MacOS you may need to run: `npm rebuild bcrypt --build-from-source`.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import jetPaths from 'jet-paths';
|
|
2
|
-
|
|
3
|
-
const Paths = {
|
|
4
|
-
_: '/api',
|
|
5
|
-
Users: {
|
|
6
|
-
_: '/users',
|
|
7
|
-
Get: '/all',
|
|
8
|
-
Add: '/add',
|
|
9
|
-
Update: '/update',
|
|
10
|
-
Delete: '/delete/:id',
|
|
11
|
-
},
|
|
12
|
-
} as const;
|
|
13
|
-
|
|
14
|
-
export const JetPaths = jetPaths(Paths);
|
|
15
|
-
export default Paths;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import jetEnv, { num } from 'jet-env';
|
|
2
|
-
import tspo from 'tspo';
|
|
3
|
-
|
|
4
|
-
/******************************************************************************
|
|
5
|
-
Constants
|
|
6
|
-
******************************************************************************/
|
|
7
|
-
|
|
8
|
-
// NOTE: These need to match the names of your ".env" files
|
|
9
|
-
export const NodeEnvs = {
|
|
10
|
-
DEV: 'development',
|
|
11
|
-
TEST: 'test',
|
|
12
|
-
PRODUCTION: 'production',
|
|
13
|
-
} as const;
|
|
14
|
-
|
|
15
|
-
/******************************************************************************
|
|
16
|
-
Setup
|
|
17
|
-
******************************************************************************/
|
|
18
|
-
|
|
19
|
-
const EnvVars = jetEnv({
|
|
20
|
-
NodeEnv: (v) => tspo.isValue(NodeEnvs, v),
|
|
21
|
-
Port: num,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
/******************************************************************************
|
|
25
|
-
Export default
|
|
26
|
-
******************************************************************************/
|
|
27
|
-
|
|
28
|
-
export default EnvVars;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/******************************************************************************
|
|
2
|
-
Functions
|
|
3
|
-
******************************************************************************/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Get a random number between 1 and 1,000,000,000,000
|
|
7
|
-
*/
|
|
8
|
-
export function getRandomInt(): number {
|
|
9
|
-
return Math.floor(Math.random() * 1_000_000_000_000);
|
|
10
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { ParseError } from 'jet-validators/utils';
|
|
2
|
-
|
|
3
|
-
import HttpStatusCodes from '@src/common/constants/HttpStatusCodes';
|
|
4
|
-
|
|
5
|
-
/******************************************************************************
|
|
6
|
-
Classes
|
|
7
|
-
******************************************************************************/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Error with status code and message.
|
|
11
|
-
*/
|
|
12
|
-
export class RouteError extends Error {
|
|
13
|
-
public status: HttpStatusCodes;
|
|
14
|
-
|
|
15
|
-
public constructor(status: HttpStatusCodes, message: string) {
|
|
16
|
-
super(message);
|
|
17
|
-
this.status = status;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Handle "parseObj" errors.
|
|
23
|
-
*/
|
|
24
|
-
export class ValidationError extends RouteError {
|
|
25
|
-
public static MESSAGE =
|
|
26
|
-
'The parseObj() function discovered one or ' + 'more errors.';
|
|
27
|
-
|
|
28
|
-
public constructor(errors: ParseError[]) {
|
|
29
|
-
const msg = JSON.stringify({
|
|
30
|
-
message: ValidationError.MESSAGE,
|
|
31
|
-
errors,
|
|
32
|
-
});
|
|
33
|
-
super(HttpStatusCodes.BAD_REQUEST, msg);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { isDate } from 'jet-validators';
|
|
2
|
-
import { transform } from 'jet-validators/utils';
|
|
3
|
-
|
|
4
|
-
/******************************************************************************
|
|
5
|
-
Functions
|
|
6
|
-
******************************************************************************/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Convert to date object then check is a validate date.
|
|
10
|
-
*/
|
|
11
|
-
export const transformIsDate = transform(
|
|
12
|
-
(arg) => new Date(arg as string),
|
|
13
|
-
(arg) => isDate(arg),
|
|
14
|
-
);
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import logger from 'jet-logger';
|
|
2
|
-
|
|
3
|
-
import EnvVars from './common/constants/env';
|
|
4
|
-
import server from './server';
|
|
5
|
-
|
|
6
|
-
/******************************************************************************
|
|
7
|
-
Constants
|
|
8
|
-
******************************************************************************/
|
|
9
|
-
|
|
10
|
-
const SERVER_START_MESSAGE =
|
|
11
|
-
'Express server started on port: ' + EnvVars.Port.toString();
|
|
12
|
-
|
|
13
|
-
/******************************************************************************
|
|
14
|
-
Run
|
|
15
|
-
******************************************************************************/
|
|
16
|
-
|
|
17
|
-
// Start the server
|
|
18
|
-
server.listen(EnvVars.Port, (err) => {
|
|
19
|
-
if (!!err) {
|
|
20
|
-
logger.err(err.message);
|
|
21
|
-
} else {
|
|
22
|
-
logger.info(SERVER_START_MESSAGE);
|
|
23
|
-
}
|
|
24
|
-
});
|