express-generator-typescript 2.8.0 → 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 -153
- 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/template/package.json +68 -0
- 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/package.json +0 -70
- 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
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import { ValueOf } from '../types/utility-types';
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { ValueOf } from "../types/structure-utils";
|
|
3
|
+
// ========================================================================= //
|
|
4
|
+
// CONSTANTS //
|
|
5
|
+
// ========================================================================= //
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Hypertext Transfer Protocol (HTTP) response status codes.
|
|
@@ -386,9 +385,9 @@ const HttpStatusCodes = {
|
|
|
386
385
|
NETWORK_AUTHENTICATION_REQUIRED: 511,
|
|
387
386
|
} as const;
|
|
388
387
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
388
|
+
// ========================================================================= //
|
|
389
|
+
// EXPORT //
|
|
390
|
+
// ========================================================================= //
|
|
392
391
|
|
|
393
392
|
type HttpStatusCodes = ValueOf<typeof HttpStatusCodes>;
|
|
394
393
|
export default HttpStatusCodes;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import jetPaths from 'jet-paths';
|
|
2
|
+
|
|
3
|
+
// ========================================================================= //
|
|
4
|
+
// CONSTANTS //
|
|
5
|
+
// ========================================================================= //
|
|
6
|
+
|
|
7
|
+
const Paths = jetPaths({
|
|
8
|
+
_: '/api',
|
|
9
|
+
Users: {
|
|
10
|
+
_: '/users',
|
|
11
|
+
Get: '/all',
|
|
12
|
+
Add: '/add',
|
|
13
|
+
Update: '/update',
|
|
14
|
+
Delete: '/delete',
|
|
15
|
+
},
|
|
16
|
+
} as const);
|
|
17
|
+
|
|
18
|
+
// ========================================================================= //
|
|
19
|
+
// EXPORT //
|
|
20
|
+
// ========================================================================= //
|
|
21
|
+
|
|
22
|
+
export default Paths;
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
// EXEC //
|
|
17
|
+
// ========================================================================= //
|
|
18
|
+
|
|
19
|
+
const EnvVars = jetEnv({
|
|
20
|
+
NodeEnv: (v) => tspo.isValue(NodeEnvs, v),
|
|
21
|
+
Port: num,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// ========================================================================= //
|
|
25
|
+
// EXPORT //
|
|
26
|
+
// ========================================================================= //
|
|
27
|
+
|
|
28
|
+
export default EnvVars;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// ========================================================================= //
|
|
2
|
+
// TYPES //
|
|
3
|
+
// ========================================================================= //
|
|
4
|
+
|
|
5
|
+
export type ISOString =
|
|
6
|
+
`${number}-${number}-${number}T${number}:${number}:${number}${string}`;
|
|
7
|
+
|
|
8
|
+
// ========================================================================= //
|
|
9
|
+
// FUNCTIONS //
|
|
10
|
+
// ========================================================================= //
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Return the current-date (or a provided date) as an ISOString.
|
|
14
|
+
*/
|
|
15
|
+
export function getISOString(date = new Date()): ISOString {
|
|
16
|
+
return date.toISOString() as ISOString;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Validate an ISOString.
|
|
21
|
+
*/
|
|
22
|
+
export function isISOString(value: unknown): value is ISOString {
|
|
23
|
+
try {
|
|
24
|
+
const date = new Date(value as string);
|
|
25
|
+
return !isNaN(date.getTime()) && date.toISOString() === value;
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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. `errors` (optional) is sent to the
|
|
11
|
+
* client alongside the message.
|
|
12
|
+
*/
|
|
13
|
+
export class RouteError extends Error {
|
|
14
|
+
public status: HttpStatusCodes;
|
|
15
|
+
public errors?: unknown[];
|
|
16
|
+
|
|
17
|
+
public constructor(
|
|
18
|
+
status: HttpStatusCodes,
|
|
19
|
+
message: string,
|
|
20
|
+
errors?: unknown[],
|
|
21
|
+
) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.status = status;
|
|
24
|
+
this.errors = errors;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Request data failed schema validation.
|
|
30
|
+
*/
|
|
31
|
+
export class ValidationError extends RouteError {
|
|
32
|
+
public static MESSAGE = 'Request validation failed.';
|
|
33
|
+
|
|
34
|
+
public constructor(errors: ParseError[]) {
|
|
35
|
+
super(HttpStatusCodes.BAD_REQUEST, ValidationError.MESSAGE, errors);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
// EXEC //
|
|
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
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import jetid from 'jet-id';
|
|
2
|
+
import { isNonEmptyString, isString } from 'jet-validators';
|
|
3
|
+
import { parseObject, Schema, testObject } from 'jet-validators/utils';
|
|
4
|
+
|
|
5
|
+
import { getISOString, isISOString } from '@src/common/utils/date-utils';
|
|
6
|
+
|
|
7
|
+
import { Entity } from './common/types';
|
|
8
|
+
|
|
9
|
+
// ========================================================================= //
|
|
10
|
+
// CONSTANTS //
|
|
11
|
+
// ========================================================================= //
|
|
12
|
+
|
|
13
|
+
const GetDefaults = (): IUser => ({
|
|
14
|
+
id: jetid(),
|
|
15
|
+
name: '',
|
|
16
|
+
email: '',
|
|
17
|
+
created: getISOString(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const schema: Schema<IUser> = {
|
|
21
|
+
id: isUserId,
|
|
22
|
+
name: isString,
|
|
23
|
+
email: isString,
|
|
24
|
+
created: isISOString,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// ========================================================================= //
|
|
28
|
+
// TYPES //
|
|
29
|
+
// ========================================================================= //
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @entity users
|
|
33
|
+
*/
|
|
34
|
+
export interface IUser extends Entity {
|
|
35
|
+
name: string;
|
|
36
|
+
email: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Fields a client supplies when creating a user; the server sets the rest.
|
|
41
|
+
*/
|
|
42
|
+
export type IUserInput = Pick<IUser, 'name' | 'email'>;
|
|
43
|
+
|
|
44
|
+
// ========================================================================= //
|
|
45
|
+
// FUNCTIONS //
|
|
46
|
+
// ========================================================================= //
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validate the `User` schema.
|
|
50
|
+
*/
|
|
51
|
+
const parseUser = parseObject<IUser>(schema);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* For the APIs make sure the right fields are complete
|
|
55
|
+
*/
|
|
56
|
+
const isCompleteUser = testObject<IUser>({
|
|
57
|
+
...schema,
|
|
58
|
+
name: isNonEmptyString,
|
|
59
|
+
email: isNonEmptyString,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Validate the fields a client sends to create a user.
|
|
64
|
+
*/
|
|
65
|
+
const isUserInput = testObject<IUserInput>({
|
|
66
|
+
name: isNonEmptyString,
|
|
67
|
+
email: isNonEmptyString,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Test if an id is a valid user id.
|
|
72
|
+
*/
|
|
73
|
+
function isUserId(val: unknown): val is string {
|
|
74
|
+
return jetid.test(val);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* New user object.
|
|
79
|
+
*/
|
|
80
|
+
function new_(user?: Partial<IUser>): IUser {
|
|
81
|
+
return parseUser({ ...GetDefaults(), ...user }, (errors) => {
|
|
82
|
+
throw new Error('Setup new user failed ' + JSON.stringify(errors, null, 2));
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ========================================================================= //
|
|
87
|
+
// EXPORT //
|
|
88
|
+
// ========================================================================= //
|
|
89
|
+
|
|
90
|
+
export default {
|
|
91
|
+
new: new_,
|
|
92
|
+
isId: isUserId,
|
|
93
|
+
isComplete: isCompleteUser,
|
|
94
|
+
isInput: isUserInput,
|
|
95
|
+
} as const;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ISOString } from "@src/common/utils/date-utils";
|
|
2
|
+
|
|
3
|
+
// ========================================================================= //
|
|
4
|
+
// TYPES //
|
|
5
|
+
// ========================================================================= //
|
|
6
|
+
|
|
7
|
+
export interface Entity {
|
|
8
|
+
id: string; // @PK
|
|
9
|
+
created: ISOString; // @audit
|
|
10
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var Http = (() => {
|
|
2
|
+
// Setup request for json
|
|
3
|
+
var getOptions = (verb, data) => {
|
|
4
|
+
var options = {
|
|
5
|
+
dataType: 'json',
|
|
6
|
+
method: verb,
|
|
7
|
+
headers: {
|
|
8
|
+
Accept: 'application/json',
|
|
9
|
+
'Content-Type': 'application/json',
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
if (!!data) {
|
|
13
|
+
options.body = JSON.stringify(data);
|
|
14
|
+
}
|
|
15
|
+
return options;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Set Http methods
|
|
19
|
+
return {
|
|
20
|
+
get: (path) => fetch(path, getOptions('GET')),
|
|
21
|
+
post: (path, data) => fetch(path, getOptions('POST', data)),
|
|
22
|
+
put: (path, data) => fetch(path, getOptions('PUT', data)),
|
|
23
|
+
delete: (path) => fetch(path, getOptions('DELETE')),
|
|
24
|
+
};
|
|
25
|
+
})();
|