express-generator-typescript 2.4.19 → 2.4.23
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/express-generator-typescript.js +8 -16
- package/lib/project-files/README.md +1 -1
- package/lib/project-files/eslint.config.js +55 -0
- package/lib/project-files/package.json +13 -16
- package/lib/project-files/preload.js +3 -0
- package/lib/project-files/scripts/build.ts +4 -7
- package/lib/project-files/spec/index.ts +3 -13
- package/lib/project-files/spec/types/misc.ts +5 -11
- package/lib/project-files/src/common/EnvVars.ts +1 -5
- package/lib/project-files/src/repos/database.json +1 -1
- package/lib/project-files/src/routes/UserRoutes.ts +4 -4
- package/lib/project-files/src/routes/common/check.ts +7 -7
- package/lib/project-files/src/routes/common/types.ts +0 -8
- package/lib/project-files/src/server.ts +3 -12
- package/lib/project-files/tsconfig.json +4 -2
- package/lib/project-files-auth/README.md +1 -1
- package/lib/project-files-auth/eslint.config.js +55 -0
- package/lib/project-files-auth/package.json +13 -12
- package/lib/project-files-auth/preload.js +3 -0
- package/lib/project-files-auth/scripts/build.ts +4 -7
- package/lib/project-files-auth/spec/index.ts +3 -13
- package/lib/project-files-auth/spec/types/misc.ts +5 -11
- package/lib/project-files-auth/src/common/EnvVars.ts +1 -5
- package/lib/project-files-auth/src/routes/AuthRoutes.ts +2 -2
- package/lib/project-files-auth/src/routes/UserRoutes.ts +4 -4
- package/lib/project-files-auth/src/routes/common/check.ts +7 -7
- package/lib/project-files-auth/src/server.ts +3 -8
- package/lib/project-files-auth/tsconfig.json +4 -2
- package/package.json +1 -1
- package/lib/project-files/.eslintignore +0 -2
- package/lib/project-files/.eslintrc.json +0 -44
- package/lib/project-files-auth/.eslintignore +0 -2
- package/lib/project-files-auth/.eslintrc.json +0 -44
package/bin/cli.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create new express-generator-typescript project.
|
|
3
|
-
*
|
|
4
|
-
* created by Sean Maxwell, 5/31/2019
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
const path = require('path'),
|
|
8
2
|
editJsonFile = require('edit-json-file'),
|
|
9
3
|
childProcess = require('child_process'),
|
|
@@ -14,20 +8,19 @@ const path = require('path'),
|
|
|
14
8
|
// **** Variables **** //
|
|
15
9
|
|
|
16
10
|
// Project folder paths
|
|
17
|
-
const PROJECT_FOLDER_PATH = './project-files'
|
|
11
|
+
const PROJECT_FOLDER_PATH = './project-files',
|
|
18
12
|
PROJECT_FOLDER_PATH_AUTH = './project-files-auth';
|
|
19
13
|
|
|
20
14
|
// Project-folder dependencies
|
|
21
15
|
const DEPENDENCIES = 'express dotenv morgan cookie-parser jet-logger ' +
|
|
22
16
|
'module-alias express-async-errors helmet jsonfile inserturlparams ' +
|
|
23
|
-
'jet-paths moment',
|
|
17
|
+
'jet-paths moment ',
|
|
24
18
|
DEPENDENCIES_AUTH = ' bcrypt jsonwebtoken',
|
|
25
19
|
DEV_DEPENDENCIES = 'ts-node typescript nodemon find jasmine supertest ' +
|
|
26
20
|
'@types/node @types/express @types/jasmine @types/find @types/morgan ' +
|
|
27
21
|
'@types/cookie-parser @types/supertest fs-extra tsconfig-paths ' +
|
|
28
|
-
'@types/jsonfile @
|
|
29
|
-
'@
|
|
30
|
-
'ts-command-line-args',
|
|
22
|
+
'@types/jsonfile @types/fs-extra ' +
|
|
23
|
+
'eslint @eslint/js @types/eslint__js typescript-eslint eslint-plugin-n @stylistic/eslint-plugin-ts',
|
|
31
24
|
DEV_DEPENDENCIES_AUTH = ' @types/bcrypt @types/jsonwebtoken';
|
|
32
25
|
|
|
33
26
|
// "ncp" options
|
|
@@ -60,12 +53,11 @@ async function expressGenTs(destination, useYarn, withAuth) {
|
|
|
60
53
|
function copyProjectFiles(destination, withAuth) {
|
|
61
54
|
const folder = (withAuth ? PROJECT_FOLDER_PATH_AUTH : PROJECT_FOLDER_PATH),
|
|
62
55
|
source = path.join(__dirname, folder);
|
|
63
|
-
return new Promise((res, rej) => {
|
|
64
|
-
ncp.limit = 16;
|
|
56
|
+
return /** @type {Promise<void>} */(new Promise((res, rej) => {
|
|
65
57
|
return ncp(source, destination, ncpOpts, (err) => {
|
|
66
58
|
return (!!err ? rej(err) : res());
|
|
67
59
|
});
|
|
68
|
-
});
|
|
60
|
+
}));
|
|
69
61
|
}
|
|
70
62
|
|
|
71
63
|
/**
|
|
@@ -84,13 +76,13 @@ function updatePackageJson(destination) {
|
|
|
84
76
|
* Because npm does not allow .gitignore to be published.
|
|
85
77
|
*/
|
|
86
78
|
function renameGitigoreFile(destination) {
|
|
87
|
-
return new Promise((res, rej) =>
|
|
79
|
+
return /** @type {Promise<void>} */(new Promise((res, rej) =>
|
|
88
80
|
fs.rename(
|
|
89
81
|
(destination + '/gitignore'),
|
|
90
82
|
(destination + '/.gitignore'),
|
|
91
83
|
(err => !!err ? rej(err) : res()),
|
|
92
84
|
)
|
|
93
|
-
);
|
|
85
|
+
));
|
|
94
86
|
}
|
|
95
87
|
|
|
96
88
|
/**
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
const eslint = require('@eslint/js');
|
|
5
|
+
const tseslint = require('typescript-eslint');
|
|
6
|
+
const stylisticTs = require('@stylistic/eslint-plugin-ts');
|
|
7
|
+
const nodePlugin = require('eslint-plugin-n');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module.exports = tseslint.config(
|
|
11
|
+
eslint.configs.recommended,
|
|
12
|
+
nodePlugin.configs['flat/recommended-script'],
|
|
13
|
+
...tseslint.configs.strictTypeChecked,
|
|
14
|
+
...tseslint.configs.stylisticTypeChecked,
|
|
15
|
+
{
|
|
16
|
+
languageOptions: {
|
|
17
|
+
parserOptions: {
|
|
18
|
+
project: './tsconfig.json',
|
|
19
|
+
warnOnUnsupportedTypeScriptVersion: false,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
plugins: {
|
|
25
|
+
'@stylistic/ts': stylisticTs,
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
files: ['**/*.ts'],
|
|
30
|
+
ignores: ['**/*.js'],
|
|
31
|
+
rules: {
|
|
32
|
+
'@typescript-eslint/explicit-member-accessibility': 'warn',
|
|
33
|
+
'@typescript-eslint/no-misused-promises': 0,
|
|
34
|
+
'@typescript-eslint/no-floating-promises': 0,
|
|
35
|
+
'@typescript-eslint/no-confusing-void-expression': 0,
|
|
36
|
+
'@typescript-eslint/no-unnecessary-condition': 0,
|
|
37
|
+
'@typescript-eslint/restrict-template-expressions': [ 'error', { allowNumber: true }],
|
|
38
|
+
'max-len': [
|
|
39
|
+
'warn',
|
|
40
|
+
{
|
|
41
|
+
'code': 80
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
'@stylistic/ts/semi': ['warn'],
|
|
45
|
+
'comma-dangle': ['warn', 'always-multiline'],
|
|
46
|
+
'no-console': 1,
|
|
47
|
+
'no-extra-boolean-cast': 0,
|
|
48
|
+
'indent': ['warn', 2],
|
|
49
|
+
'quotes': ['warn', 'single'],
|
|
50
|
+
'n/no-process-env': 1,
|
|
51
|
+
'n/no-missing-import': 0,
|
|
52
|
+
'n/no-unpublished-import': 0
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
)
|
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
"name": "express-typescript-example",
|
|
3
3
|
"version": "0.0.0",
|
|
4
4
|
"scripts": {
|
|
5
|
-
"build": "ts-node ./scripts/build.ts",
|
|
6
|
-
"dev": "NODE_ENV=development ts-node ./src",
|
|
5
|
+
"build": "npx ts-node ./scripts/build.ts",
|
|
6
|
+
"dev": "NODE_ENV=development npx ts-node ./src",
|
|
7
7
|
"dev:hot": "nodemon --exec \"npm run dev\" --watch ./src -e ts",
|
|
8
|
-
"lint": "npx eslint
|
|
9
|
-
"lint:tests": "npx eslint
|
|
8
|
+
"lint": "npx eslint ./src/**/*.ts",
|
|
9
|
+
"lint:tests": "npx eslint ./spec/**/*.ts",
|
|
10
10
|
"start": "NODE_ENV=production node -r ./preload.js ./dist",
|
|
11
|
-
"test": "NODE_ENV=test ts-node ./spec",
|
|
11
|
+
"test": "NODE_ENV=test npx ts-node ./spec",
|
|
12
12
|
"test:hot": "nodemon --exec \"npm run test\" --watch ./src --watch ./spec -e ts"
|
|
13
13
|
},
|
|
14
14
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
15
|
+
"node": ">=16.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"bcrypt": "^5.0.1",
|
|
19
18
|
"cookie-parser": "^1.4.6",
|
|
20
19
|
"dotenv": "^16.0.2",
|
|
21
20
|
"express": "^4.18.1",
|
|
@@ -25,35 +24,33 @@
|
|
|
25
24
|
"jet-logger": "^1.3.1",
|
|
26
25
|
"jet-paths": "^1.0.5",
|
|
27
26
|
"jsonfile": "^6.1.0",
|
|
28
|
-
"jsonwebtoken": "^8.5.1",
|
|
29
27
|
"module-alias": "^2.2.2",
|
|
30
28
|
"moment": "^2.30.1",
|
|
31
29
|
"morgan": "^1.10.0"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
|
-
"@
|
|
32
|
+
"@eslint/js": "^9.11.1",
|
|
33
|
+
"@stylistic/eslint-plugin-ts": "^2.8.0",
|
|
35
34
|
"@types/cookie-parser": "^1.4.3",
|
|
35
|
+
"@types/eslint__js": "^8.42.3",
|
|
36
36
|
"@types/express": "^4.17.13",
|
|
37
37
|
"@types/find": "^0.2.1",
|
|
38
38
|
"@types/fs-extra": "^9.0.13",
|
|
39
39
|
"@types/jasmine": "^4.3.0",
|
|
40
40
|
"@types/jsonfile": "^6.1.0",
|
|
41
|
-
"@types/jsonwebtoken": "^8.5.9",
|
|
42
41
|
"@types/morgan": "^1.9.3",
|
|
43
42
|
"@types/node": "^18.7.14",
|
|
44
43
|
"@types/supertest": "^6.0.2",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"eslint": "^8.23.0",
|
|
48
|
-
"eslint-plugin-node": "^11.1.0",
|
|
44
|
+
"eslint": "^9.11.1",
|
|
45
|
+
"eslint-plugin-n": "^17.10.3",
|
|
49
46
|
"find": "^0.3.0",
|
|
50
47
|
"fs-extra": "^10.1.0",
|
|
51
48
|
"jasmine": "^4.3.0",
|
|
52
49
|
"nodemon": "^2.0.19",
|
|
53
50
|
"supertest": "^6.3.4",
|
|
54
|
-
"ts-command-line-args": "^2.4.2",
|
|
55
51
|
"ts-node": "^10.9.1",
|
|
56
52
|
"tsconfig-paths": "^4.1.0",
|
|
57
|
-
"typescript": "^
|
|
53
|
+
"typescript": "^5.6.2",
|
|
54
|
+
"typescript-eslint": "^8.8.0"
|
|
58
55
|
}
|
|
59
56
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
1
3
|
const dotenv = require('dotenv');
|
|
2
4
|
const path = require('path');
|
|
3
5
|
const moduleAlias = require('module-alias');
|
|
@@ -18,3 +20,4 @@ if (result2.error) {
|
|
|
18
20
|
if (NODE_ENV === 'production') {
|
|
19
21
|
moduleAlias.addAlias('@src', __dirname + '/dist');
|
|
20
22
|
}
|
|
23
|
+
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Remove old files, copy front-end ones.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
import fs from 'fs-extra';
|
|
6
2
|
import logger from 'jet-logger';
|
|
7
3
|
import childProcess from 'child_process';
|
|
@@ -14,13 +10,14 @@ import childProcess from 'child_process';
|
|
|
14
10
|
try {
|
|
15
11
|
// Remove current build
|
|
16
12
|
await remove('./dist/');
|
|
17
|
-
await exec('
|
|
13
|
+
await exec('npm run lint', './');
|
|
18
14
|
await exec('tsc --build tsconfig.prod.json', './');
|
|
19
15
|
// Copy
|
|
20
16
|
await copy('./src/public', './dist/public');
|
|
21
17
|
await copy('./src/views', './dist/views');
|
|
22
18
|
} catch (err) {
|
|
23
19
|
logger.err(err);
|
|
20
|
+
// eslint-disable-next-line n/no-process-exit
|
|
24
21
|
process.exit(1);
|
|
25
22
|
}
|
|
26
23
|
})();
|
|
@@ -30,7 +27,7 @@ import childProcess from 'child_process';
|
|
|
30
27
|
*/
|
|
31
28
|
function remove(loc: string): Promise<void> {
|
|
32
29
|
return new Promise((res, rej) => {
|
|
33
|
-
return fs.remove(loc,
|
|
30
|
+
return fs.remove(loc, err => {
|
|
34
31
|
return (!!err ? rej(err) : res());
|
|
35
32
|
});
|
|
36
33
|
});
|
|
@@ -41,7 +38,7 @@ function remove(loc: string): Promise<void> {
|
|
|
41
38
|
*/
|
|
42
39
|
function copy(src: string, dest: string): Promise<void> {
|
|
43
40
|
return new Promise((res, rej) => {
|
|
44
|
-
return fs.copy(src, dest,
|
|
41
|
+
return fs.copy(src, dest, err => {
|
|
45
42
|
return (!!err ? rej(err) : res());
|
|
46
43
|
});
|
|
47
44
|
});
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import find from 'find';
|
|
2
2
|
import Jasmine from 'jasmine';
|
|
3
|
-
import { parse } from 'ts-command-line-args';
|
|
4
3
|
import logger from 'jet-logger';
|
|
4
|
+
import { argv } from 'process';
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
// Setup command line options.
|
|
8
|
-
const args = parse<{
|
|
9
|
-
testFile: string;
|
|
10
|
-
}>({
|
|
11
|
-
testFile: {
|
|
12
|
-
type: String,
|
|
13
|
-
defaultValue: '',
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
|
|
17
7
|
// Init Jasmine
|
|
18
8
|
const jasmine = new Jasmine();
|
|
19
9
|
jasmine.exitOnCompletion = false;
|
|
@@ -30,8 +20,8 @@ jasmine.loadConfig({
|
|
|
30
20
|
|
|
31
21
|
// Run all or a single unit-test
|
|
32
22
|
let execResp: Promise<jasmine.JasmineDoneInfo> | undefined;
|
|
33
|
-
if (
|
|
34
|
-
const testFile =
|
|
23
|
+
if (!!argv[2]) {
|
|
24
|
+
const testFile = argv[2];
|
|
35
25
|
find.file(testFile + '.spec.ts', './spec', (files: string[]) => {
|
|
36
26
|
if (files.length === 1) {
|
|
37
27
|
jasmine.execute([files[0]]);
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { Response } from 'supertest';
|
|
2
|
-
|
|
3
2
|
import { IUser } from '@src/models/User';
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
// Misc
|
|
7
6
|
export type TReqBody = Record<string, unknown>;
|
|
8
|
-
export type TRes = Omit<Response, 'body'> & { body:
|
|
7
|
+
export type TRes = Omit<Response, 'body'> & { body: {
|
|
8
|
+
error?: string;
|
|
9
|
+
user?: IUser
|
|
10
|
+
users?: IUser[]
|
|
11
|
+
}};
|
|
9
12
|
export type TApiCb = (res: TRes) => void;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// Response Body: Add things to the body here over time to prevent
|
|
13
|
-
// typescript errors.
|
|
14
|
-
type TBody = {
|
|
15
|
-
[key: string]: unknown;
|
|
16
|
-
user?: IUser;
|
|
17
|
-
users?: IUser[];
|
|
18
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"users":[{"id":366115170645,"name":"Sean Maxwell","email":"smaxwell@example.com","created":"2024-03-22T05:14:36.252Z"},{"id":310946254456,"name":"John Smith","email":"john.smith@example.com","created":"2024-03-22T05:20:55.079Z"},{"id":143027113460,"name":"Gordan Freeman","email":"nova@prospect.com","created":"2024-03-22T05:42:18.895Z"}]}
|
|
1
|
+
{"users":[{"id":366115170645,"name":"Sean Maxwell","email":"smaxwell@example.com","created":"2024-03-22T05:14:36.252Z"},{"id":310946254456,"name":"John Smith","email":"john.smith@example.com","created":"2024-03-22T05:20:55.079Z"},{"id":143027113460,"name":"Gordan Freeman","email":"nova@prospect.com","created":"2024-03-22T05:42:18.895Z"},{"id":81065793658,"name":"d","email":"a","created":"2024-10-04T00:29:08.847Z"}]}
|
|
@@ -13,7 +13,7 @@ import check from './common/check';
|
|
|
13
13
|
*/
|
|
14
14
|
async function getAll(_: IReq, res: IRes) {
|
|
15
15
|
const users = await UserService.getAll();
|
|
16
|
-
|
|
16
|
+
res.status(HttpStatusCodes.OK).json({ users });
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -22,7 +22,7 @@ async function getAll(_: IReq, res: IRes) {
|
|
|
22
22
|
async function add(req: IReq, res: IRes) {
|
|
23
23
|
const user = check.isValid(req.body, 'user', User.isUser);
|
|
24
24
|
await UserService.addOne(user);
|
|
25
|
-
|
|
25
|
+
res.status(HttpStatusCodes.CREATED).end();
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -31,7 +31,7 @@ async function add(req: IReq, res: IRes) {
|
|
|
31
31
|
async function update(req: IReq, res: IRes) {
|
|
32
32
|
const user = check.isValid(req.body, 'user', User.isUser);
|
|
33
33
|
await UserService.updateOne(user);
|
|
34
|
-
|
|
34
|
+
res.status(HttpStatusCodes.OK).end();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
@@ -40,7 +40,7 @@ async function update(req: IReq, res: IRes) {
|
|
|
40
40
|
async function delete_(req: IReq, res: IRes) {
|
|
41
41
|
const id = check.isNum(req.params, 'id');
|
|
42
42
|
await UserService.delete(id);
|
|
43
|
-
|
|
43
|
+
res.status(HttpStatusCodes.OK).end();
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
|
|
@@ -8,10 +8,10 @@ type TReqObj = Record<string, unknown>;
|
|
|
8
8
|
* Check that param/s is a string
|
|
9
9
|
*/
|
|
10
10
|
function isStr(reqObj: TReqObj, params: string): string;
|
|
11
|
-
function isStr(reqObj: TReqObj, params:
|
|
11
|
+
function isStr(reqObj: TReqObj, params: readonly string[]): string[];
|
|
12
12
|
function isStr(
|
|
13
13
|
reqObj: TReqObj,
|
|
14
|
-
params: string |
|
|
14
|
+
params: string | readonly string[],
|
|
15
15
|
): string | string[] {
|
|
16
16
|
return _checkWrapper(reqObj, params, _checkStr);
|
|
17
17
|
}
|
|
@@ -31,10 +31,10 @@ function _checkStr(val: unknown): string | undefined {
|
|
|
31
31
|
* Check that param/s is a number.
|
|
32
32
|
*/
|
|
33
33
|
function isNum(reqObj: TReqObj, params: string): number;
|
|
34
|
-
function isNum(reqObj: TReqObj, params:
|
|
34
|
+
function isNum(reqObj: TReqObj, params: readonly string[]): number[];
|
|
35
35
|
function isNum(
|
|
36
36
|
reqObj: TReqObj,
|
|
37
|
-
params: string |
|
|
37
|
+
params: string | readonly string[],
|
|
38
38
|
): number | number[] {
|
|
39
39
|
return _checkWrapper(reqObj, params, _checkNum);
|
|
40
40
|
}
|
|
@@ -55,10 +55,10 @@ function _checkNum(val: unknown): number | undefined {
|
|
|
55
55
|
* Check that param/s is a number
|
|
56
56
|
*/
|
|
57
57
|
function isBool(reqObj: TReqObj, params: string): boolean;
|
|
58
|
-
function isBool(reqObj: TReqObj, params:
|
|
58
|
+
function isBool(reqObj: TReqObj, params: readonly string[]): boolean[];
|
|
59
59
|
function isBool(
|
|
60
60
|
reqObj: TReqObj,
|
|
61
|
-
params: string |
|
|
61
|
+
params: string | readonly string[],
|
|
62
62
|
): boolean | boolean[] {
|
|
63
63
|
return _checkWrapper(reqObj, params, _checkBool);
|
|
64
64
|
}
|
|
@@ -107,7 +107,7 @@ function isValid<T>(
|
|
|
107
107
|
*/
|
|
108
108
|
function _checkWrapper<T>(
|
|
109
109
|
reqObj: TReqObj,
|
|
110
|
-
params: string |
|
|
110
|
+
params: string | readonly string[],
|
|
111
111
|
checkFn: (val: unknown) => T | undefined,
|
|
112
112
|
): T | T[] {
|
|
113
113
|
// If is array
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
|
-
/**
|
|
3
|
-
* Shared types for routes.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
1
|
import { Response, Request } from 'express';
|
|
7
2
|
|
|
8
3
|
|
|
9
4
|
// **** Express **** //
|
|
10
5
|
|
|
11
6
|
type TObj = Record<string, unknown>;
|
|
12
|
-
|
|
13
7
|
export type IReq = Request<TObj, void, TObj, TObj>;
|
|
14
|
-
|
|
15
8
|
export type IRes = Response<unknown, TObj>
|
|
16
|
-
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Setup express server.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
import cookieParser from 'cookie-parser';
|
|
6
2
|
import morgan from 'morgan';
|
|
7
3
|
import path from 'path';
|
|
@@ -46,21 +42,16 @@ if (EnvVars.NodeEnv === NodeEnvs.Production.valueOf()) {
|
|
|
46
42
|
app.use(Paths.Base, BaseRouter);
|
|
47
43
|
|
|
48
44
|
// Add error handler
|
|
49
|
-
app.use((
|
|
50
|
-
err: Error,
|
|
51
|
-
_: Request,
|
|
52
|
-
res: Response,
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
54
|
-
next: NextFunction,
|
|
55
|
-
) => {
|
|
45
|
+
app.use((err: Error, _: Request, res: Response, next: NextFunction) => {
|
|
56
46
|
if (EnvVars.NodeEnv !== NodeEnvs.Test.valueOf()) {
|
|
57
47
|
logger.err(err, true);
|
|
58
48
|
}
|
|
59
49
|
let status = HttpStatusCodes.BAD_REQUEST;
|
|
60
50
|
if (err instanceof RouteError) {
|
|
61
51
|
status = err.status;
|
|
52
|
+
res.status(status).json({ error: err.message });
|
|
62
53
|
}
|
|
63
|
-
return
|
|
54
|
+
return next(err);
|
|
64
55
|
});
|
|
65
56
|
|
|
66
57
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
|
|
4
|
+
const eslint = require('@eslint/js');
|
|
5
|
+
const tseslint = require('typescript-eslint');
|
|
6
|
+
const stylisticTs = require('@stylistic/eslint-plugin-ts');
|
|
7
|
+
const nodePlugin = require('eslint-plugin-n');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module.exports = tseslint.config(
|
|
11
|
+
eslint.configs.recommended,
|
|
12
|
+
nodePlugin.configs['flat/recommended-script'],
|
|
13
|
+
...tseslint.configs.strictTypeChecked,
|
|
14
|
+
...tseslint.configs.stylisticTypeChecked,
|
|
15
|
+
{
|
|
16
|
+
languageOptions: {
|
|
17
|
+
parserOptions: {
|
|
18
|
+
project: './tsconfig.json',
|
|
19
|
+
warnOnUnsupportedTypeScriptVersion: false,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
plugins: {
|
|
25
|
+
'@stylistic/ts': stylisticTs,
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
files: ['**/*.ts'],
|
|
30
|
+
ignores: ['**/*.js'],
|
|
31
|
+
rules: {
|
|
32
|
+
'@typescript-eslint/explicit-member-accessibility': 'warn',
|
|
33
|
+
'@typescript-eslint/no-misused-promises': 0,
|
|
34
|
+
'@typescript-eslint/no-floating-promises': 0,
|
|
35
|
+
'@typescript-eslint/no-confusing-void-expression': 0,
|
|
36
|
+
'@typescript-eslint/no-unnecessary-condition': 0,
|
|
37
|
+
'@typescript-eslint/restrict-template-expressions': [ 'error', { allowNumber: true }],
|
|
38
|
+
'max-len': [
|
|
39
|
+
'warn',
|
|
40
|
+
{
|
|
41
|
+
'code': 80
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
'@stylistic/ts/semi': ['warn'],
|
|
45
|
+
'comma-dangle': ['warn', 'always-multiline'],
|
|
46
|
+
'no-console': 1,
|
|
47
|
+
'no-extra-boolean-cast': 0,
|
|
48
|
+
'indent': ['warn', 2],
|
|
49
|
+
'quotes': ['warn', 'single'],
|
|
50
|
+
'n/no-process-env': 1,
|
|
51
|
+
'n/no-missing-import': 0,
|
|
52
|
+
'n/no-unpublished-import': 0
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
)
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
"name": "express-typescript-example",
|
|
3
3
|
"version": "0.0.0",
|
|
4
4
|
"scripts": {
|
|
5
|
-
"build": "ts-node ./scripts/build.ts",
|
|
6
|
-
"dev": "NODE_ENV=development ts-node ./src",
|
|
5
|
+
"build": "npx ts-node ./scripts/build.ts",
|
|
6
|
+
"dev": "NODE_ENV=development npx ts-node ./src",
|
|
7
7
|
"dev:hot": "nodemon --exec \"npm run dev\" --watch ./src -e ts",
|
|
8
|
-
"lint": "npx eslint
|
|
9
|
-
"lint:tests": "npx eslint
|
|
8
|
+
"lint": "npx eslint ./src/**/*.ts",
|
|
9
|
+
"lint:tests": "npx eslint ./spec/**/*.ts",
|
|
10
10
|
"start": "NODE_ENV=production node -r ./preload.js ./dist",
|
|
11
|
-
"test": "NODE_ENV=test ts-node ./spec",
|
|
11
|
+
"test": "NODE_ENV=test npx ts-node ./spec",
|
|
12
12
|
"test:hot": "nodemon --exec \"npm run test\" --watch ./src --watch ./spec -e ts"
|
|
13
13
|
},
|
|
14
14
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
15
|
+
"node": ">=16.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"bcrypt": "^5.0.1",
|
|
@@ -32,7 +32,10 @@
|
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/bcrypt": "^5.0.0",
|
|
35
|
+
"@eslint/js": "^9.11.1",
|
|
36
|
+
"@stylistic/eslint-plugin-ts": "^2.8.0",
|
|
35
37
|
"@types/cookie-parser": "^1.4.3",
|
|
38
|
+
"@types/eslint__js": "^8.42.3",
|
|
36
39
|
"@types/express": "^4.17.13",
|
|
37
40
|
"@types/find": "^0.2.1",
|
|
38
41
|
"@types/fs-extra": "^9.0.13",
|
|
@@ -42,18 +45,16 @@
|
|
|
42
45
|
"@types/morgan": "^1.9.3",
|
|
43
46
|
"@types/node": "^18.7.14",
|
|
44
47
|
"@types/supertest": "^6.0.2",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"eslint": "^8.23.0",
|
|
48
|
-
"eslint-plugin-node": "^11.1.0",
|
|
48
|
+
"eslint": "^9.11.1",
|
|
49
|
+
"eslint-plugin-n": "^17.10.3",
|
|
49
50
|
"find": "^0.3.0",
|
|
50
51
|
"fs-extra": "^10.1.0",
|
|
51
52
|
"jasmine": "^4.3.0",
|
|
52
53
|
"nodemon": "^2.0.19",
|
|
53
54
|
"supertest": "^6.3.4",
|
|
54
|
-
"ts-command-line-args": "^2.4.2",
|
|
55
55
|
"ts-node": "^10.9.1",
|
|
56
56
|
"tsconfig-paths": "^4.1.0",
|
|
57
|
-
"typescript": "^
|
|
57
|
+
"typescript": "^5.6.2",
|
|
58
|
+
"typescript-eslint": "^8.8.0"
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
1
3
|
const dotenv = require('dotenv');
|
|
2
4
|
const path = require('path');
|
|
3
5
|
const moduleAlias = require('module-alias');
|
|
@@ -18,3 +20,4 @@ if (result2.error) {
|
|
|
18
20
|
if (NODE_ENV === 'production') {
|
|
19
21
|
moduleAlias.addAlias('@src', __dirname + '/dist');
|
|
20
22
|
}
|
|
23
|
+
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Remove old files, copy front-end ones.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
import fs from 'fs-extra';
|
|
6
2
|
import logger from 'jet-logger';
|
|
7
3
|
import childProcess from 'child_process';
|
|
@@ -14,13 +10,14 @@ import childProcess from 'child_process';
|
|
|
14
10
|
try {
|
|
15
11
|
// Remove current build
|
|
16
12
|
await remove('./dist/');
|
|
17
|
-
await exec('
|
|
13
|
+
await exec('npm run lint', './');
|
|
18
14
|
await exec('tsc --build tsconfig.prod.json', './');
|
|
19
15
|
// Copy
|
|
20
16
|
await copy('./src/public', './dist/public');
|
|
21
17
|
await copy('./src/views', './dist/views');
|
|
22
18
|
} catch (err) {
|
|
23
19
|
logger.err(err);
|
|
20
|
+
// eslint-disable-next-line n/no-process-exit
|
|
24
21
|
process.exit(1);
|
|
25
22
|
}
|
|
26
23
|
})();
|
|
@@ -30,7 +27,7 @@ import childProcess from 'child_process';
|
|
|
30
27
|
*/
|
|
31
28
|
function remove(loc: string): Promise<void> {
|
|
32
29
|
return new Promise((res, rej) => {
|
|
33
|
-
return fs.remove(loc,
|
|
30
|
+
return fs.remove(loc, err => {
|
|
34
31
|
return (!!err ? rej(err) : res());
|
|
35
32
|
});
|
|
36
33
|
});
|
|
@@ -41,7 +38,7 @@ function remove(loc: string): Promise<void> {
|
|
|
41
38
|
*/
|
|
42
39
|
function copy(src: string, dest: string): Promise<void> {
|
|
43
40
|
return new Promise((res, rej) => {
|
|
44
|
-
return fs.copy(src, dest,
|
|
41
|
+
return fs.copy(src, dest, err => {
|
|
45
42
|
return (!!err ? rej(err) : res());
|
|
46
43
|
});
|
|
47
44
|
});
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import find from 'find';
|
|
2
2
|
import Jasmine from 'jasmine';
|
|
3
|
-
import { parse } from 'ts-command-line-args';
|
|
4
3
|
import logger from 'jet-logger';
|
|
4
|
+
import { argv } from 'process';
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
// Setup command line options.
|
|
8
|
-
const args = parse<{
|
|
9
|
-
testFile: string;
|
|
10
|
-
}>({
|
|
11
|
-
testFile: {
|
|
12
|
-
type: String,
|
|
13
|
-
defaultValue: '',
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
|
|
17
7
|
// Init Jasmine
|
|
18
8
|
const jasmine = new Jasmine();
|
|
19
9
|
jasmine.exitOnCompletion = false;
|
|
@@ -30,8 +20,8 @@ jasmine.loadConfig({
|
|
|
30
20
|
|
|
31
21
|
// Run all or a single unit-test
|
|
32
22
|
let execResp: Promise<jasmine.JasmineDoneInfo> | undefined;
|
|
33
|
-
if (
|
|
34
|
-
const testFile =
|
|
23
|
+
if (!!argv[2]) {
|
|
24
|
+
const testFile = argv[2];
|
|
35
25
|
find.file(testFile + '.spec.ts', './spec', (files: string[]) => {
|
|
36
26
|
if (files.length === 1) {
|
|
37
27
|
jasmine.execute([files[0]]);
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { Response } from 'supertest';
|
|
2
|
-
|
|
3
2
|
import { IUser } from '@src/models/User';
|
|
4
3
|
|
|
5
4
|
|
|
6
5
|
// Misc
|
|
7
6
|
export type TReqBody = Record<string, unknown>;
|
|
8
|
-
export type TRes = Omit<Response, 'body'> & { body:
|
|
7
|
+
export type TRes = Omit<Response, 'body'> & { body: {
|
|
8
|
+
error?: string;
|
|
9
|
+
user?: IUser
|
|
10
|
+
users?: IUser[]
|
|
11
|
+
}};
|
|
9
12
|
export type TApiCb = (res: TRes) => void;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// Response Body: Add things to the body here over time to prevent
|
|
13
|
-
// typescript errors.
|
|
14
|
-
type TBody = {
|
|
15
|
-
[key: string]: unknown;
|
|
16
|
-
user?: IUser;
|
|
17
|
-
users?: IUser[];
|
|
18
|
-
}
|
|
@@ -22,7 +22,7 @@ async function login(req: IReq, res: IRes) {
|
|
|
22
22
|
role: user.role,
|
|
23
23
|
});
|
|
24
24
|
// Return
|
|
25
|
-
|
|
25
|
+
res.status(HttpStatusCodes.OK).end();
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -30,7 +30,7 @@ async function login(req: IReq, res: IRes) {
|
|
|
30
30
|
*/
|
|
31
31
|
function logout(_: IReq, res: IRes) {
|
|
32
32
|
SessionUtil.clearCookie(res);
|
|
33
|
-
|
|
33
|
+
res.status(HttpStatusCodes.OK).end();
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
|
|
@@ -14,7 +14,7 @@ import check from './common/check';
|
|
|
14
14
|
*/
|
|
15
15
|
async function getAll(_: IReq, res: IRes) {
|
|
16
16
|
const users = await UserService.getAll();
|
|
17
|
-
|
|
17
|
+
res.status(HttpStatusCodes.OK).json({ users });
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -23,7 +23,7 @@ async function getAll(_: IReq, res: IRes) {
|
|
|
23
23
|
async function add(req: IReq, res: IRes) {
|
|
24
24
|
const user = check.isValid(req.body, 'user', User.isUser);
|
|
25
25
|
await UserService.addOne(user);
|
|
26
|
-
|
|
26
|
+
res.status(HttpStatusCodes.CREATED).end();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -32,7 +32,7 @@ async function add(req: IReq, res: IRes) {
|
|
|
32
32
|
async function update(req: IReq, res: IRes) {
|
|
33
33
|
const user = check.isValid(req.body, 'user', User.isUser);
|
|
34
34
|
await UserService.updateOne(user);
|
|
35
|
-
|
|
35
|
+
res.status(HttpStatusCodes.OK).end();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -41,7 +41,7 @@ async function update(req: IReq, res: IRes) {
|
|
|
41
41
|
async function delete_(req: IReq, res: IRes) {
|
|
42
42
|
const id = check.isNum(req.params, 'id');
|
|
43
43
|
await UserService.delete(id);
|
|
44
|
-
|
|
44
|
+
res.status(HttpStatusCodes.OK).end();
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
|
|
@@ -8,10 +8,10 @@ type TReqObj = Record<string, unknown>;
|
|
|
8
8
|
* Check that param/s is a string
|
|
9
9
|
*/
|
|
10
10
|
function isStr(reqObj: TReqObj, params: string): string;
|
|
11
|
-
function isStr(reqObj: TReqObj, params:
|
|
11
|
+
function isStr(reqObj: TReqObj, params: readonly string[]): string[];
|
|
12
12
|
function isStr(
|
|
13
13
|
reqObj: TReqObj,
|
|
14
|
-
params: string |
|
|
14
|
+
params: string | readonly string[],
|
|
15
15
|
): string | string[] {
|
|
16
16
|
return _checkWrapper(reqObj, params, _checkStr);
|
|
17
17
|
}
|
|
@@ -31,10 +31,10 @@ function _checkStr(val: unknown): string | undefined {
|
|
|
31
31
|
* Check that param/s is a number.
|
|
32
32
|
*/
|
|
33
33
|
function isNum(reqObj: TReqObj, params: string): number;
|
|
34
|
-
function isNum(reqObj: TReqObj, params:
|
|
34
|
+
function isNum(reqObj: TReqObj, params: readonly string[]): number[];
|
|
35
35
|
function isNum(
|
|
36
36
|
reqObj: TReqObj,
|
|
37
|
-
params: string |
|
|
37
|
+
params: string | readonly string[],
|
|
38
38
|
): number | number[] {
|
|
39
39
|
return _checkWrapper(reqObj, params, _checkNum);
|
|
40
40
|
}
|
|
@@ -55,10 +55,10 @@ function _checkNum(val: unknown): number | undefined {
|
|
|
55
55
|
* Check that param/s is a number
|
|
56
56
|
*/
|
|
57
57
|
function isBool(reqObj: TReqObj, params: string): boolean;
|
|
58
|
-
function isBool(reqObj: TReqObj, params:
|
|
58
|
+
function isBool(reqObj: TReqObj, params: readonly string[]): boolean[];
|
|
59
59
|
function isBool(
|
|
60
60
|
reqObj: TReqObj,
|
|
61
|
-
params: string |
|
|
61
|
+
params: string | readonly string[],
|
|
62
62
|
): boolean | boolean[] {
|
|
63
63
|
return _checkWrapper(reqObj, params, _checkBool);
|
|
64
64
|
}
|
|
@@ -107,7 +107,7 @@ function isValid<T>(
|
|
|
107
107
|
*/
|
|
108
108
|
function _checkWrapper<T>(
|
|
109
109
|
reqObj: TReqObj,
|
|
110
|
-
params: string |
|
|
110
|
+
params: string | readonly string[],
|
|
111
111
|
checkFn: (val: unknown) => T | undefined,
|
|
112
112
|
): T | T[] {
|
|
113
113
|
// If is array
|
|
@@ -47,21 +47,16 @@ if (EnvVars.NodeEnv === NodeEnvs.Production.valueOf()) {
|
|
|
47
47
|
app.use(Paths.Base, BaseRouter);
|
|
48
48
|
|
|
49
49
|
// Add error handler
|
|
50
|
-
app.use((
|
|
51
|
-
err: Error,
|
|
52
|
-
_: Request,
|
|
53
|
-
res: Response,
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
55
|
-
next: NextFunction,
|
|
56
|
-
) => {
|
|
50
|
+
app.use((err: Error, _: Request, res: Response, next: NextFunction) => {
|
|
57
51
|
if (EnvVars.NodeEnv !== NodeEnvs.Test.valueOf()) {
|
|
58
52
|
logger.err(err, true);
|
|
59
53
|
}
|
|
60
54
|
let status = HttpStatusCodes.BAD_REQUEST;
|
|
61
55
|
if (err instanceof RouteError) {
|
|
62
56
|
status = err.status;
|
|
57
|
+
res.status(status).json({ error: err.message });
|
|
63
58
|
}
|
|
64
|
-
return
|
|
59
|
+
return next(err);
|
|
65
60
|
});
|
|
66
61
|
|
|
67
62
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-generator-typescript",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.23",
|
|
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",
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"parser": "@typescript-eslint/parser",
|
|
3
|
-
"plugins": [
|
|
4
|
-
"@typescript-eslint"
|
|
5
|
-
],
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/recommended",
|
|
9
|
-
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
|
10
|
-
"plugin:node/recommended"
|
|
11
|
-
],
|
|
12
|
-
"parserOptions": {
|
|
13
|
-
"project": "./tsconfig.json"
|
|
14
|
-
},
|
|
15
|
-
"rules": {
|
|
16
|
-
"@typescript-eslint/explicit-member-accessibility": "warn",
|
|
17
|
-
"@typescript-eslint/no-misused-promises": 0,
|
|
18
|
-
"@typescript-eslint/no-floating-promises": 0,
|
|
19
|
-
"max-len": [
|
|
20
|
-
"warn",
|
|
21
|
-
{
|
|
22
|
-
"code": 80
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"comma-dangle": ["warn", "always-multiline"],
|
|
26
|
-
"no-console": 1,
|
|
27
|
-
"no-extra-boolean-cast": 0,
|
|
28
|
-
"semi": 1,
|
|
29
|
-
"indent": ["warn", 2],
|
|
30
|
-
"quotes": ["warn", "single"],
|
|
31
|
-
"node/no-process-env": 1,
|
|
32
|
-
"node/no-unsupported-features/es-syntax": [
|
|
33
|
-
"error",
|
|
34
|
-
{ "ignores" : ["modules"] }
|
|
35
|
-
],
|
|
36
|
-
"node/no-missing-import": 0,
|
|
37
|
-
"node/no-unpublished-import": 0
|
|
38
|
-
},
|
|
39
|
-
"settings": {
|
|
40
|
-
"node": {
|
|
41
|
-
"tryExtensions": [".js", ".json", ".node", ".ts"]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"parser": "@typescript-eslint/parser",
|
|
3
|
-
"plugins": [
|
|
4
|
-
"@typescript-eslint"
|
|
5
|
-
],
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/recommended",
|
|
9
|
-
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
|
10
|
-
"plugin:node/recommended"
|
|
11
|
-
],
|
|
12
|
-
"parserOptions": {
|
|
13
|
-
"project": "./tsconfig.json"
|
|
14
|
-
},
|
|
15
|
-
"rules": {
|
|
16
|
-
"@typescript-eslint/explicit-member-accessibility": "warn",
|
|
17
|
-
"@typescript-eslint/no-misused-promises": 0,
|
|
18
|
-
"@typescript-eslint/no-floating-promises": 0,
|
|
19
|
-
"max-len": [
|
|
20
|
-
"warn",
|
|
21
|
-
{
|
|
22
|
-
"code": 80
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"comma-dangle": ["warn", "always-multiline"],
|
|
26
|
-
"no-console": 1,
|
|
27
|
-
"no-extra-boolean-cast": 0,
|
|
28
|
-
"semi": 1,
|
|
29
|
-
"indent": ["warn", 2],
|
|
30
|
-
"quotes": ["warn", "single"],
|
|
31
|
-
"node/no-process-env": 1,
|
|
32
|
-
"node/no-unsupported-features/es-syntax": [
|
|
33
|
-
"error",
|
|
34
|
-
{ "ignores" : ["modules"] }
|
|
35
|
-
],
|
|
36
|
-
"node/no-missing-import": 0,
|
|
37
|
-
"node/no-unpublished-import": 0
|
|
38
|
-
},
|
|
39
|
-
"settings": {
|
|
40
|
-
"node": {
|
|
41
|
-
"tryExtensions": [".js", ".json", ".node", ".ts"]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|