@cley_faye/boilerplate 3.18.0 → 3.20.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 +8 -1
- package/lib/bin/serve_spa.js +20 -4
- package/lib/express.d.ts +13 -2
- package/lib/express.js +18 -5
- package/lib/grunt/args.js +1 -1
- package/lib/grunt/reactapp.js +1 -1
- package/lib/winston.js +7 -17
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -443,6 +443,7 @@ appStart({
|
|
|
443
443
|
port: 3000,
|
|
444
444
|
shutdownFunction: () => {;},
|
|
445
445
|
logger: consoleLogger,
|
|
446
|
+
noReady: false,
|
|
446
447
|
}).then(({port, server}) => {;});
|
|
447
448
|
```
|
|
448
449
|
|
|
@@ -453,8 +454,14 @@ The settings are:
|
|
|
453
454
|
- port: port to listen to. Can be 0 to use a random available port
|
|
454
455
|
- shutdownFunction: a function to call after the server stop listening
|
|
455
456
|
- logger: a winston logger to log that the server started listening
|
|
457
|
+
- noReady: if true, does not call `process.send("ready");` (used by PM2)
|
|
456
458
|
|
|
457
|
-
The function
|
|
459
|
+
The shutdown function can return a promise, and if it returns/resolve with `true` the process is
|
|
460
|
+
left alive.
|
|
461
|
+
Otherwise `process.exit()` is called after `shutdownFunction()` resolves/returns.
|
|
462
|
+
|
|
463
|
+
The `appStart()` function returns a promise that resolve with the actual port used for listening
|
|
464
|
+
when the server is started.
|
|
458
465
|
|
|
459
466
|
The server is automatically registered using the `autoclose` part to stop when a SIGINT signal is
|
|
460
467
|
received.
|
package/lib/bin/serve_spa.js
CHANGED
|
@@ -53,16 +53,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
53
53
|
};
|
|
54
54
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
55
|
const path = __importStar(require("node:path"));
|
|
56
|
+
const node_fs_1 = require("node:fs");
|
|
56
57
|
const express_1 = __importDefault(require("express"));
|
|
57
58
|
const minimist_1 = __importDefault(require("minimist"));
|
|
58
59
|
const singlepageapp_js_1 = require("../express/middlewares/singlepageapp.js");
|
|
59
60
|
const express_js_1 = require("../express.js");
|
|
60
61
|
const winston_js_1 = require("../winston.js");
|
|
61
62
|
const ARGV_START_OFFSET = 2;
|
|
62
|
-
const { port, root, index, help, static: staticDirs } = (0, minimist_1.default)(process.argv.slice(ARGV_START_OFFSET));
|
|
63
|
+
const { port, root, index, help, staticlist, static: staticDirs } = (0, minimist_1.default)(process.argv.slice(ARGV_START_OFFSET));
|
|
63
64
|
const DEFAULT_PORT = 3000;
|
|
64
65
|
const DEFAULT_PATH = path.join("dist", "webapp");
|
|
65
66
|
const DEFAULT_INDEX = "index.html";
|
|
67
|
+
const DEFAULT_STATICFILE = "spa_static.config";
|
|
66
68
|
const DEFAULT_STATIC = ["js", "css", "img"];
|
|
67
69
|
if (help) {
|
|
68
70
|
winston_js_1.consoleLogger.info(`
|
|
@@ -72,20 +74,34 @@ serve_spa \\
|
|
|
72
74
|
[--port=${DEFAULT_PORT}] \\
|
|
73
75
|
[--root=${DEFAULT_PATH}] \\
|
|
74
76
|
[--index=${DEFAULT_INDEX}] \\
|
|
77
|
+
[--staticlist=${DEFAULT_STATICFILE}] \\
|
|
75
78
|
[--static=js…] \\
|
|
76
79
|
[--help]
|
|
77
80
|
|
|
78
81
|
The --static argument can be repeated to add more directories to it.
|
|
79
82
|
It defaults to ${JSON.stringify(DEFAULT_STATIC)}.
|
|
83
|
+
|
|
84
|
+
The staticfile value is a text file with one static directory line.
|
|
85
|
+
If present, they are merged with the CLI arguments.
|
|
80
86
|
`.trim());
|
|
81
87
|
// eslint-disable-next-line no-process-exit
|
|
82
88
|
process.exit(0);
|
|
83
89
|
}
|
|
84
90
|
const getPort = () => port ?? DEFAULT_PORT;
|
|
85
91
|
const getStatic = () => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
const result = [];
|
|
93
|
+
if (staticDirs)
|
|
94
|
+
result.push(...(Array.isArray(staticDirs) ? staticDirs : [staticDirs]));
|
|
95
|
+
if (staticlist) {
|
|
96
|
+
for (const staticsrc of (Array.isArray(staticlist) ? staticlist : [staticlist])) {
|
|
97
|
+
if (!(0, node_fs_1.existsSync)(staticsrc))
|
|
98
|
+
continue;
|
|
99
|
+
result.push(...(0, node_fs_1.readFileSync)(staticsrc, "utf8")
|
|
100
|
+
.split("\n")
|
|
101
|
+
.filter(c => c));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return result.length > 0 ? result : undefined;
|
|
89
105
|
};
|
|
90
106
|
const app = (0, express_1.default)();
|
|
91
107
|
app.use((0, express_js_1.createPipeline)({
|
package/lib/express.d.ts
CHANGED
|
@@ -104,6 +104,15 @@ export declare const createPipeline: (settings: PipelineSettings, debugLog?: Log
|
|
|
104
104
|
* Configure the views rendering engine for an ExpressJS App
|
|
105
105
|
*/
|
|
106
106
|
export declare const setViewEngine: (app: express.Express, viewEngine: string, viewsDirectory: string, extraLocals?: Record<string, string | number>) => void;
|
|
107
|
+
/**
|
|
108
|
+
* Function to call when the server stops.
|
|
109
|
+
*
|
|
110
|
+
* This is usually triggered by a SIGTERM.
|
|
111
|
+
*
|
|
112
|
+
* If the function returns "true", it prevent the process from stopping.
|
|
113
|
+
* Otherwise `process.exit()` is called.
|
|
114
|
+
*/
|
|
115
|
+
type ShutdownFunction = () => Promise<boolean> | boolean | undefined;
|
|
107
116
|
export interface StartDefinition {
|
|
108
117
|
app: express.Application;
|
|
109
118
|
/** @deprecated use listenInterface instead */
|
|
@@ -117,8 +126,9 @@ export interface StartDefinition {
|
|
|
117
126
|
*/
|
|
118
127
|
listenInterface?: boolean | string;
|
|
119
128
|
port?: number;
|
|
120
|
-
shutdownFunction?:
|
|
129
|
+
shutdownFunction?: ShutdownFunction;
|
|
121
130
|
logger?: winston.Logger;
|
|
131
|
+
noReady?: boolean;
|
|
122
132
|
}
|
|
123
133
|
export interface StartResult {
|
|
124
134
|
port: number;
|
|
@@ -144,4 +154,5 @@ export interface StartResult {
|
|
|
144
154
|
*
|
|
145
155
|
* @property server
|
|
146
156
|
*/
|
|
147
|
-
export declare const appStart: ({ app, allowNonLocal, listenInterface, port, shutdownFunction, logger, }: StartDefinition) => Promise<StartResult>;
|
|
157
|
+
export declare const appStart: ({ app, allowNonLocal, listenInterface, port, shutdownFunction, logger, noReady, }: StartDefinition) => Promise<StartResult>;
|
|
158
|
+
export {};
|
package/lib/express.js
CHANGED
|
@@ -149,6 +149,19 @@ const setViewEngine = (app, viewEngine, viewsDirectory, extraLocals) => {
|
|
|
149
149
|
}
|
|
150
150
|
};
|
|
151
151
|
exports.setViewEngine = setViewEngine;
|
|
152
|
+
const handleShutdown = (logger, shutdownFunction) => () => {
|
|
153
|
+
const fn = async () => {
|
|
154
|
+
const noExit = shutdownFunction ? Boolean(await shutdownFunction()) : false;
|
|
155
|
+
if (noExit)
|
|
156
|
+
return;
|
|
157
|
+
// We *want* to exit on server shutdown
|
|
158
|
+
// eslint-disable-next-line no-process-exit
|
|
159
|
+
process.exit();
|
|
160
|
+
};
|
|
161
|
+
fn().catch(err => {
|
|
162
|
+
logger?.error(err);
|
|
163
|
+
});
|
|
164
|
+
};
|
|
152
165
|
/** Start the server and register signal for automatic closing.
|
|
153
166
|
*
|
|
154
167
|
* @param app
|
|
@@ -169,7 +182,7 @@ exports.setViewEngine = setViewEngine;
|
|
|
169
182
|
*
|
|
170
183
|
* @property server
|
|
171
184
|
*/
|
|
172
|
-
const appStart = ({ app, allowNonLocal, listenInterface, port, shutdownFunction, logger, }) => new Promise(resolve => {
|
|
185
|
+
const appStart = ({ app, allowNonLocal, listenInterface, port, shutdownFunction, logger, noReady, }) => new Promise(resolve => {
|
|
173
186
|
let server = null;
|
|
174
187
|
const readyCallback = () => {
|
|
175
188
|
if (server === null) {
|
|
@@ -185,11 +198,13 @@ const appStart = ({ app, allowNonLocal, listenInterface, port, shutdownFunction,
|
|
|
185
198
|
port: effectivePort,
|
|
186
199
|
server,
|
|
187
200
|
});
|
|
201
|
+
if (!noReady && process.send)
|
|
202
|
+
process.send("ready");
|
|
188
203
|
};
|
|
189
204
|
if (allowNonLocal !== undefined && listenInterface !== undefined) {
|
|
190
205
|
throw new Error("You can't specify both allowNonLocal and listenInterface at the same time");
|
|
191
206
|
}
|
|
192
|
-
if (allowNonLocal
|
|
207
|
+
if (allowNonLocal ?? listenInterface === true) {
|
|
193
208
|
server = app.listen(port ?? 0, readyCallback);
|
|
194
209
|
}
|
|
195
210
|
else if (typeof listenInterface === "string") {
|
|
@@ -198,8 +213,6 @@ const appStart = ({ app, allowNonLocal, listenInterface, port, shutdownFunction,
|
|
|
198
213
|
else {
|
|
199
214
|
server = app.listen(port ?? 0, "localhost", readyCallback);
|
|
200
215
|
}
|
|
201
|
-
|
|
202
|
-
server.on("close", shutdownFunction);
|
|
203
|
-
}
|
|
216
|
+
server.on("close", handleShutdown(logger, shutdownFunction));
|
|
204
217
|
});
|
|
205
218
|
exports.appStart = appStart;
|
package/lib/grunt/args.js
CHANGED
|
@@ -37,7 +37,7 @@ var OptType;
|
|
|
37
37
|
OptType["NUMBER"] = "number";
|
|
38
38
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
39
39
|
OptType["BOOLEAN"] = "boolean";
|
|
40
|
-
})(OptType
|
|
40
|
+
})(OptType || (exports.OptType = OptType = {}));
|
|
41
41
|
/**
|
|
42
42
|
* Process a string-type argument
|
|
43
43
|
*/
|
package/lib/grunt/reactapp.js
CHANGED
|
@@ -47,7 +47,7 @@ var HandlerType;
|
|
|
47
47
|
HandlerType["SASS"] = "sass";
|
|
48
48
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
49
49
|
HandlerType["COPY"] = "copy";
|
|
50
|
-
})(HandlerType
|
|
50
|
+
})(HandlerType || (exports.HandlerType = HandlerType = {}));
|
|
51
51
|
const gatherTasks = (handlers, gruntConfig, targetName, options) => Object.keys(handlers)
|
|
52
52
|
.reduce((acc, cur) => acc.concat((options?.[cur] && options[cur]?.disabled)
|
|
53
53
|
? []
|
package/lib/winston.js
CHANGED
|
@@ -69,7 +69,7 @@ exports.filterStacktrace = filterStacktrace;
|
|
|
69
69
|
* Prefix all lines with the level and the timestamp if needed
|
|
70
70
|
*/
|
|
71
71
|
const prefixOutput = (level, message, timestamp) => {
|
|
72
|
-
const timestampPrefix = timestamp
|
|
72
|
+
const timestampPrefix = (timestamp ?? (level.toLowerCase() === "error"))
|
|
73
73
|
? `${new Date().toISOString()} `
|
|
74
74
|
: "";
|
|
75
75
|
const levelPrefix = `${level.toString().padStart(LOG_LEVEL_PADDING_SIZE)}: `;
|
|
@@ -119,12 +119,7 @@ const addAxiosContent = (error) => {
|
|
|
119
119
|
res.push(JSON.stringify(error.response.data));
|
|
120
120
|
}
|
|
121
121
|
catch {
|
|
122
|
-
|
|
123
|
-
res.push(error.response.data.toString());
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
res.push("<cannot output body>");
|
|
127
|
-
}
|
|
122
|
+
res.push("<cannot output body>");
|
|
128
123
|
}
|
|
129
124
|
}
|
|
130
125
|
}
|
|
@@ -145,7 +140,7 @@ const getCause = (error) => {
|
|
|
145
140
|
if (cause instanceof Error)
|
|
146
141
|
return cause;
|
|
147
142
|
try {
|
|
148
|
-
return new Error(
|
|
143
|
+
return new Error(JSON.stringify(cause));
|
|
149
144
|
}
|
|
150
145
|
catch {
|
|
151
146
|
return new Error("Unknown cause");
|
|
@@ -205,15 +200,10 @@ const getErrorFromTransformable = (info) => {
|
|
|
205
200
|
}
|
|
206
201
|
};
|
|
207
202
|
const customFormat = (timestamp, collapseStacktrace, stacktraceFilter) => winston_1.default.format.printf((info) => {
|
|
208
|
-
const effectiveTimestamp = timestamp
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
? logConfig.collapseNodeModules || logConfig.collapseStacktrace
|
|
213
|
-
: collapseStacktrace;
|
|
214
|
-
const effectiveStacktraceFilter = stacktraceFilter === undefined
|
|
215
|
-
? logConfig.stacktraceFilter
|
|
216
|
-
: stacktraceFilter;
|
|
203
|
+
const effectiveTimestamp = timestamp ?? logConfig.timestamp;
|
|
204
|
+
const effectiveCollapse = collapseStacktrace
|
|
205
|
+
?? (logConfig.collapseNodeModules || logConfig.collapseStacktrace);
|
|
206
|
+
const effectiveStacktraceFilter = stacktraceFilter ?? logConfig.stacktraceFilter;
|
|
217
207
|
const error = getErrorFromTransformable(info);
|
|
218
208
|
const message = error
|
|
219
209
|
? (0, exports.filterError)(error, effectiveCollapse, effectiveStacktraceFilter)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cley_faye/boilerplate",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.20.0",
|
|
4
4
|
"description": "Boilerplate code generator for generic projects",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,19 +21,19 @@
|
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/CleyFaye/boilerplate#readme",
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@keeex/eslint-config": "^1.
|
|
25
|
-
"@types/express": "^4.17.
|
|
26
|
-
"@types/grunt": "^0.4.
|
|
27
|
-
"@types/http-errors": "^2.0.
|
|
28
|
-
"@types/minimist": "^1.2.
|
|
29
|
-
"@types/node": "^18.
|
|
30
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
31
|
-
"@typescript-eslint/parser": "^
|
|
32
|
-
"eslint": "^8.
|
|
33
|
-
"eslint-plugin-deprecation": "^
|
|
34
|
-
"eslint-plugin-import": "^2.
|
|
24
|
+
"@keeex/eslint-config": "^1.11.5",
|
|
25
|
+
"@types/express": "^4.17.18",
|
|
26
|
+
"@types/grunt": "^0.4.28",
|
|
27
|
+
"@types/http-errors": "^2.0.2",
|
|
28
|
+
"@types/minimist": "^1.2.3",
|
|
29
|
+
"@types/node": "^18.18.3",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
|
31
|
+
"@typescript-eslint/parser": "^6.7.4",
|
|
32
|
+
"eslint": "^8.50.0",
|
|
33
|
+
"eslint-plugin-deprecation": "^2.0.0",
|
|
34
|
+
"eslint-plugin-import": "^2.28.1",
|
|
35
35
|
"eslint-plugin-promise": "^6.1.1",
|
|
36
|
-
"eslint-webpack-plugin": "^4.0.
|
|
36
|
+
"eslint-webpack-plugin": "^4.0.1",
|
|
37
37
|
"express-winston": "^4.2.0",
|
|
38
38
|
"grunt": "^1.6.1",
|
|
39
39
|
"grunt-banner": "^0.6.0",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"grunt-run": "^0.8.1",
|
|
42
42
|
"load-grunt-tasks": "^5.1.0",
|
|
43
43
|
"logform": "^2.5.1",
|
|
44
|
-
"typescript": "^
|
|
45
|
-
"webpack": "^5.
|
|
46
|
-
"winston": "^3.
|
|
44
|
+
"typescript": "^5.2.2",
|
|
45
|
+
"webpack": "^5.88.2",
|
|
46
|
+
"winston": "^3.10.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@babel/core": "7.x",
|