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
package/README.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img alt="express-generator-typescript" src="https://github.com/seanpmaxwell/express-generator-typescript/raw/
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<p align="center">
|
|
6
|
-
<a href="https://www.npmjs.com/package/express-generator-typescript"><img src="https://img.shields.io/npm/v/express-generator-typescript.svg?style=for-the-badge&logo=npm" alt="NPM Version"></a>
|
|
7
|
-
<a href="https://www.npmjs.com/package/express-generator-typescript"><img src="https://img.shields.io/npm/dm/express-generator-typescript.svg?style=for-the-badge" alt="NPM Downloads"></a>
|
|
8
|
-
<a href="https://www.npmjs.com/package/express-generator-typescript"><img src="https://img.shields.io/npm/l/express-generator-typescript.svg?style=for-the-badge" alt="License"></a>
|
|
2
|
+
<img alt="express-generator-typescript" src="https://github.com/seanpmaxwell/express-generator-typescript/raw/main/assets/express-typescript.png" width="420">
|
|
9
3
|
</p>
|
|
10
4
|
|
|
11
5
|
# express-generator-typescript
|
|
12
6
|
|
|
7
|
+
[](https://www.npmjs.com/package/express-generator-typescript)
|
|
8
|
+
[](https://www.npmjs.com/package/express-generator-typescript)
|
|
9
|
+
[](https://github.com/seanpmaxwell/express-generator-typescript/blob/main/LICENSE)
|
|
10
|
+
|
|
13
11
|
Command line tool which generates production-ready express templates with TypeScript baked in. Spin up a web server in seconds that follows the [TypeScript best practices](https://github.com/seanpmaxwell/Typescript-Best-Practices/blob/main/README.md).
|
|
12
|
+
<br/>
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
## Documenation
|
package/bin/cli.js
CHANGED
|
@@ -1,33 +1,92 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { parseArgs } = require('util');
|
|
4
|
+
|
|
5
|
+
const expressGenTs = require('../lib/express-generator-typescript');
|
|
6
|
+
const { version, engines } = require('../package.json');
|
|
7
|
+
|
|
8
|
+
// ========================================================================= //
|
|
9
|
+
// CONSTANTS //
|
|
10
|
+
// ========================================================================= //
|
|
11
|
+
|
|
12
|
+
const DEFAULT_DEST = 'express-gen-ts';
|
|
13
|
+
const MIN_NODE = engines.node.replace(/^>=/, '');
|
|
14
|
+
|
|
15
|
+
const HELP = `Usage: express-generator-typescript [project-name] [options]
|
|
16
|
+
|
|
17
|
+
Creates a new Express + TypeScript project (default name: "${DEFAULT_DEST}").
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
--use-yarn Install dependencies with yarn instead of npm
|
|
21
|
+
--force Write into the target folder even if it is not empty
|
|
22
|
+
-h, --help Show this help
|
|
23
|
+
-v, --version Show the version`;
|
|
24
|
+
|
|
25
|
+
// ========================================================================= //
|
|
26
|
+
// EXEC //
|
|
27
|
+
// ========================================================================= //
|
|
28
|
+
|
|
29
|
+
main().catch((err) => {
|
|
30
|
+
console.error('\nProject setup failed: ' + err.message);
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// ========================================================================= //
|
|
35
|
+
// FUNCTIONS //
|
|
36
|
+
// ========================================================================= //
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Parse the command-line args and hand off to `expressGenTs`.
|
|
40
|
+
*
|
|
41
|
+
* @returns {Promise<void>}
|
|
42
|
+
*/
|
|
43
|
+
async function main() {
|
|
44
|
+
// ---- Parse command-line-arguments
|
|
45
|
+
const { values, positionals } = parseArgs({
|
|
46
|
+
allowPositionals: true,
|
|
47
|
+
options: {
|
|
48
|
+
'use-yarn': { type: 'boolean', default: false },
|
|
49
|
+
force: { type: 'boolean', default: false },
|
|
50
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
51
|
+
version: { type: 'boolean', short: 'v', default: false },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
if (values.help) {
|
|
55
|
+
console.log(HELP);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (values.version) {
|
|
59
|
+
console.log(version);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (positionals.length > 1) {
|
|
63
|
+
throw new Error('Expected at most one project name.\n\n' + HELP);
|
|
64
|
+
}
|
|
65
|
+
assertNodeVersion();
|
|
66
|
+
|
|
67
|
+
// ---- Run "express-generator-typescript"
|
|
68
|
+
const dest = path.resolve(process.cwd(), positionals[0] ?? DEFAULT_DEST);
|
|
69
|
+
console.log('Setting up new Express/TypeScript project in ' + dest);
|
|
70
|
+
await expressGenTs(dest, {
|
|
71
|
+
useYarn: values['use-yarn'],
|
|
72
|
+
force: values.force,
|
|
73
|
+
});
|
|
74
|
+
console.log('Project setup complete!');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The generated project's tooling (vitest, eslint) requires a recent Node, so
|
|
79
|
+
* fail fast instead of producing a project that can't run.
|
|
80
|
+
*
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
function assertNodeVersion() {
|
|
84
|
+
const toParts = (v) => v.split('.').map(Number);
|
|
85
|
+
const [maj, min] = toParts(process.versions.node);
|
|
86
|
+
const [reqMaj, reqMin] = toParts(MIN_NODE);
|
|
87
|
+
if (maj < reqMaj || (maj === reqMaj && min < reqMin)) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Node ${MIN_NODE} or newer is required (found ${process.versions.node}).`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -1,153 +1,125 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
*
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
*
|
|
90
|
-
*/
|
|
91
|
-
function
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
*
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* Download the dependencies.
|
|
127
|
-
*/
|
|
128
|
-
function downloadNodeModules(destination, useYarn) {
|
|
129
|
-
const options = { cwd: destination };
|
|
130
|
-
// Setup dependencies string
|
|
131
|
-
let depStr = DEPENDENCIES.join(' '),
|
|
132
|
-
devDepStr = DEV_DEPENDENCIES.join(' ');
|
|
133
|
-
// Setup download command
|
|
134
|
-
let downloadLibCmd,
|
|
135
|
-
downloadDepCmd;
|
|
136
|
-
if (useYarn) {
|
|
137
|
-
downloadLibCmd = 'yarn add ' + depStr;
|
|
138
|
-
downloadDepCmd = 'yarn add ' + devDepStr + ' -D';
|
|
139
|
-
} else {
|
|
140
|
-
downloadLibCmd = 'npm i -s ' + depStr;
|
|
141
|
-
downloadDepCmd = 'npm i -D ' + devDepStr;
|
|
142
|
-
}
|
|
143
|
-
// Execute command
|
|
144
|
-
childProcess.execSync(downloadLibCmd, options);
|
|
145
|
-
childProcess.execSync(downloadDepCmd, options);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/******************************************************************************
|
|
150
|
-
Export
|
|
151
|
-
******************************************************************************/
|
|
152
|
-
|
|
153
|
-
module.exports = expressGenTs;
|
|
1
|
+
const childProcess = require('child_process');
|
|
2
|
+
const fs = require('fs/promises');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// ========================================================================= //
|
|
6
|
+
// CONSTANTS //
|
|
7
|
+
// ========================================================================= //
|
|
8
|
+
|
|
9
|
+
const TEMPLATE_DIR = path.join(__dirname, 'template');
|
|
10
|
+
|
|
11
|
+
// Local build/editor artifacts that only exist when running from a checkout.
|
|
12
|
+
const EXCLUDED_NAMES = new Set([
|
|
13
|
+
'node_modules',
|
|
14
|
+
'package-lock.json',
|
|
15
|
+
'dist',
|
|
16
|
+
'tsconfig.tsbuildinfo',
|
|
17
|
+
'.vscode',
|
|
18
|
+
'database.test.json',
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
// ========================================================================= //
|
|
22
|
+
// FUNCTIONS //
|
|
23
|
+
// ========================================================================= //
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Entry point: scaffold a new project at `dest` and install its dependencies.
|
|
27
|
+
* Rejects on any failure so callers can report it and exit non-zero.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} dest - Absolute path to create the project in.
|
|
30
|
+
* @param {object} [options]
|
|
31
|
+
* @param {boolean} [options.useYarn] - Install with yarn instead of npm.
|
|
32
|
+
* @param {boolean} [options.force] - Allow writing into a non-empty folder.
|
|
33
|
+
* @param {boolean} [options.skipInstall] - Don't install dependencies.
|
|
34
|
+
* @returns {Promise<void>}
|
|
35
|
+
*/
|
|
36
|
+
async function expressGenTs(dest, options = {}) {
|
|
37
|
+
const { useYarn = false, force = false, skipInstall = false } = options;
|
|
38
|
+
if (!force) {
|
|
39
|
+
await assertEmptyOrMissing(dest);
|
|
40
|
+
}
|
|
41
|
+
await copyProjectFiles(dest);
|
|
42
|
+
await setPackageName(dest);
|
|
43
|
+
await renameGitignoreFile(dest);
|
|
44
|
+
if (!skipInstall) {
|
|
45
|
+
installDependencies(dest, useYarn);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Throw if `dest` exists and has any contents, so existing work is never
|
|
51
|
+
* overwritten.
|
|
52
|
+
*
|
|
53
|
+
* @param {string} dest
|
|
54
|
+
* @returns {Promise<void>}
|
|
55
|
+
*/
|
|
56
|
+
async function assertEmptyOrMissing(dest) {
|
|
57
|
+
let entries;
|
|
58
|
+
try {
|
|
59
|
+
entries = await fs.readdir(dest);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (err.code === 'ENOENT') return;
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
if (entries.length > 0) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`"${dest}" already exists and is not empty. Choose another name or ` +
|
|
67
|
+
'pass --force to write into it anyway.',
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Copy the `template` folder into `dest`.
|
|
74
|
+
*
|
|
75
|
+
* @param {string} dest
|
|
76
|
+
* @returns {Promise<void>}
|
|
77
|
+
*/
|
|
78
|
+
function copyProjectFiles(dest) {
|
|
79
|
+
return fs.cp(TEMPLATE_DIR, dest, {
|
|
80
|
+
recursive: true,
|
|
81
|
+
filter: (src) => !EXCLUDED_NAMES.has(path.basename(src)),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Name the new project after its folder.
|
|
87
|
+
*
|
|
88
|
+
* @param {string} dest
|
|
89
|
+
* @returns {Promise<void>}
|
|
90
|
+
*/
|
|
91
|
+
async function setPackageName(dest) {
|
|
92
|
+
const pkgPath = path.join(dest, 'package.json');
|
|
93
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'));
|
|
94
|
+
pkg.name = path.basename(dest);
|
|
95
|
+
await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Rename the template's `gitignore` to `.gitignore`, because npm does not
|
|
100
|
+
* allow a `.gitignore` file to be published.
|
|
101
|
+
*
|
|
102
|
+
* @param {string} dest
|
|
103
|
+
* @returns {Promise<void>}
|
|
104
|
+
*/
|
|
105
|
+
function renameGitignoreFile(dest) {
|
|
106
|
+
return fs.rename(path.join(dest, 'gitignore'), path.join(dest, '.gitignore'));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Install the versions pinned in the template's package.json.
|
|
111
|
+
*
|
|
112
|
+
* @param {string} dest
|
|
113
|
+
* @param {boolean} useYarn
|
|
114
|
+
* @returns {void}
|
|
115
|
+
*/
|
|
116
|
+
function installDependencies(dest, useYarn) {
|
|
117
|
+
const cmd = useYarn ? 'yarn install' : 'npm install';
|
|
118
|
+
childProcess.execSync(cmd, { cwd: dest, stdio: 'inherit' });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ========================================================================= //
|
|
122
|
+
// EXPORT //
|
|
123
|
+
// ========================================================================= //
|
|
124
|
+
|
|
125
|
+
module.exports = expressGenTs;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
## About
|
|
2
|
+
|
|
3
|
+
This project was created with [express-generator-typescript](https://github.com/seanpmaxwell/express-generator-typescript). It requires Node.js 22.12 or newer.
|
|
4
|
+
|
|
5
|
+
<p align="center">· · ·</p>
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Available Scripts
|
|
9
|
+
|
|
10
|
+
### `npm run install:clean`
|
|
11
|
+
|
|
12
|
+
Remove the existing `node_modules/` folder, `package-lock.json`, and reinstall all library modules.
|
|
13
|
+
|
|
14
|
+
### `npm run dev`
|
|
15
|
+
|
|
16
|
+
Run the server in development with hot reloading and browser refresh (see `package.json` for all `npm run dev` variations)<br/>
|
|
17
|
+
|
|
18
|
+
**IMPORTANT** development mode uses `swc` for performance reasons which DOES NOT check for typescript errors. Run `npm run typecheck` to check for type errors. NOTE: you should use your IDE to prevent most type errors.
|
|
19
|
+
|
|
20
|
+
### `npm test`
|
|
21
|
+
|
|
22
|
+
Run unit-tests with <a href="https://vitest.dev/guide/">vitest</a>.
|
|
23
|
+
|
|
24
|
+
### `npm run lint`
|
|
25
|
+
|
|
26
|
+
Check for linting errors.
|
|
27
|
+
|
|
28
|
+
### `npm run format`
|
|
29
|
+
|
|
30
|
+
Format `src/` and `tests/` with prettier.
|
|
31
|
+
|
|
32
|
+
### `npm run build`
|
|
33
|
+
|
|
34
|
+
Build the project for production.
|
|
35
|
+
|
|
36
|
+
### `npm start`
|
|
37
|
+
|
|
38
|
+
Run the production build (Must be built first).
|
|
39
|
+
|
|
40
|
+
### `npm run typecheck`
|
|
41
|
+
|
|
42
|
+
Check for typescript errors.
|
|
43
|
+
|
|
44
|
+
<p align="center">· · ·</p>
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Additional Notes
|
|
48
|
+
|
|
49
|
+
- `config/.env.production` is listed in `.gitignore` so production secrets don't get committed. Keep it out of version control and provide its values through your deployment tooling.
|
|
50
|
+
- The database is a JSON file (`src/repos/common/database.json`, or `dist/repos/common/database.json` in production) meant only for the demo. It's created automatically if missing and isn't safe for concurrent writes, so replace `src/repos/MockOrm.ts` with a real database before going to production.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
proxy: "http://localhost:3000/", // The address where your Express app runs
|
|
3
|
+
open: true, // Avoid reopening the browser on every nodemon restart
|
|
4
|
+
port: 3001, // The port BrowserSync will run on
|
|
5
|
+
files: ["src/**/*.*"], // Files to watch
|
|
6
|
+
ignore: ['**/node_modules/**', '**/repos/**/*.json'],
|
|
7
|
+
reloadDelay: 500, // Wait for nodemon to restart
|
|
8
|
+
};
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# ---- Environment
|
|
2
2
|
NODE_ENV=development
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# ---- Server
|
|
6
6
|
PORT=3000
|
|
7
|
-
HOST=localhost
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
# ---- Setup jet-logger
|
|
11
10
|
JET_LOGGER_MODE=console
|
|
12
11
|
JET_LOGGER_FILEPATH=jet-logger.log
|
|
13
|
-
|
|
12
|
+
JET_LOGGER_SHOW_TIME=true
|
|
14
13
|
JET_LOGGER_FORMAT=line
|
|
15
|
-
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# ---- Environment
|
|
2
2
|
NODE_ENV=production
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# ---- Server
|
|
6
6
|
PORT=8081
|
|
7
|
-
HOST=localhost
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
# ---- Setup jet-logger
|
|
11
10
|
JET_LOGGER_MODE=file
|
|
12
11
|
JET_LOGGER_FILEPATH=jet-logger.log
|
|
13
|
-
|
|
12
|
+
JET_LOGGER_SHOW_TIME=true
|
|
14
13
|
JET_LOGGER_FORMAT=line
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# ---- Environment
|
|
2
2
|
NODE_ENV=test
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# ---- Server
|
|
6
6
|
PORT=4000
|
|
7
|
-
HOST=localhost
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
# ---- Setup `jet-logger`
|
|
11
10
|
JET_LOGGER_MODE=console
|
|
12
11
|
JET_LOGGER_FILEPATH=jet-logger.log
|
|
13
|
-
|
|
12
|
+
JET_LOGGER_SHOW_TIME=true
|
|
14
13
|
JET_LOGGER_FORMAT=line
|
|
@@ -4,6 +4,10 @@ import n from 'eslint-plugin-n';
|
|
|
4
4
|
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
5
5
|
import tseslint from 'typescript-eslint';
|
|
6
6
|
|
|
7
|
+
// ========================================================================= //
|
|
8
|
+
// EXPORT //
|
|
9
|
+
// ========================================================================= //
|
|
10
|
+
|
|
7
11
|
export default defineConfig([
|
|
8
12
|
// global ignores
|
|
9
13
|
globalIgnores(['**/dist/**', '**/public/**/lib/**']),
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "express-typescript-example",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"build": "shx rm -rf dist && npm run lint && tsc --project tsconfig.prod.json && npm run build:copy-static",
|
|
6
|
+
"build:copy-static": "shx mkdir -p dist/public dist/views && shx cp -r src/public/* dist/public && shx cp -r src/views/* dist/views",
|
|
7
|
+
"install:clean": "shx rm -rf ./node_modules package-lock.json && npm i",
|
|
8
|
+
"dev:basic": "cross-env DOTENV_CONFIG_PATH=./config/.env.development ts-node ./src/main",
|
|
9
|
+
"dev:watch": "nodemon --exec \"npm run dev:basic\" --watch ./src --ext .ts",
|
|
10
|
+
"dev": "concurrently \"npm run dev:watch\" \"npm run sync\"",
|
|
11
|
+
"lint": "eslint .",
|
|
12
|
+
"format": "prettier --write .",
|
|
13
|
+
"start": "cross-env DOTENV_CONFIG_PATH=./config/.env.production node -r dotenv/config -r module-alias/register ./dist/main.js",
|
|
14
|
+
"sync": "delay 1s && browser-sync start --config bs-config.js",
|
|
15
|
+
"test": "cross-env NODE_ENV=test vitest",
|
|
16
|
+
"typecheck": "tsc -b --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22.12.0"
|
|
20
|
+
},
|
|
21
|
+
"_moduleAliases": {
|
|
22
|
+
"@src": "dist"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"cross-env": "^10.1.0",
|
|
26
|
+
"dotenv": "^18.0.4",
|
|
27
|
+
"express": "^5.2.1",
|
|
28
|
+
"helmet": "^8.3.0",
|
|
29
|
+
"jet-env": "^1.1.6",
|
|
30
|
+
"jet-id": "^1.3.1",
|
|
31
|
+
"jet-logger": "3.0.0",
|
|
32
|
+
"jet-paths": "^4.0.1",
|
|
33
|
+
"jet-validators": "^2.3.1",
|
|
34
|
+
"jsonfile": "^6.2.1",
|
|
35
|
+
"module-alias": "^2.3.4",
|
|
36
|
+
"morgan": "^1.12.1",
|
|
37
|
+
"tspo": "^1.0.7"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@eslint/js": "^10.0.1",
|
|
41
|
+
"@swc/core": "^1.16.2",
|
|
42
|
+
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
43
|
+
"@types/express": "^5.0.6",
|
|
44
|
+
"@types/jsonfile": "^6.1.4",
|
|
45
|
+
"@types/morgan": "^1.9.10",
|
|
46
|
+
"@types/node": "^26.6.2",
|
|
47
|
+
"@types/supertest": "^7.2.1",
|
|
48
|
+
"browser-sync": "^3.0.4",
|
|
49
|
+
"concurrently": "^10.0.5",
|
|
50
|
+
"delay-cli": "^3.0.0",
|
|
51
|
+
"eslint": "^10.11.0",
|
|
52
|
+
"eslint-config-prettier": "^10.1.8",
|
|
53
|
+
"eslint-plugin-n": "^18.3.0",
|
|
54
|
+
"jiti": "^2.7.0",
|
|
55
|
+
"nodemon": "^3.1.14",
|
|
56
|
+
"prettier": "^3.9.9",
|
|
57
|
+
"shx": "^0.4.0",
|
|
58
|
+
"supertest": "^7.3.0",
|
|
59
|
+
"ts-node": "^10.9.2",
|
|
60
|
+
"tsconfig-paths": "^4.2.0",
|
|
61
|
+
"typescript": "^6.0.3",
|
|
62
|
+
"typescript-eslint": "^8.70.1",
|
|
63
|
+
"vitest": "^5.0.2"
|
|
64
|
+
},
|
|
65
|
+
"allowScripts": {
|
|
66
|
+
"@swc/core@1.16.2": true
|
|
67
|
+
}
|
|
68
|
+
}
|