exisjs 0.9.1 → 0.10.0-alpha.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 +3 -0
- package/bin/exis.js +76 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +2 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +16 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/docs/content/README.md +1 -0
- package/dist/docs/content/cli/commands.mdx +23 -1
- package/dist/docs/content/cli/usage.mdx +2 -1
- package/dist/docs/content/config.mdx +50 -4
- package/dist/docs/content/deployment.mdx +163 -0
- package/dist/docs/content/installation.mdx +1 -1
- package/dist/docs/content/introduction.mdx +3 -0
- package/dist/docs/content/validation.mdx +34 -12
- package/dist/docs/reference/config.mdx +3 -1
- package/dist/docs/reference/sanitize.mdx +129 -134
- package/dist/docs/reference/validator.mdx +12 -3
- package/dist/internal.d.ts +16 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +45 -0
- package/dist/internal.js.map +1 -0
- package/dist/{cli → lib}/resolve-aliases.d.ts.map +1 -1
- package/dist/{cli → lib}/resolve-aliases.js.map +1 -1
- package/dist/lib/start-command.d.ts +11 -0
- package/dist/lib/start-command.d.ts.map +1 -0
- package/dist/lib/start-command.js +79 -0
- package/dist/lib/start-command.js.map +1 -0
- package/dist/lib/start-server.js +4 -2
- package/dist/lib/start-server.js.map +1 -1
- package/dist/middleware/backpressure.d.ts +5 -0
- package/dist/middleware/backpressure.d.ts.map +1 -1
- package/dist/middleware/backpressure.js +66 -36
- package/dist/middleware/backpressure.js.map +1 -1
- package/dist/router/route-scanner.d.ts +12 -4
- package/dist/router/route-scanner.d.ts.map +1 -1
- package/dist/router/route-scanner.js +65 -51
- package/dist/router/route-scanner.js.map +1 -1
- package/dist/sanitize/index.d.ts +29 -3
- package/dist/sanitize/index.d.ts.map +1 -1
- package/dist/sanitize/index.js +91 -32
- package/dist/sanitize/index.js.map +1 -1
- package/dist/server/adapters/bun-adapter.d.ts +1 -1
- package/dist/server/adapters/bun-adapter.d.ts.map +1 -1
- package/dist/server/adapters/bun-adapter.js.map +1 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +24 -1
- package/dist/server/app.js.map +1 -1
- package/dist/server/bootstrapper.d.ts.map +1 -1
- package/dist/server/bootstrapper.js +4 -2
- package/dist/server/bootstrapper.js.map +1 -1
- package/dist/server/cluster.d.ts.map +1 -1
- package/dist/server/cluster.js +3 -0
- package/dist/server/cluster.js.map +1 -1
- package/dist/server/metrics.d.ts +43 -0
- package/dist/server/metrics.d.ts.map +1 -0
- package/dist/server/metrics.js +254 -0
- package/dist/server/metrics.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +31 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/validator/builder.d.ts +32 -17
- package/dist/validator/builder.d.ts.map +1 -1
- package/dist/validator/builder.js +84 -25
- package/dist/validator/builder.js.map +1 -1
- package/dist/validator/compile.d.ts +7 -2
- package/dist/validator/compile.d.ts.map +1 -1
- package/dist/validator/compile.js +85 -54
- package/dist/validator/compile.js.map +1 -1
- package/dist/validator/engine.d.ts +58 -7
- package/dist/validator/engine.d.ts.map +1 -1
- package/dist/validator/engine.js +436 -522
- package/dist/validator/engine.js.map +1 -1
- package/dist/validator/error.d.ts.map +1 -1
- package/dist/validator/error.js +7 -0
- package/dist/validator/error.js.map +1 -1
- package/dist/validator/index.d.ts +4 -1
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js +5 -1
- package/dist/validator/index.js.map +1 -1
- package/dist/validator/rules.d.ts +66 -7
- package/dist/validator/rules.d.ts.map +1 -1
- package/dist/validator/rules.js +435 -109
- package/dist/validator/rules.js.map +1 -1
- package/dist/validator/tex-types.d.ts +15 -0
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/dist/validator/tex-types.js +127 -64
- package/dist/validator/tex-types.js.map +1 -1
- package/dist/validator/tex.d.ts +1 -1
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/text.d.ts +2 -0
- package/dist/validator/text.d.ts.map +1 -1
- package/dist/validator/text.js +31 -13
- package/dist/validator/text.js.map +1 -1
- package/dist/validator/types.d.ts +22 -0
- package/dist/validator/types.d.ts.map +1 -1
- package/package.json +81 -9
- package/dist/cli/commands/build.d.ts +0 -11
- package/dist/cli/commands/build.d.ts.map +0 -1
- package/dist/cli/commands/build.js +0 -344
- package/dist/cli/commands/build.js.map +0 -1
- package/dist/cli/commands/clean.d.ts +0 -5
- package/dist/cli/commands/clean.d.ts.map +0 -1
- package/dist/cli/commands/clean.js +0 -30
- package/dist/cli/commands/clean.js.map +0 -1
- package/dist/cli/commands/dev.d.ts +0 -21
- package/dist/cli/commands/dev.d.ts.map +0 -1
- package/dist/cli/commands/dev.js +0 -842
- package/dist/cli/commands/dev.js.map +0 -1
- package/dist/cli/commands/doctor.d.ts +0 -2
- package/dist/cli/commands/doctor.d.ts.map +0 -1
- package/dist/cli/commands/doctor.js +0 -228
- package/dist/cli/commands/doctor.js.map +0 -1
- package/dist/cli/commands/exports.d.ts +0 -2
- package/dist/cli/commands/exports.d.ts.map +0 -1
- package/dist/cli/commands/exports.js +0 -48
- package/dist/cli/commands/exports.js.map +0 -1
- package/dist/cli/commands/generate.d.ts +0 -33
- package/dist/cli/commands/generate.d.ts.map +0 -1
- package/dist/cli/commands/generate.js +0 -469
- package/dist/cli/commands/generate.js.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -2
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -37
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/repl.d.ts +0 -6
- package/dist/cli/commands/repl.d.ts.map +0 -1
- package/dist/cli/commands/repl.js +0 -75
- package/dist/cli/commands/repl.js.map +0 -1
- package/dist/cli/commands/run.d.ts +0 -7
- package/dist/cli/commands/run.d.ts.map +0 -1
- package/dist/cli/commands/run.js +0 -101
- package/dist/cli/commands/run.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -8
- package/dist/cli/commands/start.d.ts.map +0 -1
- package/dist/cli/commands/start.js +0 -155
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/test.d.ts +0 -8
- package/dist/cli/commands/test.d.ts.map +0 -1
- package/dist/cli/commands/test.js +0 -165
- package/dist/cli/commands/test.js.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -268
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/manifest.d.ts +0 -4
- package/dist/cli/manifest.d.ts.map +0 -1
- package/dist/cli/manifest.js +0 -489
- package/dist/cli/manifest.js.map +0 -1
- package/dist/cli/routes.d.ts +0 -17
- package/dist/cli/routes.d.ts.map +0 -1
- package/dist/cli/routes.js +0 -317
- package/dist/cli/routes.js.map +0 -1
- package/dist/cli/utils.d.ts +0 -24
- package/dist/cli/utils.d.ts.map +0 -1
- package/dist/cli/utils.js +0 -54
- package/dist/cli/utils.js.map +0 -1
- package/dist/lib/inspect-routes.d.ts +0 -2
- package/dist/lib/inspect-routes.d.ts.map +0 -1
- package/dist/lib/inspect-routes.js +0 -150
- package/dist/lib/inspect-routes.js.map +0 -1
- package/dist/lib/start-repl.d.ts +0 -2
- package/dist/lib/start-repl.d.ts.map +0 -1
- package/dist/lib/start-repl.js +0 -120
- package/dist/lib/start-repl.js.map +0 -1
- package/dist/sanitize/sanitize.d.ts +0 -33
- package/dist/sanitize/sanitize.d.ts.map +0 -1
- package/dist/sanitize/sanitize.js +0 -104
- package/dist/sanitize/sanitize.js.map +0 -1
- /package/dist/{cli → lib}/resolve-aliases.d.ts +0 -0
- /package/dist/{cli → lib}/resolve-aliases.js +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startBuiltServer = startBuiltServer;
|
|
7
|
+
// `exisjs start`: boots a built app. It lives in the runtime, not in
|
|
8
|
+
// @exisjs/cli, so production installs without development dependencies can
|
|
9
|
+
// still run `exisjs start` (or `npm start`).
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
|
+
const node_url_1 = require("node:url");
|
|
13
|
+
const START_SERVER_PATH = node_path_1.default.join(__dirname, 'start-server.js');
|
|
14
|
+
// tsc compiles import() to require() for CommonJS; main.js may be ESM
|
|
15
|
+
const importModule = new Function('specifier', 'return import(specifier)');
|
|
16
|
+
/**
|
|
17
|
+
* Starts the built server in this process, so it receives SIGINT / SIGTERM
|
|
18
|
+
* itself and shuts down gracefully (the same as `node .exis/server/main.js`).
|
|
19
|
+
*/
|
|
20
|
+
async function startBuiltServer(options = {},
|
|
21
|
+
// Loads the server; tests pass a stub instead of starting one
|
|
22
|
+
load = importModule) {
|
|
23
|
+
const cwd = process.cwd();
|
|
24
|
+
if (options.port)
|
|
25
|
+
process.env.PORT = options.port;
|
|
26
|
+
if (options.host)
|
|
27
|
+
process.env.HOST = options.host;
|
|
28
|
+
process.env.NODE_ENV = 'production';
|
|
29
|
+
process.env.__EXIS_CLI = 'true';
|
|
30
|
+
const mainFile = node_path_1.default.join(cwd, '.exis', 'server', 'main.js');
|
|
31
|
+
if (!options.entry && node_fs_1.default.existsSync(mainFile)) {
|
|
32
|
+
await load((0, node_url_1.pathToFileURL)(mainFile).href);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Builds made before main.js existed, or a custom --entry
|
|
36
|
+
const entryFile = resolveDistEntry(cwd, options.entry);
|
|
37
|
+
if (!entryFile) {
|
|
38
|
+
console.error('\x1b[31m✗\x1b[0m No compiled output found. Run `exisjs build` first.');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
process.env.EXIS_ENTRY_FILE = entryFile;
|
|
42
|
+
await load((0, node_url_1.pathToFileURL)(START_SERVER_PATH).href);
|
|
43
|
+
}
|
|
44
|
+
function resolveDistEntry(cwd, custom) {
|
|
45
|
+
if (custom) {
|
|
46
|
+
const abs = node_path_1.default.resolve(cwd, custom);
|
|
47
|
+
return node_fs_1.default.existsSync(abs) ? abs : null;
|
|
48
|
+
}
|
|
49
|
+
const srcJs = node_path_1.default.join(cwd, '.exis/server/src/http/server.js');
|
|
50
|
+
const rootJs = node_path_1.default.join(cwd, '.exis/server/http/server.js');
|
|
51
|
+
const distSrcJs = node_path_1.default.join(cwd, 'dist/src/http/server.js');
|
|
52
|
+
const distRootJs = node_path_1.default.join(cwd, 'dist/http/server.js');
|
|
53
|
+
const rawSrcJs = node_path_1.default.join(cwd, 'src/http/server.js');
|
|
54
|
+
const rawRootJs = node_path_1.default.join(cwd, 'http/server.js');
|
|
55
|
+
const hasSrc = node_fs_1.default.existsSync(srcJs) || node_fs_1.default.existsSync(distSrcJs) || node_fs_1.default.existsSync(rawSrcJs);
|
|
56
|
+
const hasRoot = node_fs_1.default.existsSync(rootJs) ||
|
|
57
|
+
node_fs_1.default.existsSync(distRootJs) ||
|
|
58
|
+
node_fs_1.default.existsSync(rawRootJs);
|
|
59
|
+
if (hasSrc && hasRoot) {
|
|
60
|
+
console.error('\n\x1b[31m Ambiguous Entry Point Error\x1b[0m\n' +
|
|
61
|
+
'You have server entry files in both "src/http" and "http" directories.\n' +
|
|
62
|
+
'Please keep only one of them to prevent unexpected behavior.\n');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
if (node_fs_1.default.existsSync(srcJs))
|
|
66
|
+
return srcJs;
|
|
67
|
+
if (node_fs_1.default.existsSync(rootJs))
|
|
68
|
+
return rootJs;
|
|
69
|
+
if (node_fs_1.default.existsSync(distSrcJs))
|
|
70
|
+
return distSrcJs;
|
|
71
|
+
if (node_fs_1.default.existsSync(distRootJs))
|
|
72
|
+
return distRootJs;
|
|
73
|
+
if (node_fs_1.default.existsSync(rawSrcJs))
|
|
74
|
+
return rawSrcJs;
|
|
75
|
+
if (node_fs_1.default.existsSync(rawRootJs))
|
|
76
|
+
return rawRootJs;
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=start-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-command.js","sourceRoot":"","sources":["../../src/lib/start-command.ts"],"names":[],"mappings":";;;;;AAwBA,4CA4BC;AApDD,qEAAqE;AACrE,2EAA2E;AAC3E,6CAA6C;AAC7C,0DAA4B;AAC5B,sDAAwB;AACxB,uCAAwC;AAExC,MAAM,iBAAiB,GAAG,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;AAQjE,sEAAsE;AACtE,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAEpD,CAAA;AAErB;;;GAGG;AACI,KAAK,UAAU,gBAAgB,CACpC,UAAwB,EAAE;AAC1B,8DAA8D;AAC9D,OAAgD,YAAY;IAE5D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEzB,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACjD,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACjD,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,YAAY,CAAA;IACnC,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,MAAM,CAAA;IAE/B,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;IAC7D,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,iBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,CAAC,IAAA,wBAAa,EAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAA;QACxC,OAAM;IACR,CAAC;IAED,0DAA0D;IAC1D,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IACtD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,sEAAsE,CACvE,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,SAAS,CAAA;IACvC,MAAM,IAAI,CAAC,IAAA,wBAAa,EAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAA;AACnD,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,MAAe;IACpD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACrC,OAAO,iBAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,MAAM,KAAK,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAA;IAC/D,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,6BAA6B,CAAC,CAAA;IAC5D,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAA;IAC3D,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAA;IACrD,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;IAElD,MAAM,MAAM,GACV,iBAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,iBAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,iBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC7E,MAAM,OAAO,GACX,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QACrB,iBAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QACzB,iBAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IAE1B,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CACX,iDAAiD;YAC/C,0EAA0E;YAC1E,gEAAgE,CACnE,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,iBAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACtC,IAAI,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IACxC,IAAI,iBAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IAC9C,IAAI,iBAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAA;IAChD,IAAI,iBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC5C,IAAI,iBAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IAE9C,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/lib/start-server.js
CHANGED
|
@@ -71,7 +71,7 @@ async function start() {
|
|
|
71
71
|
loadEnv(cwd);
|
|
72
72
|
// Register path aliases loader
|
|
73
73
|
try {
|
|
74
|
-
const { registerPathAliasLoader } = await Promise.resolve().then(() => __importStar(require('
|
|
74
|
+
const { registerPathAliasLoader } = await Promise.resolve().then(() => __importStar(require('./resolve-aliases.js')));
|
|
75
75
|
registerPathAliasLoader(cwd);
|
|
76
76
|
}
|
|
77
77
|
catch {
|
|
@@ -188,7 +188,9 @@ async function start() {
|
|
|
188
188
|
return;
|
|
189
189
|
isShuttingDown = true;
|
|
190
190
|
clearInterval(memMonitor);
|
|
191
|
-
|
|
191
|
+
// The dev server's parent prints its own messages; `exisjs start`
|
|
192
|
+
// and main.js run the server themselves, so it reports here
|
|
193
|
+
const isCLI = process.env.__EXIS_DEV_SERVER;
|
|
192
194
|
if (!isCLI) {
|
|
193
195
|
console.error(`\n[exis] ${signal} received. Shutting down gracefully...`);
|
|
194
196
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-server.js","sourceRoot":"","sources":["../../src/lib/start-server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAAwB;AACxB,uCAAwC;AACxC,qDAAmD;AACnD,2DAA0D;AAE1D,KAAK,UAAU,KAAK;IAClB,2EAA2E;IAC3E,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAClC,MAAM,KAAK,GAAG,iBAAE,CAAC,iBAAiB,EAAE,CAAA;QACpC,IAAI,KAAK,CAAC,cAAc,GAAG,GAAG,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;YACvD,OAAO,CAAC,KAAK,CACX,6EAA6E,CAC9E,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAC,+BAA+B;QACnD,CAAC;IACH,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA,CAAC,6BAA6B;IAE/C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAA;IAE7C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAA;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,gBAAgB,EAAE,GAAG,wDAAa,wBAAwB,GAAC,CAAA;QACnE,gBAAgB,CAAC,aAAa,EAAE,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,wDAAa,SAAS,GAAC,CAAA;QAClC,MAAM,IAAI,GAAG,wDAAa,WAAW,GAAC,CAAA;QACtC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;QAEzB,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAA;QAE3E,iDAAiD;QACjD,MAAM,EAAE,OAAO,EAAE,GAAG,wDAAa,kBAAkB,GAAC,CAAA;QACpD,OAAO,CAAC,GAAG,CAAC,CAAA;QAEZ,+BAA+B;QAC/B,IAAI,CAAC;YACH,MAAM,EAAE,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"start-server.js","sourceRoot":"","sources":["../../src/lib/start-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,4 +8,9 @@ export interface BackpressureOptions {
|
|
|
8
8
|
timeoutMs?: number;
|
|
9
9
|
}
|
|
10
10
|
export declare function backpressureMiddleware(options?: BackpressureOptions): Handler;
|
|
11
|
+
/**
|
|
12
|
+
* Checks the `queue` config and returns the backpressure options it asks
|
|
13
|
+
* for. Throws at start-up on anything the framework would otherwise ignore.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveQueueConfig(queue: unknown): BackpressureOptions | undefined;
|
|
11
16
|
//# sourceMappingURL=backpressure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backpressure.d.ts","sourceRoot":"","sources":["../../src/middleware/backpressure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAmC,MAAM,UAAU,CAAA;AAGxE,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,mBAAwB,GAChC,OAAO,
|
|
1
|
+
{"version":3,"file":"backpressure.d.ts","sourceRoot":"","sources":["../../src/middleware/backpressure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAmC,MAAM,UAAU,CAAA;AAGxE,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAmET;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,GACb,mBAAmB,GAAG,SAAS,CAqCjC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.backpressureMiddleware = backpressureMiddleware;
|
|
4
|
+
exports.resolveQueueConfig = resolveQueueConfig;
|
|
4
5
|
const errors_1 = require("../error/errors");
|
|
5
6
|
function backpressureMiddleware(options = {}) {
|
|
6
7
|
const maxConcurrent = options.maxConcurrent ?? 1000;
|
|
@@ -8,57 +9,86 @@ function backpressureMiddleware(options = {}) {
|
|
|
8
9
|
const timeoutMs = options.timeoutMs ?? 10000;
|
|
9
10
|
let activeCount = 0;
|
|
10
11
|
const queue = [];
|
|
12
|
+
// 'close' fires once for every response: finished, streamed or aborted.
|
|
13
|
+
// Counting on res.end() alone leaked a slot for each of the other two.
|
|
14
|
+
const start = (res, next) => {
|
|
15
|
+
activeCount++;
|
|
16
|
+
res.raw.once('close', () => {
|
|
17
|
+
activeCount--;
|
|
18
|
+
process.nextTick(processNext);
|
|
19
|
+
});
|
|
20
|
+
next();
|
|
21
|
+
};
|
|
11
22
|
const processNext = () => {
|
|
12
|
-
|
|
23
|
+
while (activeCount < maxConcurrent && queue.length > 0) {
|
|
13
24
|
const queued = queue.shift();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
process.nextTick(processNext);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
activeCount++;
|
|
22
|
-
// Use _onFinish to decrement activeCount when done
|
|
23
|
-
queued.res._onFinish.push(() => {
|
|
24
|
-
activeCount--;
|
|
25
|
-
process.nextTick(processNext);
|
|
26
|
-
});
|
|
27
|
-
queued.next();
|
|
28
|
-
}
|
|
25
|
+
clearTimeout(queued.timer);
|
|
26
|
+
if (queued.isCancelled)
|
|
27
|
+
continue;
|
|
28
|
+
start(queued.res, queued.next);
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
return (req, res, next) => {
|
|
32
|
-
if (activeCount < maxConcurrent)
|
|
33
|
-
|
|
34
|
-
res._onFinish.push(() => {
|
|
35
|
-
activeCount--;
|
|
36
|
-
process.nextTick(processNext);
|
|
37
|
-
});
|
|
38
|
-
return next();
|
|
39
|
-
}
|
|
32
|
+
if (activeCount < maxConcurrent)
|
|
33
|
+
return start(res, next);
|
|
40
34
|
// Capacity reached, queue the request
|
|
41
35
|
if (queue.length >= maxQueue) {
|
|
42
|
-
// Return 503 Service Unavailable immediately
|
|
43
36
|
return next(errors_1.HttpError.serviceUnavailable('Server is at capacity. Please try again later.'));
|
|
44
37
|
}
|
|
45
38
|
const queuedReq = {
|
|
46
|
-
req,
|
|
47
39
|
res,
|
|
48
40
|
next,
|
|
49
|
-
timer:
|
|
41
|
+
timer: setTimeout(() => {
|
|
42
|
+
queuedReq.isCancelled = true;
|
|
43
|
+
next(errors_1.HttpError.serviceUnavailable('Request timed out in queue.'));
|
|
44
|
+
}, timeoutMs),
|
|
50
45
|
isCancelled: false,
|
|
51
46
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
47
|
+
queuedReq.timer.unref?.();
|
|
48
|
+
// A client that gives up while waiting frees its place in the queue
|
|
49
|
+
res.raw.once('close', () => {
|
|
50
|
+
if (!queuedReq.isCancelled) {
|
|
51
|
+
queuedReq.isCancelled = true;
|
|
52
|
+
clearTimeout(queuedReq.timer);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
61
55
|
queue.push(queuedReq);
|
|
62
56
|
};
|
|
63
57
|
}
|
|
58
|
+
const QUEUE_KEYS = ['driver', 'maxConcurrent', 'maxQueue', 'timeoutMs'];
|
|
59
|
+
/**
|
|
60
|
+
* Checks the `queue` config and returns the backpressure options it asks
|
|
61
|
+
* for. Throws at start-up on anything the framework would otherwise ignore.
|
|
62
|
+
*/
|
|
63
|
+
function resolveQueueConfig(queue) {
|
|
64
|
+
if (queue === undefined || queue === null || queue === false)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (typeof queue !== 'object' || Array.isArray(queue)) {
|
|
67
|
+
throw new TypeError(`[ExisJS Config] queue must be an object, got ${Array.isArray(queue) ? 'an array' : typeof queue}`);
|
|
68
|
+
}
|
|
69
|
+
const q = queue;
|
|
70
|
+
for (const key of Object.keys(q)) {
|
|
71
|
+
if (!QUEUE_KEYS.includes(key)) {
|
|
72
|
+
throw new TypeError(`[ExisJS Config] Unknown option queue.${key}. Supported: ${QUEUE_KEYS.join(', ')}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (q.driver !== undefined && q.driver !== 'memory') {
|
|
76
|
+
throw new TypeError(`[ExisJS Config] queue.driver "${String(q.driver)}" is not supported. ` +
|
|
77
|
+
'The only driver is "memory": requests over queue.maxConcurrent wait ' +
|
|
78
|
+
'in this process and are lost if it stops. Remove queue.driver, or ' +
|
|
79
|
+
'set it to "memory".');
|
|
80
|
+
}
|
|
81
|
+
for (const key of ['maxConcurrent', 'maxQueue', 'timeoutMs']) {
|
|
82
|
+
const v = q[key];
|
|
83
|
+
const min = key === 'maxQueue' ? 0 : 1;
|
|
84
|
+
if (v !== undefined && !(Number.isInteger(v) && v >= min)) {
|
|
85
|
+
throw new TypeError(`[ExisJS Config] queue.${key} must be an integer >= ${min}, got ${JSON.stringify(v)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
maxConcurrent: q.maxConcurrent,
|
|
90
|
+
maxQueue: q.maxQueue,
|
|
91
|
+
timeoutMs: q.timeoutMs,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
64
94
|
//# sourceMappingURL=backpressure.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backpressure.js","sourceRoot":"","sources":["../../src/middleware/backpressure.ts"],"names":[],"mappings":";;AAYA,
|
|
1
|
+
{"version":3,"file":"backpressure.js","sourceRoot":"","sources":["../../src/middleware/backpressure.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,12 +3,17 @@ import { Router } from '../router/router';
|
|
|
3
3
|
/** Which controller style a route module exports, if any. */
|
|
4
4
|
export declare function routeParadigm(mod: any): 'oop' | 'functional' | null;
|
|
5
5
|
export declare function mixedParadigmMessage(oopFiles: string[], functionalFiles: string[]): string;
|
|
6
|
+
interface LazyRoute {
|
|
7
|
+
filePath: string;
|
|
8
|
+
loaded: boolean;
|
|
9
|
+
/** Shared by every request that arrives while the file is being mounted */
|
|
10
|
+
loading?: Promise<void>;
|
|
11
|
+
/** Module already imported by the startup paradigm check, used for the first mount */
|
|
12
|
+
preloaded?: any;
|
|
13
|
+
}
|
|
6
14
|
export declare class RouteScanner {
|
|
7
15
|
app: App;
|
|
8
|
-
lazyRoutes: Map<string,
|
|
9
|
-
filePath: string;
|
|
10
|
-
loaded: boolean;
|
|
11
|
-
}>;
|
|
16
|
+
lazyRoutes: Map<string, LazyRoute>;
|
|
12
17
|
routeMap: Map<string, string>;
|
|
13
18
|
apiDir: string | null;
|
|
14
19
|
_allApiDirs?: string[];
|
|
@@ -16,6 +21,8 @@ export declare class RouteScanner {
|
|
|
16
21
|
globalParadigm: 'oop' | 'functional' | null;
|
|
17
22
|
constructor(app: App);
|
|
18
23
|
loadAllRoutes(): Promise<void>;
|
|
24
|
+
/** Mounts a lazily registered route file once; concurrent callers share the same load. */
|
|
25
|
+
private loadLazyRoute;
|
|
19
26
|
autoMountRoutes(root: string): Promise<void>;
|
|
20
27
|
private mountDocs;
|
|
21
28
|
mountRouteFile(filePath: string, routePath: string, preloaded?: any): Promise<void>;
|
|
@@ -30,4 +37,5 @@ export declare class RouteScanner {
|
|
|
30
37
|
module: any;
|
|
31
38
|
}[]): void;
|
|
32
39
|
}
|
|
40
|
+
export {};
|
|
33
41
|
//# sourceMappingURL=route-scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-scanner.d.ts","sourceRoot":"","sources":["../../src/router/route-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAkBzC,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,KAAK,GAAG,YAAY,GAAG,IAAI,CAgBnE;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAAE,EAClB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAYR;AAED,qBAAa,YAAY;IAQJ,GAAG,EAAE,GAAG;IAPpB,UAAU
|
|
1
|
+
{"version":3,"file":"route-scanner.d.ts","sourceRoot":"","sources":["../../src/router/route-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAkBzC,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,KAAK,GAAG,YAAY,GAAG,IAAI,CAgBnE;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAAE,EAClB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAYR;AAED,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,sFAAsF;IACtF,SAAS,CAAC,EAAE,GAAG,CAAA;CAChB;AAoBD,qBAAa,YAAY;IAQJ,GAAG,EAAE,GAAG;IAPpB,UAAU,yBAA+B;IACzC,QAAQ,sBAA4B;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAO;IAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,UAAQ;IACrB,cAAc,EAAE,KAAK,GAAG,YAAY,GAAG,IAAI,CAAO;gBAEtC,GAAG,EAAE,GAAG;IAErB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAepC,0FAA0F;IAC1F,OAAO,CAAC,aAAa;IAuBR,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAsO3C,SAAS;IAkBjB,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,GAAG,GACd,OAAO,CAAC,IAAI,CAAC;IAiOT,2BAA2B,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM;IAIhD,oBAAoB,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,iBAAiB,GAAE,GAAG,EAAO,GAC5B,IAAI;IAsBA,2BAA2B,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,SAAa,GAAG,IAAI;YAI5D,iBAAiB;YAIjB,aAAa;IAOd,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,wBAAwB,CAC7B,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,EAAE,GAC3C,IAAI;CAGR"}
|
|
@@ -68,6 +68,15 @@ function mixedParadigmMessage(oopFiles, functionalFiles) {
|
|
|
68
68
|
`Functional controllers found in:\n${formatFiles(functionalFiles)}\n\n` +
|
|
69
69
|
`Fix: Choose one paradigm and update the files to match.`);
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Outside development a route that cannot load stops the start: a server
|
|
73
|
+
* missing part of its API must not report healthy and take traffic.
|
|
74
|
+
*/
|
|
75
|
+
function routeLoadError(file, err) {
|
|
76
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
77
|
+
return Object.assign(new Error(`[ExisJS] ${file} failed to load, so the server will not start: ${reason}`), { cause: err });
|
|
78
|
+
}
|
|
79
|
+
const importModule = new Function('specifier', 'return import(specifier)');
|
|
71
80
|
class RouteScanner {
|
|
72
81
|
constructor(app) {
|
|
73
82
|
this.app = app;
|
|
@@ -78,29 +87,45 @@ class RouteScanner {
|
|
|
78
87
|
this.globalParadigm = null;
|
|
79
88
|
}
|
|
80
89
|
async loadAllRoutes() {
|
|
81
|
-
for (const
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
catch (e) {
|
|
91
|
-
this.app.log.error({ err: e, file: entry.filePath }, 'Failed to eager-load route');
|
|
92
|
-
}
|
|
93
|
-
}
|
|
90
|
+
for (const entry of this.lazyRoutes.values()) {
|
|
91
|
+
if (entry.loaded)
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
await this.loadLazyRoute(entry);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// The placeholder stays, so the first request retries and reports the error
|
|
98
|
+
this.app.log.error({ err: e, file: entry.filePath }, 'Failed to eager-load route');
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
101
|
}
|
|
102
|
+
/** Mounts a lazily registered route file once; concurrent callers share the same load. */
|
|
103
|
+
loadLazyRoute(entry) {
|
|
104
|
+
entry.loading ?? (entry.loading = (async () => {
|
|
105
|
+
const router = this.app.getRouter();
|
|
106
|
+
const preloaded = entry.preloaded;
|
|
107
|
+
entry.preloaded = undefined;
|
|
108
|
+
try {
|
|
109
|
+
// Real routes go in before the placeholder leaves, so no request finds neither
|
|
110
|
+
await this.mountRouteFile(entry.filePath, this.routeMap.get(entry.filePath), preloaded);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
router.removeRoutesBySource(entry.filePath); // drop a partial mount
|
|
114
|
+
entry.loading = undefined; // the next request tries again
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
router.removeRoutesBySource('lazy:' + entry.filePath);
|
|
118
|
+
entry.loaded = true;
|
|
119
|
+
})());
|
|
120
|
+
return entry.loading;
|
|
121
|
+
}
|
|
97
122
|
async autoMountRoutes(root) {
|
|
98
123
|
const fs = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
|
|
99
124
|
const path = await Promise.resolve().then(() => __importStar(require('node:path')));
|
|
100
125
|
const isProd = process.env.NODE_ENV === 'production';
|
|
101
126
|
const isDev = this.app.options.env === 'development';
|
|
102
127
|
try {
|
|
103
|
-
const { registerPathAliasLoader } = await Promise.resolve().then(() => __importStar(require('../
|
|
128
|
+
const { registerPathAliasLoader } = await Promise.resolve().then(() => __importStar(require('../lib/resolve-aliases.js')));
|
|
104
129
|
registerPathAliasLoader(root);
|
|
105
130
|
}
|
|
106
131
|
catch {
|
|
@@ -125,22 +150,17 @@ class RouteScanner {
|
|
|
125
150
|
let url = (0, node_url_1.pathToFileURL)(manifestPath).href;
|
|
126
151
|
if (!isProd)
|
|
127
152
|
url += '?t=' + Date.now(); // cache bust for dev
|
|
128
|
-
|
|
129
|
-
if (process.env.VITEST || process.env.NODE_ENV === 'test') {
|
|
130
|
-
mod = await Promise.resolve(`${url}`).then(s => __importStar(require(s)));
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
const dynamicImport = new Function('specifier', 'return import(specifier)');
|
|
134
|
-
mod = await dynamicImport(url);
|
|
135
|
-
}
|
|
153
|
+
const mod = await importModule(url);
|
|
136
154
|
manifest = mod.manifest;
|
|
137
155
|
manifestErrorHandler = mod.errorHandler;
|
|
138
156
|
manifestCronJobs = mod.cronJobs;
|
|
139
157
|
}
|
|
140
158
|
}
|
|
141
159
|
catch (err) {
|
|
160
|
+
// The manifest imports every route; one that throws (a missing
|
|
161
|
+
// environment value, say) means the app cannot run as built
|
|
142
162
|
if (err.code !== 'ENOENT') {
|
|
143
|
-
|
|
163
|
+
throw routeLoadError('the routes manifest', err);
|
|
144
164
|
}
|
|
145
165
|
}
|
|
146
166
|
}
|
|
@@ -180,8 +200,7 @@ class RouteScanner {
|
|
|
180
200
|
await this.mountRouteFile(normalizedPath, routePath, routeMod);
|
|
181
201
|
}
|
|
182
202
|
catch (err) {
|
|
183
|
-
|
|
184
|
-
this.app.log.error({ err, file: filePath }, `Failed to load route file: ${filePath}`);
|
|
203
|
+
throw routeLoadError(filePath, err);
|
|
185
204
|
}
|
|
186
205
|
}
|
|
187
206
|
await this.mountDocs();
|
|
@@ -226,27 +245,19 @@ class RouteScanner {
|
|
|
226
245
|
this.routeMap.set(normalized, routePath);
|
|
227
246
|
if (isDev) {
|
|
228
247
|
const lazyKey = normalized;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
loaded: false,
|
|
232
|
-
});
|
|
248
|
+
const entry = { filePath: normalized, loaded: false };
|
|
249
|
+
this.lazyRoutes.set(lazyKey, entry);
|
|
233
250
|
const lazyHandler = async (req, res, next) => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
entry.loaded = true;
|
|
237
|
-
this.app.getRouter().removeRoutesBySource('lazy:' + lazyKey);
|
|
238
|
-
try {
|
|
239
|
-
await this.mountRouteFile(normalized, routePath);
|
|
240
|
-
}
|
|
241
|
-
catch (err) {
|
|
242
|
-
(0, overlay_1.formatDevError)(err, normalized);
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
await this.app.getRouter().handle(req, res, next);
|
|
251
|
+
try {
|
|
252
|
+
await this.loadLazyRoute(entry);
|
|
246
253
|
}
|
|
247
|
-
|
|
248
|
-
|
|
254
|
+
catch (err) {
|
|
255
|
+
(0, overlay_1.formatDevError)(err, normalized);
|
|
256
|
+
if (next)
|
|
257
|
+
return next(err);
|
|
258
|
+
throw err;
|
|
249
259
|
}
|
|
260
|
+
await this.app.getRouter().handle(req, res, next);
|
|
250
261
|
};
|
|
251
262
|
const lazyRouter = new router_1.Router();
|
|
252
263
|
lazyRouter.all(routePath, lazyHandler);
|
|
@@ -261,7 +272,7 @@ class RouteScanner {
|
|
|
261
272
|
await this.mountRouteFile(normalized, routePath);
|
|
262
273
|
}
|
|
263
274
|
catch (err) {
|
|
264
|
-
|
|
275
|
+
throw routeLoadError(path.relative(root, filePath), err);
|
|
265
276
|
}
|
|
266
277
|
}
|
|
267
278
|
}
|
|
@@ -280,6 +291,10 @@ class RouteScanner {
|
|
|
280
291
|
try {
|
|
281
292
|
const url = (0, node_url_1.pathToFileURL)(file).href;
|
|
282
293
|
const mod = await dynamicImport(url);
|
|
294
|
+
// Reused for the first mount so the file's top level runs only once
|
|
295
|
+
const entry = this.lazyRoutes.get(file);
|
|
296
|
+
if (entry && !entry.loaded)
|
|
297
|
+
entry.preloaded = mod;
|
|
283
298
|
const paradigm = routeParadigm(mod);
|
|
284
299
|
if (paradigm === 'functional')
|
|
285
300
|
functionalFiles.push(file);
|
|
@@ -299,6 +314,9 @@ class RouteScanner {
|
|
|
299
314
|
else if (functionalFiles.length > 0)
|
|
300
315
|
this.globalParadigm = 'functional';
|
|
301
316
|
}
|
|
317
|
+
if (isDev && this.app.options.dev?.lazyRoutes === false) {
|
|
318
|
+
await this.loadAllRoutes();
|
|
319
|
+
}
|
|
302
320
|
if (!this.hasBoundaries && !isProd) {
|
|
303
321
|
this.app.log.warn('No boundary.ts found — applying default security headers.');
|
|
304
322
|
}
|
|
@@ -324,13 +342,9 @@ class RouteScanner {
|
|
|
324
342
|
const url = process.env.VITEST || process.env.NODE_ENV === 'test'
|
|
325
343
|
? (0, node_url_1.pathToFileURL)(filePath).href
|
|
326
344
|
: (0, node_url_1.pathToFileURL)(filePath).href + '?t=' + Date.now();
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
else {
|
|
331
|
-
const dynamicImport = new Function('specifier', 'return import(specifier)');
|
|
332
|
-
mod = await dynamicImport(url);
|
|
333
|
-
}
|
|
345
|
+
// A real import(): tsc turns `import()` into require() for CommonJS,
|
|
346
|
+
// which loads a second copy of modules a test imports as ESM
|
|
347
|
+
mod = await importModule(url);
|
|
334
348
|
}
|
|
335
349
|
catch {
|
|
336
350
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|