@zintrust/core 0.4.14 → 0.4.16
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/package.json +1 -1
- package/src/boot/bootstrap.js +5 -3
- package/src/boot/registry/registerRoute.d.ts.map +1 -1
- package/src/boot/registry/registerRoute.js +35 -19
- package/src/cli/PromptHelper.d.ts.map +1 -1
- package/src/cli/PromptHelper.js +1 -0
- package/src/cli/commands/AddCommand.d.ts +4 -0
- package/src/cli/commands/AddCommand.d.ts.map +1 -1
- package/src/cli/commands/AddCommand.js +119 -4
- package/src/cli/commands/NewCommand.d.ts +1 -1
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +4 -1
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +32 -3
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +1 -0
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +2 -0
- package/src/config/middleware.d.ts +4 -1
- package/src/config/middleware.d.ts.map +1 -1
- package/src/config/middleware.js +24 -1
- package/src/index.js +3 -3
- package/src/microservices/ServiceManifest.d.ts +1 -0
- package/src/microservices/ServiceManifest.d.ts.map +1 -1
- package/src/microservices/ServiceManifest.js +5 -0
- package/src/middleware/CsrfMiddleware.d.ts +1 -1
- package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
- package/src/runtime/ProjectRuntime.d.ts.map +1 -1
- package/src/runtime/ProjectRuntime.js +21 -11
- package/src/runtime/WorkerAdapterImports.d.ts.map +1 -1
- package/src/runtime/WorkerAdapterImports.js +17 -0
- package/src/runtime/WorkersModule.d.ts.map +1 -1
- package/src/runtime/WorkersModule.js +46 -8
- package/src/templates/project/basic/config/middleware.ts.tpl +18 -5
- package/src/templates/project/basic/src/zintrust.plugins.wg.ts.tpl +5 -0
package/package.json
CHANGED
package/src/boot/bootstrap.js
CHANGED
|
@@ -199,9 +199,11 @@ const BootstrapFunctions = Object.freeze({
|
|
|
199
199
|
// (This is driven by src/zintrust.plugins.ts generated by `zin plugin install`.)
|
|
200
200
|
try {
|
|
201
201
|
const { PluginAutoImports } = await import('../runtime/PluginAutoImports.js');
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
if (appConfig.dockerWorker === true) {
|
|
203
|
+
const officialImports = await PluginAutoImports.tryImportRuntimeAutoImports('base');
|
|
204
|
+
if (!officialImports.ok) {
|
|
205
|
+
Logger.warn('Official plugin auto-imports failed:', ErrorFactory.createGeneralError('officialImports', officialImports.errorMessage));
|
|
206
|
+
}
|
|
205
207
|
}
|
|
206
208
|
const projectImports = await PluginAutoImports.tryImportProjectAutoImports();
|
|
207
209
|
if (!projectImports.ok && projectImports.reason !== 'not-found') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerRoute.d.ts","sourceRoot":"","sources":["../../../../src/boot/registry/registerRoute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAc3D,eAAO,MAAM,kBAAkB,QAAO,OAKrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAMpF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAOrF,CAAC;
|
|
1
|
+
{"version":3,"file":"registerRoute.d.ts","sourceRoot":"","sources":["../../../../src/boot/registry/registerRoute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAc3D,eAAO,MAAM,kBAAkB,QAAO,OAKrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAMpF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAOrF,CAAC;AA2LF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,MAAM,EACxB,QAAQ,OAAO,KACd,OAAO,CAAC,IAAI,CAqBd,CAAC"}
|
|
@@ -89,6 +89,8 @@ const resolveServicePrefix = (entry) => {
|
|
|
89
89
|
const ensureManifestServiceEnvLoaded = async (entry) => {
|
|
90
90
|
if (isCloudflare)
|
|
91
91
|
return;
|
|
92
|
+
if (entry.loadEnv === false)
|
|
93
|
+
return;
|
|
92
94
|
const { EnvFileLoader } = await import('../../cli/utils/EnvFileLoader.js');
|
|
93
95
|
const projectRoot = getProjectRoot();
|
|
94
96
|
const envPath = resolveManifestServiceEnvDir(projectRoot, entry);
|
|
@@ -98,6 +100,35 @@ const ensureManifestServiceEnvLoaded = async (entry) => {
|
|
|
98
100
|
envPaths: [envPath],
|
|
99
101
|
});
|
|
100
102
|
};
|
|
103
|
+
const shouldRegisterManifestEntry = (entry, activeService) => {
|
|
104
|
+
if (entry.monolithEnabled === false || typeof entry.loadRoutes !== 'function') {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
if (activeService !== undefined && activeService.id !== entry.id) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
};
|
|
112
|
+
const loadRuntimeManifest = async () => {
|
|
113
|
+
if (isCloudflare) {
|
|
114
|
+
await ProjectRuntime.tryLoadWorkerRuntime();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
await ProjectRuntime.tryLoadNodeRuntime();
|
|
118
|
+
};
|
|
119
|
+
const registerManifestEntryRoutes = async (router, entry, activeService) => {
|
|
120
|
+
try {
|
|
121
|
+
await ensureManifestServiceEnvLoaded(entry);
|
|
122
|
+
const mod = await entry.loadRoutes?.();
|
|
123
|
+
const registerRoutes = isObject(mod) ? mod.registerRoutes : undefined;
|
|
124
|
+
if (typeof registerRoutes === 'function') {
|
|
125
|
+
registerLoadedRoutes(router, entry, registerRoutes, activeService);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
Logger.warn(`Failed to register manifest routes for ${entry.id}`, error);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
101
132
|
const registerLoadedRoutes = (router, entry, registerRoutes, activeService) => {
|
|
102
133
|
const servicePrefix = resolveServicePrefix(entry);
|
|
103
134
|
if (activeService?.id === entry.id) {
|
|
@@ -109,7 +140,7 @@ const registerLoadedRoutes = (router, entry, registerRoutes, activeService) => {
|
|
|
109
140
|
});
|
|
110
141
|
};
|
|
111
142
|
const registerManifestRoutes = async (router) => {
|
|
112
|
-
await
|
|
143
|
+
await loadRuntimeManifest();
|
|
113
144
|
const serviceManifest = ProjectRuntime.getServiceManifest();
|
|
114
145
|
if (serviceManifest.length === 0)
|
|
115
146
|
return;
|
|
@@ -117,25 +148,10 @@ const registerManifestRoutes = async (router) => {
|
|
|
117
148
|
if (activeService !== undefined && isCloudflare)
|
|
118
149
|
return;
|
|
119
150
|
for (const entry of serviceManifest) {
|
|
120
|
-
if (entry
|
|
151
|
+
if (!shouldRegisterManifestEntry(entry, activeService))
|
|
121
152
|
continue;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
// eslint-disable-next-line no-await-in-loop
|
|
128
|
-
await ensureManifestServiceEnvLoaded(entry);
|
|
129
|
-
// eslint-disable-next-line no-await-in-loop
|
|
130
|
-
const mod = await entry.loadRoutes();
|
|
131
|
-
const registerRoutes = isObject(mod) ? mod.registerRoutes : undefined;
|
|
132
|
-
if (typeof registerRoutes === 'function') {
|
|
133
|
-
registerLoadedRoutes(router, entry, registerRoutes, activeService);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
Logger.warn(`Failed to register manifest routes for ${entry.id}`, error);
|
|
138
|
-
}
|
|
153
|
+
// eslint-disable-next-line no-await-in-loop
|
|
154
|
+
await registerManifestEntryRoutes(router, entry, activeService);
|
|
139
155
|
}
|
|
140
156
|
};
|
|
141
157
|
const registerFrameworkRoutes = async (resolvedBasePath, router) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptHelper.d.ts","sourceRoot":"","sources":["../../../src/cli/PromptHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;sBACqB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMlE;;OAEG;8BAC6B,MAAM,gBAAe,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAuBrF;;OAEG;6BAEU,MAAM,gBACJ,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"PromptHelper.d.ts","sourceRoot":"","sources":["../../../src/cli/PromptHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;sBACqB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMlE;;OAEG;8BAC6B,MAAM,gBAAe,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAuBrF;;OAEG;6BAEU,MAAM,gBACJ,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;IAwBlB;;OAEG;uBACqB,MAAM,gBAAsB,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAqBpF;;OAEG;uCAEkB,MAAM,EAAE,gBACd,OAAO,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBpB;;OAEG;qBAEQ,MAAM,mBACC,OAAO,gBACV,OAAO,GACnB,OAAO,CAAC,OAAO,CAAC;IAiBnB;;OAEG;wBAEQ,MAAM,WACN,MAAM,EAAE,kBACF,MAAM,gBACR,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;IAkBlB;;OAEG;uBAEQ,MAAM,iBACD,MAAM,gBACP,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;EAgBlB,CAAC"}
|
package/src/cli/PromptHelper.js
CHANGED
|
@@ -54,6 +54,7 @@ export const PromptHelper = Object.freeze({
|
|
|
54
54
|
{ name: 'PostgreSQL — Production-ready relational DB', value: 'postgresql' },
|
|
55
55
|
{ name: 'MySQL — Production-ready relational DB', value: 'mysql' },
|
|
56
56
|
{ name: 'SQLite — Local dev (file-based)', value: 'sqlite' },
|
|
57
|
+
{ name: 'd1 — Cloudflare D1 database', value: 'd1' },
|
|
57
58
|
{ name: 'd1-proxy — Cloudflare D1 via HTTPS proxy', value: 'd1-remote' },
|
|
58
59
|
],
|
|
59
60
|
default: defaultDb,
|
|
@@ -32,6 +32,9 @@ interface ControllerPromptAnswers {
|
|
|
32
32
|
interface RoutesPromptAnswers {
|
|
33
33
|
name: string;
|
|
34
34
|
}
|
|
35
|
+
interface MiddlewarePromptAnswers {
|
|
36
|
+
name: string;
|
|
37
|
+
}
|
|
35
38
|
interface FactoryPromptAnswers {
|
|
36
39
|
name: string;
|
|
37
40
|
model: string;
|
|
@@ -80,6 +83,7 @@ export declare const AddCommand: Readonly<{
|
|
|
80
83
|
promptModelConfig: () => Promise<ModelPromptAnswers>;
|
|
81
84
|
promptControllerConfig: () => Promise<ControllerPromptAnswers>;
|
|
82
85
|
promptRoutesConfig: () => Promise<RoutesPromptAnswers>;
|
|
86
|
+
promptMiddlewareConfig: () => Promise<MiddlewarePromptAnswers>;
|
|
83
87
|
promptFactoryConfig: () => Promise<FactoryPromptAnswers>;
|
|
84
88
|
promptSeederConfig: () => Promise<SeederPromptAnswers>;
|
|
85
89
|
promptRequestFactoryConfig: () => Promise<RequestFactoryPromptAnswers>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/AddCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAarE,OAAO,KAAK,EAEV,aAAa,EACd,MAAM,2CAA2C,CAAC;AAwCnD,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC;IAChC,IAAI,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;CAC7C;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,uBAAuB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,2BAA2B;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,4BAA4B;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"AddCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/AddCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,8 +24,8 @@ import { PluginManager } from '../../runtime/PluginManager.js';
|
|
|
24
24
|
import inquirer from 'inquirer';
|
|
25
25
|
const addOptions = (command) => {
|
|
26
26
|
command
|
|
27
|
-
.argument('<type>', 'What to add: service, feature, migration, model, controller, routes, factory, seeder, requestfactory, responsefactory, workflow, or governance')
|
|
28
|
-
.argument('[name]', 'Name of service/feature/migration/model/controller/factory/seeder/requestfactory/responsefactory/workflow (governance takes no name)')
|
|
27
|
+
.argument('<type>', 'What to add: service, feature, migration, model, controller, routes, middleware, factory, seeder, requestfactory, responsefactory, workflow, or governance')
|
|
28
|
+
.argument('[name]', 'Name of service/feature/migration/model/controller/middleware/factory/seeder/requestfactory/responsefactory/workflow (governance takes no name)')
|
|
29
29
|
.option('--package-manager <pm>', 'Specify package manager to use when installing plugins (npm|yarn|pnpm)')
|
|
30
30
|
.option('--domain <name>', 'Service domain (e.g., ecommerce, payments) - for services')
|
|
31
31
|
.option('--database <type>', 'Database (shared|isolated) - for services')
|
|
@@ -369,6 +369,119 @@ const addRoutes = async (cmd, routeName, opts) => {
|
|
|
369
369
|
cmd.info(`File: ${path.basename(result.routeFile)}`);
|
|
370
370
|
cmd.info(`\nNext steps:\n • Add route definitions\n • Import controllers\n • Register in main router`);
|
|
371
371
|
};
|
|
372
|
+
const promptMiddlewareConfig = async () => {
|
|
373
|
+
return inquirer.prompt([
|
|
374
|
+
{
|
|
375
|
+
type: 'input',
|
|
376
|
+
name: 'name',
|
|
377
|
+
message: 'Middleware name (PascalCase, e.g., AuthMiddleware):',
|
|
378
|
+
validate: (value) => {
|
|
379
|
+
return /^[A-Z][a-zA-Z\d]*Middleware$/.test(value)
|
|
380
|
+
? true
|
|
381
|
+
: 'Must be PascalCase ending with "Middleware"';
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
]);
|
|
385
|
+
};
|
|
386
|
+
const buildMiddlewareKey = (middlewareName) => {
|
|
387
|
+
const withoutSuffix = middlewareName.replace(/Middleware$/, '');
|
|
388
|
+
return `${CommonUtils.camelCase(withoutSuffix)}Middleware`;
|
|
389
|
+
};
|
|
390
|
+
const buildMiddlewareSource = (middlewareName) => {
|
|
391
|
+
return `import type { Middleware } from '../../index.js';
|
|
392
|
+
|
|
393
|
+
export const ${middlewareName}: Middleware = async (_req, _res, next) => {
|
|
394
|
+
await next();
|
|
395
|
+
};
|
|
396
|
+
`;
|
|
397
|
+
};
|
|
398
|
+
const registerMiddlewareImport = (configSource, middlewareName) => {
|
|
399
|
+
const importLine = `import { ${middlewareName} } from '@app/Middleware/${middlewareName}';`;
|
|
400
|
+
if (configSource.includes(importLine))
|
|
401
|
+
return configSource;
|
|
402
|
+
const lines = configSource.split('\n');
|
|
403
|
+
let insertAt = -1;
|
|
404
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
405
|
+
if (lines[index]?.startsWith('import '))
|
|
406
|
+
insertAt = index;
|
|
407
|
+
}
|
|
408
|
+
if (insertAt === -1) {
|
|
409
|
+
return `${importLine}\n${configSource}`;
|
|
410
|
+
}
|
|
411
|
+
lines.splice(insertAt + 1, 0, importLine);
|
|
412
|
+
return lines.join('\n');
|
|
413
|
+
};
|
|
414
|
+
const registerMiddlewareRouteKey = (configSource, middlewareName, middlewareKey) => {
|
|
415
|
+
if (configSource.includes(`${middlewareKey}: ${middlewareName}`)) {
|
|
416
|
+
return { content: configSource, updated: true };
|
|
417
|
+
}
|
|
418
|
+
const routeBlockPattern = /route:\s*\{([\s\S]*?)\n\s*\},/;
|
|
419
|
+
if (routeBlockPattern.test(configSource)) {
|
|
420
|
+
return {
|
|
421
|
+
content: configSource.replace(routeBlockPattern, (_match, inner) => {
|
|
422
|
+
const prefix = inner.trim() === '' ? '' : inner.replace(/\s*$/, '');
|
|
423
|
+
const nextInner = prefix === ''
|
|
424
|
+
? `\n ${middlewareKey}: ${middlewareName},`
|
|
425
|
+
: `${prefix}\n ${middlewareKey}: ${middlewareName},`;
|
|
426
|
+
return `route: {${nextInner}\n },`;
|
|
427
|
+
}),
|
|
428
|
+
updated: true,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
const closingPattern = /\n\} as MiddlewaresType;\s*$/;
|
|
432
|
+
if (!closingPattern.test(configSource)) {
|
|
433
|
+
return { content: configSource, updated: false };
|
|
434
|
+
}
|
|
435
|
+
const inserted = configSource.replace(closingPattern, `\n global: [],\n route: {\n ${middlewareKey}: ${middlewareName},\n },\n} as MiddlewaresType;\n`);
|
|
436
|
+
return { content: inserted, updated: true };
|
|
437
|
+
};
|
|
438
|
+
const printManualMiddlewareRegistrationSnippet = (cmd, middlewareName, middlewareKey) => {
|
|
439
|
+
cmd.warn('Could not update config/middleware.ts automatically. Add this manually:');
|
|
440
|
+
cmd.info(`import { ${middlewareName} } from '@app/Middleware/${middlewareName}';`);
|
|
441
|
+
cmd.info(`route: { ${middlewareKey}: ${middlewareName} }`);
|
|
442
|
+
cmd.info(`Route typing example: type AppMiddlewareKey = MiddlewareKey | '${middlewareKey}';`);
|
|
443
|
+
};
|
|
444
|
+
const addMiddleware = async (cmd, middlewareName, opts) => {
|
|
445
|
+
const projectRoot = process.cwd();
|
|
446
|
+
let name = middlewareName ?? '';
|
|
447
|
+
if (name === '' && opts.noInteractive !== true) {
|
|
448
|
+
const answers = await promptMiddlewareConfig();
|
|
449
|
+
name = answers.name;
|
|
450
|
+
}
|
|
451
|
+
else if (name === '') {
|
|
452
|
+
throw ErrorFactory.createValidationError('Middleware name is required');
|
|
453
|
+
}
|
|
454
|
+
if (!/^[A-Z][a-zA-Z\d]*Middleware$/.test(name)) {
|
|
455
|
+
throw ErrorFactory.createValidationError('Middleware name must be PascalCase ending with "Middleware"');
|
|
456
|
+
}
|
|
457
|
+
const middlewareDir = path.join(projectRoot, 'app', 'Middleware');
|
|
458
|
+
const middlewarePath = path.join(middlewareDir, `${name}.ts`);
|
|
459
|
+
const configPath = path.join(projectRoot, 'config', 'middleware.ts');
|
|
460
|
+
const middlewareKey = buildMiddlewareKey(name);
|
|
461
|
+
ensureDirectoryExists(middlewareDir);
|
|
462
|
+
const created = FileGenerator.writeFile(middlewarePath, buildMiddlewareSource(name), {
|
|
463
|
+
overwrite: false,
|
|
464
|
+
});
|
|
465
|
+
if (!FileGenerator.fileExists(configPath)) {
|
|
466
|
+
cmd.success(`Middleware '${name}' created successfully!`);
|
|
467
|
+
cmd.warn('config/middleware.ts was not found, so registration was skipped.');
|
|
468
|
+
printManualMiddlewareRegistrationSnippet(cmd, name, middlewareKey);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const currentConfig = FileGenerator.readFile(configPath);
|
|
472
|
+
const withImport = registerMiddlewareImport(currentConfig, name);
|
|
473
|
+
const registered = registerMiddlewareRouteKey(withImport, name, middlewareKey);
|
|
474
|
+
if (!registered.updated) {
|
|
475
|
+
cmd.success(`Middleware '${name}' created successfully!`);
|
|
476
|
+
printManualMiddlewareRegistrationSnippet(cmd, name, middlewareKey);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
fs.writeFileSync(configPath, registered.content, 'utf-8');
|
|
480
|
+
cmd.success(`Middleware '${name}' ${created ? 'created' : 'updated'} successfully!`);
|
|
481
|
+
cmd.info(`File: ${path.basename(middlewarePath)}`);
|
|
482
|
+
cmd.info(`Registered route key: ${middlewareKey}`);
|
|
483
|
+
cmd.info(`\nNext steps:\n • Use '${middlewareKey}' in route metadata\n • If your route file uses MiddlewareKey, extend it locally: type AppMiddlewareKey = MiddlewareKey | '${middlewareKey}'`);
|
|
484
|
+
};
|
|
372
485
|
const getFactoryInitialConfig = (factoryName, opts) => {
|
|
373
486
|
return {
|
|
374
487
|
name: factoryName ?? '',
|
|
@@ -833,6 +946,7 @@ const TYPE_HANDLERS = {
|
|
|
833
946
|
model: addModel,
|
|
834
947
|
controller: addController,
|
|
835
948
|
routes: addRoutes,
|
|
949
|
+
middleware: addMiddleware,
|
|
836
950
|
factory: addFactory,
|
|
837
951
|
seeder: addSeeder,
|
|
838
952
|
requestfactory: addRequestFactory,
|
|
@@ -845,7 +959,7 @@ const TYPE_HANDLERS = {
|
|
|
845
959
|
const handleType = async (cmd, type, name, opts) => {
|
|
846
960
|
const handler = TYPE_HANDLERS[type];
|
|
847
961
|
if (handler === undefined) {
|
|
848
|
-
throw ErrorFactory.createCliError(`Unknown type "${type}". Use: service, feature, migration, model, controller, routes, factory, seeder, requestfactory, responsefactory, workflow, or governance`);
|
|
962
|
+
throw ErrorFactory.createCliError(`Unknown type "${type}". Use: service, feature, migration, model, controller, routes, middleware, factory, seeder, requestfactory, responsefactory, workflow, or governance`);
|
|
849
963
|
}
|
|
850
964
|
await handler(cmd, name, opts);
|
|
851
965
|
};
|
|
@@ -874,7 +988,7 @@ const executeAdd = async (cmd, options) => {
|
|
|
874
988
|
const addOpts = { ...options, ...commandOpts };
|
|
875
989
|
try {
|
|
876
990
|
if (type === undefined || type === '') {
|
|
877
|
-
throw ErrorFactory.createCliError('Please specify what to add: service, feature, migration, model, controller, routes, factory, or seeder');
|
|
991
|
+
throw ErrorFactory.createCliError('Please specify what to add: service, feature, migration, model, controller, routes, middleware, factory, or seeder');
|
|
878
992
|
}
|
|
879
993
|
// Planned modular adapter syntax: `zin add db:sqlite` (delegate to plugin installer)
|
|
880
994
|
const normalizedType = type.toLowerCase();
|
|
@@ -921,6 +1035,7 @@ export const AddCommand = Object.freeze({
|
|
|
921
1035
|
promptModelConfig,
|
|
922
1036
|
promptControllerConfig,
|
|
923
1037
|
promptRoutesConfig,
|
|
1038
|
+
promptMiddlewareConfig,
|
|
924
1039
|
promptFactoryConfig,
|
|
925
1040
|
promptSeederConfig,
|
|
926
1041
|
promptRequestFactoryConfig,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { CommandOptions, IBaseCommand } from '../BaseCommand';
|
|
6
6
|
type TemplateType = 'basic' | 'api' | 'microservice' | 'fullstack';
|
|
7
|
-
type DatabaseType = 'sqlite' | 'mysql' | 'postgresql' | 'mongodb' | 'd1-remote';
|
|
7
|
+
type DatabaseType = 'sqlite' | 'mysql' | 'postgresql' | 'mongodb' | 'd1' | 'd1-remote';
|
|
8
8
|
interface NewProjectConfigResult {
|
|
9
9
|
template: TemplateType;
|
|
10
10
|
database: DatabaseType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/NewCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgBrE,KAAK,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,cAAc,GAAG,WAAW,CAAC;AACnE,KAAK,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"NewCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/NewCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgBrE,KAAK,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,cAAc,GAAG,WAAW,CAAC;AACnE,KAAK,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,CAAC;AAYvF,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA0PhD,UAAU,WAAY,SAAQ,YAAY;IACxC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACxF,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACzF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,EAAE,CAAC;IACjF,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;IAChC,YAAY,IAAI,MAAM,CAAC;IACvB,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,sBAAsB,EAC9B,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpE;AA8RD;;;GAGG;AACH,eAAO,MAAM,UAAU;IACrB;;OAEG;cACO,WAAW;EAGrB,CAAC"}
|
|
@@ -54,6 +54,8 @@ const getProjectDefaults = (name, options) => {
|
|
|
54
54
|
const v = value.trim();
|
|
55
55
|
if (v === 'd1-proxy')
|
|
56
56
|
return 'd1-remote';
|
|
57
|
+
if (v === 'd1')
|
|
58
|
+
return 'd1';
|
|
57
59
|
if (v === 'd1-remote')
|
|
58
60
|
return 'd1-remote';
|
|
59
61
|
if (v === 'sqlite')
|
|
@@ -99,6 +101,7 @@ const getQuestions = (name, defaults) => {
|
|
|
99
101
|
{ name: 'sqlite — Local dev (file-based)', value: 'sqlite' },
|
|
100
102
|
{ name: 'postgresql — Production-ready relational DB', value: 'postgresql' },
|
|
101
103
|
{ name: 'mysql — Production-ready relational DB', value: 'mysql' },
|
|
104
|
+
{ name: 'd1 — Cloudflare D1 database', value: 'd1' },
|
|
102
105
|
{ name: 'd1-proxy — Cloudflare D1 via HTTPS proxy', value: 'd1-remote' },
|
|
103
106
|
{ name: 'mongodb — Document DB (may require additional setup)', value: 'mongodb' },
|
|
104
107
|
],
|
|
@@ -223,7 +226,7 @@ const installDependencies = async (projectPath, log, packageManager, force = fal
|
|
|
223
226
|
const addOptions = (command) => {
|
|
224
227
|
command.argument('<name>', 'Project name');
|
|
225
228
|
command.option('--template <type>', 'Project template (basic, api, microservice, fullstack)', 'basic');
|
|
226
|
-
command.option('--database <type>', 'Database driver (sqlite, mysql, postgresql)', 'sqlite');
|
|
229
|
+
command.option('--database <type>', 'Database driver (sqlite, mysql, postgresql, d1, d1-remote, mongodb)', 'sqlite');
|
|
227
230
|
command.option('--port <number>', 'Default port number', '7777');
|
|
228
231
|
command.option('--author <name>', 'Project author');
|
|
229
232
|
command.option('--description <text>', 'Project description');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAs4BvF,eAAO,MAAM,YAAY;cACb,YAAY;EAmCtB,CAAC"}
|
|
@@ -2,9 +2,9 @@ import { BaseCommand } from '../BaseCommand.js';
|
|
|
2
2
|
import { createDenoRunnerSource, createLambdaRunnerSource } from '../commands/runner/index.js';
|
|
3
3
|
import { EnvFileLoader } from '../utils/EnvFileLoader.js';
|
|
4
4
|
import { SpawnUtil } from '../utils/spawn.js';
|
|
5
|
-
import { generateUuid } from '../../common/utility.js';
|
|
6
5
|
import { readEnvString } from '../../common/ExternalServiceUtils.js';
|
|
7
6
|
import * as Common from '../../common/index.js';
|
|
7
|
+
import { generateUuid } from '../../common/utility.js';
|
|
8
8
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
9
9
|
import { isNonEmptyString } from '../../helper/index.js';
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from '../../node-singletons/fs.js';
|
|
@@ -303,7 +303,7 @@ const preloadManifestServiceEnv = async (context, options) => {
|
|
|
303
303
|
process.env['ZINTRUST_PROJECT_ROOT'] = context.projectRoot;
|
|
304
304
|
ProjectRuntime.clear();
|
|
305
305
|
await ProjectRuntime.tryLoadNodeRuntime();
|
|
306
|
-
const manifest = ProjectRuntime.getServiceManifest().filter((entry) => entry.monolithEnabled !== false);
|
|
306
|
+
const manifest = ProjectRuntime.getServiceManifest().filter((entry) => entry.monolithEnabled !== false && entry.loadEnv !== false);
|
|
307
307
|
if (manifest.length === 0)
|
|
308
308
|
return;
|
|
309
309
|
const envPaths = manifest
|
|
@@ -418,6 +418,7 @@ const executeWranglerStart = async (cmd, context, port, runtime, envName, wrangl
|
|
|
418
418
|
if (configPath === undefined && entry === undefined) {
|
|
419
419
|
throw ErrorFactory.createCliError("Error: wrangler config not found (wrangler.toml/json). Run 'wrangler init' first.");
|
|
420
420
|
}
|
|
421
|
+
warnOnUnsafeWranglerBootstrap(cmd, context.cwd, entry);
|
|
421
422
|
const wranglerArgs = ['dev'];
|
|
422
423
|
if (normalizedConfig !== '') {
|
|
423
424
|
wranglerArgs.push('--config', normalizedConfig);
|
|
@@ -434,14 +435,42 @@ const executeWranglerStart = async (cmd, context, port, runtime, envName, wrangl
|
|
|
434
435
|
logMySqlProxyHint(cmd);
|
|
435
436
|
cmd.info('Starting in Wrangler dev mode...');
|
|
436
437
|
const exitCode = await withWranglerEnvSnapshot(context.cwd, envName, async () => {
|
|
438
|
+
const startEnv = {
|
|
439
|
+
...buildStartEnv(context.projectRoot),
|
|
440
|
+
WORKER_ENABLED: 'false',
|
|
441
|
+
CLOUDFLARE_WORKER: 'true',
|
|
442
|
+
DOCKER_WORKER: 'false',
|
|
443
|
+
};
|
|
437
444
|
return SpawnUtil.spawnAndWait({
|
|
438
445
|
command: 'wrangler',
|
|
439
446
|
args: wranglerArgs,
|
|
440
|
-
env:
|
|
447
|
+
env: startEnv,
|
|
441
448
|
});
|
|
442
449
|
});
|
|
443
450
|
process.exit(exitCode);
|
|
444
451
|
};
|
|
452
|
+
const isUnsafeWranglerBootstrapSource = (source) => {
|
|
453
|
+
const getKernelIndex = source.indexOf('getKernel(');
|
|
454
|
+
const cloudflareFetchIndex = source.indexOf('cloudflareWorker.fetch');
|
|
455
|
+
return (getKernelIndex !== -1 && cloudflareFetchIndex !== -1 && getKernelIndex < cloudflareFetchIndex);
|
|
456
|
+
};
|
|
457
|
+
const warnOnUnsafeWranglerBootstrap = (cmd, cwd, entry) => {
|
|
458
|
+
if (entry === undefined)
|
|
459
|
+
return;
|
|
460
|
+
const entryPath = path.join(cwd, entry);
|
|
461
|
+
if (!existsSync(entryPath))
|
|
462
|
+
return;
|
|
463
|
+
try {
|
|
464
|
+
const source = readFileSync(entryPath, 'utf-8');
|
|
465
|
+
if (!isUnsafeWranglerBootstrapSource(source))
|
|
466
|
+
return;
|
|
467
|
+
cmd.warn(`Unsafe Worker bootstrap detected in ${entry}: getKernel() runs before the core Cloudflare handler initializes Worker bindings.`);
|
|
468
|
+
cmd.warn('Use `export { default } from "../../start.js"` and keep custom middleware registration in config/middleware.ts or route metadata.');
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
// Best-effort warning only.
|
|
472
|
+
}
|
|
473
|
+
};
|
|
445
474
|
const ensureTmpRunnerFile = (cwd, filename, content) => {
|
|
446
475
|
const tmpDir = path.join(cwd, 'tmp');
|
|
447
476
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ProjectScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtD,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IACpE,cAAc,IAAI,MAAM,CAAC;IACzB,sBAAsB,IAAI,OAAO,CAAC;IAClC,iBAAiB,IAAI,MAAM,CAAC;IAC5B,WAAW,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;IACtD,gBAAgB,IAAI,OAAO,CAAC;IAC5B,aAAa,IAAI,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC3E;AAodD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAsBrE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAsBA;
|
|
1
|
+
{"version":3,"file":"ProjectScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ProjectScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtD,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IACpE,cAAc,IAAI,MAAM,CAAC;IACzB,sBAAsB,IAAI,OAAO,CAAC;IAClC,iBAAiB,IAAI,MAAM,CAAC;IAC5B,WAAW,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;IACtD,gBAAgB,IAAI,OAAO,CAAC;IAC5B,aAAa,IAAI,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC3E;AAodD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAsBrE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAsBA;AA6ID;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,GAAE,MAAsB,GAAG,kBAAkB,CAsB/F;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAEhC;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;EAM5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ServiceScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD;;GAEG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuB7F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAGnF;AAED;;GAEG;AAEH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAiDhC;
|
|
1
|
+
{"version":3,"file":"ServiceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ServiceScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD;;GAEG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuB7F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAGnF;AAED;;GAEG;AAEH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAiDhC;AAocD,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC"}
|
|
@@ -110,6 +110,7 @@ export const serviceManifest: ReadonlyArray<ServiceManifestEntry> = [
|
|
|
110
110
|
name: '${options.name}',
|
|
111
111
|
configRoot: '${getServiceConfigRoot(domain, options.name)}',
|
|
112
112
|
prefix: '${serviceId}',
|
|
113
|
+
loadEnv: false,
|
|
113
114
|
port: ${options.port ?? 3001},
|
|
114
115
|
monolithEnabled: true,
|
|
115
116
|
loadRoutes: async () => ${routeImportExpression},
|
|
@@ -152,6 +153,7 @@ function updateServiceManifest(projectRoot, options) {
|
|
|
152
153
|
name: '${options.name}',
|
|
153
154
|
configRoot: '${getServiceConfigRoot(domain, options.name)}',
|
|
154
155
|
prefix: '${serviceId}',
|
|
156
|
+
loadEnv: false,
|
|
155
157
|
port: ${options.port ?? 3001},
|
|
156
158
|
monolithEnabled: true,
|
|
157
159
|
loadRoutes: async () => ${routeImportExpression},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MiddlewareConfigType } from './type';
|
|
2
|
+
import type { Middleware } from '../middleware/MiddlewareStack';
|
|
2
3
|
export declare const MiddlewareBody: {
|
|
3
4
|
readonly email: "email";
|
|
4
5
|
readonly password: "password";
|
|
@@ -6,7 +7,7 @@ export declare const MiddlewareBody: {
|
|
|
6
7
|
readonly count: "count";
|
|
7
8
|
};
|
|
8
9
|
export type MiddlewaresType = {
|
|
9
|
-
skipPaths: string
|
|
10
|
+
skipPaths: ReadonlyArray<string>;
|
|
10
11
|
fillRateLimit: {
|
|
11
12
|
windowMs: number;
|
|
12
13
|
max: number;
|
|
@@ -22,6 +23,8 @@ export type MiddlewaresType = {
|
|
|
22
23
|
max: number;
|
|
23
24
|
message: string;
|
|
24
25
|
};
|
|
26
|
+
global?: ReadonlyArray<Middleware>;
|
|
27
|
+
route?: Record<string, Middleware>;
|
|
25
28
|
};
|
|
26
29
|
export declare const MiddlewareKeys: Readonly<{
|
|
27
30
|
log: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/config/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/config/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAUzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAwD9D,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,qBAAqB,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,MAAM,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAkBuB,CAAC;AAEnD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,cAAc,CAAC;AAoOxD,wBAAgB,sBAAsB,IAAI,oBAAoB,CAwC7D;AAID;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAO,IAE7C,CAAC;AAwBF,eAAO,MAAM,gBAAgB,EAAE,oBAY7B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
|
package/src/config/middleware.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Env } from './env.js';
|
|
2
|
+
import { isArray, isObject } from '../helper/index.js';
|
|
2
3
|
import { bodyParsingMiddleware } from '../http/middleware/BodyParsingMiddleware.js';
|
|
3
4
|
import { fileUploadMiddleware } from '../http/middleware/FileUploadMiddleware.js';
|
|
4
5
|
import { AuthMiddleware } from '../middleware/AuthMiddleware.js';
|
|
@@ -157,6 +158,22 @@ function createSharedMiddlewares(loadMiddlewareConfig) {
|
|
|
157
158
|
...validations,
|
|
158
159
|
});
|
|
159
160
|
}
|
|
161
|
+
const resolveProjectGlobalMiddlewares = (loadMiddlewareConfig) => {
|
|
162
|
+
if (!isArray(loadMiddlewareConfig.global))
|
|
163
|
+
return [];
|
|
164
|
+
return loadMiddlewareConfig.global.filter((middleware) => {
|
|
165
|
+
return typeof middleware === 'function';
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
const resolveProjectRouteMiddlewares = (loadMiddlewareConfig) => {
|
|
169
|
+
if (!isObject(loadMiddlewareConfig.route))
|
|
170
|
+
return {};
|
|
171
|
+
const entries = Object.entries(loadMiddlewareConfig.route).filter((entry) => {
|
|
172
|
+
const [name, middleware] = entry;
|
|
173
|
+
return typeof name === 'string' && name.trim() !== '' && typeof middleware === 'function';
|
|
174
|
+
});
|
|
175
|
+
return Object.fromEntries(entries);
|
|
176
|
+
};
|
|
160
177
|
export function createMiddlewareConfig() {
|
|
161
178
|
const loadMiddlewareConfig = StartupConfigFileRegistry.get(StartupConfigFile.Middleware) ?? {};
|
|
162
179
|
const skipPathsFromEnv = Env.get('CSRF_SKIP_PATHS', '')
|
|
@@ -170,6 +187,8 @@ export function createMiddlewareConfig() {
|
|
|
170
187
|
: skipPathsFromEnv,
|
|
171
188
|
};
|
|
172
189
|
const shared = createSharedMiddlewares(effectiveMiddlewareConfig);
|
|
190
|
+
const projectGlobal = resolveProjectGlobalMiddlewares(effectiveMiddlewareConfig);
|
|
191
|
+
const projectRoute = resolveProjectRouteMiddlewares(effectiveMiddlewareConfig);
|
|
173
192
|
const middlewareConfigObj = {
|
|
174
193
|
global: [
|
|
175
194
|
shared.log,
|
|
@@ -180,8 +199,12 @@ export function createMiddlewareConfig() {
|
|
|
180
199
|
bodyParsingMiddleware,
|
|
181
200
|
shared.csrf,
|
|
182
201
|
shared.sanitizeBody,
|
|
202
|
+
...projectGlobal,
|
|
183
203
|
],
|
|
184
|
-
route:
|
|
204
|
+
route: {
|
|
205
|
+
...shared,
|
|
206
|
+
...projectRoute,
|
|
207
|
+
},
|
|
185
208
|
};
|
|
186
209
|
return Object.freeze(middlewareConfigObj);
|
|
187
210
|
}
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core v0.4.
|
|
2
|
+
* @zintrust/core v0.4.16
|
|
3
3
|
*
|
|
4
4
|
* ZinTrust Framework - Production-Grade TypeScript Backend
|
|
5
5
|
* Built for performance, type safety, and exceptional developer experience
|
|
6
6
|
*
|
|
7
7
|
* Build Information:
|
|
8
|
-
* Built: 2026-03-
|
|
8
|
+
* Built: 2026-03-24T13:49:16.905Z
|
|
9
9
|
* Node: >=20.0.0
|
|
10
10
|
* License: MIT
|
|
11
11
|
*
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Available at runtime for debugging and health checks
|
|
22
22
|
*/
|
|
23
23
|
export const ZINTRUST_VERSION = '0.1.41';
|
|
24
|
-
export const ZINTRUST_BUILD_DATE = '2026-03-
|
|
24
|
+
export const ZINTRUST_BUILD_DATE = '2026-03-24T13:49:16.870Z'; // Replaced during build
|
|
25
25
|
export { Application } from './boot/Application.js';
|
|
26
26
|
export { AwsSigV4 } from './common/index.js';
|
|
27
27
|
export { SignedRequest } from './security/SignedRequest.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceManifest.d.ts","sourceRoot":"","sources":["../../../src/microservices/ServiceManifest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACtD,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,KAAG,MAA6B,CAAC;AAE1F,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,KAAG,MACrC,CAAC;AAenC,eAAO,MAAM,gBAAgB,GAAI,MAAM;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,KAAG,MAMH,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAI9D,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,MAAM;IACzC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,KAAG,MAKH,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"ServiceManifest.d.ts","sourceRoot":"","sources":["../../../src/microservices/ServiceManifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,10 @@ export const isServiceManifestEntry = (value) => {
|
|
|
50
50
|
if (configRoot !== undefined && typeof configRoot !== 'string') {
|
|
51
51
|
return false;
|
|
52
52
|
}
|
|
53
|
+
const loadEnv = value['loadEnv'];
|
|
54
|
+
if (loadEnv !== undefined && typeof loadEnv !== 'boolean') {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
53
57
|
const loadRoutes = value['loadRoutes'];
|
|
54
58
|
if (loadRoutes !== undefined && !isFunction(loadRoutes)) {
|
|
55
59
|
return false;
|
|
@@ -64,6 +68,7 @@ export const normalizeServiceManifest = (value) => {
|
|
|
64
68
|
id: toCanonicalServiceId(entry),
|
|
65
69
|
prefix: getServicePrefix(entry),
|
|
66
70
|
...(isNonEmptyString(entry.configRoot) ? { configRoot: entry.configRoot } : {}),
|
|
71
|
+
loadEnv: entry.loadEnv !== false,
|
|
67
72
|
monolithEnabled: entry.monolithEnabled !== false,
|
|
68
73
|
}));
|
|
69
74
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CsrfMiddleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/CsrfMiddleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAK9D,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"CsrfMiddleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/CsrfMiddleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAK9D,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACnC;AAkDD,eAAO,MAAM,cAAc;IACzB;;OAEG;qBACa,WAAW,GAAQ,UAAU;EA6D7C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectRuntime.d.ts","sourceRoot":"","sources":["../../../src/runtime/ProjectRuntime.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC1B,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"ProjectRuntime.d.ts","sourceRoot":"","sources":["../../../src/runtime/ProjectRuntime.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC1B,MAAM,gCAAgC,CAAC;AAoGxC,eAAO,MAAM,cAAc;aAChB,IAAI;iBAIA,oBAAoB,GAAG,SAAS;gBAIjC,OAAO,GAAG,oBAAoB;oCAIV,OAAO,GAAG,oBAAoB,GAAG,SAAS;0BAM9C,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;4BAgBvC,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;0BAOjD,aAAa,CAAC,oBAAoB,CAAC;wBAIrC,oBAAoB,GAAG,SAAS;EAGpD,CAAC;AAEH,eAAe,cAAc,CAAC"}
|
|
@@ -52,10 +52,27 @@ const tryImportNodeRuntimeCandidate = async (candidate) => {
|
|
|
52
52
|
return undefined;
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
const
|
|
55
|
+
const tryImportWorkerRuntimeLiteralCandidates = async () => {
|
|
56
56
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
return cacheProjectRuntime((await import('../zintrust.runtime.wg.js')));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// continue
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
return cacheProjectRuntime((await import('../zintrust.runtime.js')));
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// continue
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
return cacheProjectRuntime((await import('../index.js' + 'zintrust.runtime.wg.js')));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// continue
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
return cacheProjectRuntime((await import('../index.js' + 'zintrust.runtime.js')));
|
|
59
76
|
}
|
|
60
77
|
catch {
|
|
61
78
|
return undefined;
|
|
@@ -95,14 +112,7 @@ export const ProjectRuntime = Object.freeze({
|
|
|
95
112
|
const cached = getCachedProjectRuntime();
|
|
96
113
|
if (hasLoadedServiceManifest(cached))
|
|
97
114
|
return cached;
|
|
98
|
-
|
|
99
|
-
for (const moduleId of workerModuleIds) {
|
|
100
|
-
// eslint-disable-next-line no-await-in-loop
|
|
101
|
-
const loaded = await tryImportWorkerRuntimeCandidate(moduleId);
|
|
102
|
-
if (loaded !== undefined)
|
|
103
|
-
return loaded;
|
|
104
|
-
}
|
|
105
|
-
return undefined;
|
|
115
|
+
return tryImportWorkerRuntimeLiteralCandidates();
|
|
106
116
|
},
|
|
107
117
|
getServiceManifest() {
|
|
108
118
|
return getCachedProjectRuntime()?.serviceManifest ?? [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerAdapterImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/WorkerAdapterImports.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WorkerAdapterImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/WorkerAdapterImports.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,oBAAoB;;;EAG/B,CAAC"}
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
// Worker-only adapter auto-imports for bundler-based runtimes (e.g. Cloudflare Workers).
|
|
2
2
|
// Keep this list limited to database adapters needed by runtime config.
|
|
3
|
+
import { ProjectRuntime } from './ProjectRuntime.js';
|
|
4
|
+
const tryImportProjectRuntime = async () => {
|
|
5
|
+
try {
|
|
6
|
+
ProjectRuntime.set(await import('../zintrust.runtime.wg.js'));
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// continue
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
ProjectRuntime.set(await import('../zintrust.runtime.js'));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Ignore missing runtime modules. Worker startup can still proceed without them.
|
|
17
|
+
}
|
|
18
|
+
};
|
|
3
19
|
// These imports resolve against the host project (developer working directory)
|
|
4
20
|
// via the @/ alias configured by the ZinTrust app templates.
|
|
5
21
|
const tryImportOptional = async () => {
|
|
22
|
+
await tryImportProjectRuntime();
|
|
6
23
|
try {
|
|
7
24
|
await import('../zintrust.plugins.wg.js');
|
|
8
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkersModule.d.ts","sourceRoot":"","sources":["../../../src/runtime/WorkersModule.ts"],"names":[],"mappings":"AAOA,KAAK,aAAa,GAAG,cAAc,mBAAmB,CAAC,CAAC;AACxD,KAAK,kBAAkB,GAAG,cAAc,yBAAyB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkersModule.d.ts","sourceRoot":"","sources":["../../../src/runtime/WorkersModule.ts"],"names":[],"mappings":"AAOA,KAAK,aAAa,GAAG,cAAc,mBAAmB,CAAC,CAAC;AACxD,KAAK,kBAAkB,GAAG,cAAc,yBAAyB,CAAC,CAAC;AA4WnE,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,aAAa,CAwB/D,CAAC;AA4CF,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,kBAAkB,CAkBzE,CAAC"}
|
|
@@ -194,6 +194,9 @@ const importLocalModule = async (packageDir, packageName) => {
|
|
|
194
194
|
};
|
|
195
195
|
const importLocalWorkersModule = async () => importLocalModule('workers', '@zintrust/workers');
|
|
196
196
|
const importLocalQueueMonitorModule = async () => importLocalModule('queue-monitor', '@zintrust/queue-monitor');
|
|
197
|
+
const importOptionalPackage = async (specifier) => {
|
|
198
|
+
return (await import(specifier));
|
|
199
|
+
};
|
|
197
200
|
let workersModulePromise;
|
|
198
201
|
let patchAttempted = false;
|
|
199
202
|
let patchAfterFailureAttempted = false;
|
|
@@ -234,12 +237,35 @@ const applyInitialPatches = () => {
|
|
|
234
237
|
Logger.warn('Rewrote @zintrust/queue-monitor ESM specifiers before import', monitorPatch);
|
|
235
238
|
}
|
|
236
239
|
};
|
|
240
|
+
const getErrorChain = (error) => {
|
|
241
|
+
const chain = [];
|
|
242
|
+
const seen = new Set();
|
|
243
|
+
let current = error;
|
|
244
|
+
while (current !== null && current !== undefined && !seen.has(current)) {
|
|
245
|
+
seen.add(current);
|
|
246
|
+
const entry = current;
|
|
247
|
+
chain.push({
|
|
248
|
+
message: typeof entry.message === 'string' && entry.message !== '' ? entry.message : String(current),
|
|
249
|
+
code: typeof entry.code === 'string' ? entry.code : undefined,
|
|
250
|
+
});
|
|
251
|
+
current = entry.cause;
|
|
252
|
+
}
|
|
253
|
+
return chain;
|
|
254
|
+
};
|
|
237
255
|
const shouldRetryAfterFailure = (error) => {
|
|
238
256
|
if (patchAfterFailureAttempted)
|
|
239
257
|
return false;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
258
|
+
return getErrorChain(error).some(({ message, code }) => code === 'ERR_MODULE_NOT_FOUND' && message.includes('@zintrust/workers'));
|
|
259
|
+
};
|
|
260
|
+
const isMissingOptionalWorkersModuleError = (error) => {
|
|
261
|
+
return getErrorChain(error).some(({ message, code }) => {
|
|
262
|
+
if (!message.includes('@zintrust/workers'))
|
|
263
|
+
return false;
|
|
264
|
+
return (code === 'ERR_MODULE_NOT_FOUND' ||
|
|
265
|
+
message.includes('ERR_MODULE_NOT_FOUND') ||
|
|
266
|
+
message.includes('Cannot find package') ||
|
|
267
|
+
message.includes('No such module'));
|
|
268
|
+
});
|
|
243
269
|
};
|
|
244
270
|
const handleImportFailure = async (error) => {
|
|
245
271
|
if (shouldRetryAfterFailure(error)) {
|
|
@@ -250,8 +276,13 @@ const handleImportFailure = async (error) => {
|
|
|
250
276
|
filesChanged,
|
|
251
277
|
replacements,
|
|
252
278
|
});
|
|
253
|
-
workersModulePromise =
|
|
254
|
-
|
|
279
|
+
workersModulePromise = importOptionalPackage('@zintrust/workers');
|
|
280
|
+
try {
|
|
281
|
+
return await workersModulePromise;
|
|
282
|
+
}
|
|
283
|
+
catch (retryError) {
|
|
284
|
+
error = retryError;
|
|
285
|
+
}
|
|
255
286
|
}
|
|
256
287
|
}
|
|
257
288
|
const localFallback = await importLocalWorkersModule();
|
|
@@ -259,6 +290,11 @@ const handleImportFailure = async (error) => {
|
|
|
259
290
|
workersModulePromise = Promise.resolve(localFallback);
|
|
260
291
|
return localFallback;
|
|
261
292
|
}
|
|
293
|
+
if (isMissingOptionalWorkersModuleError(error)) {
|
|
294
|
+
Logger.info('Optional @zintrust/workers package is unavailable; worker routes are disabled.');
|
|
295
|
+
workersModulePromise = Promise.resolve(createDisabledWorkersModule());
|
|
296
|
+
return workersModulePromise;
|
|
297
|
+
}
|
|
262
298
|
throw error;
|
|
263
299
|
};
|
|
264
300
|
const tryLocalFallback = async () => {
|
|
@@ -283,7 +319,7 @@ export const loadWorkersModule = async () => {
|
|
|
283
319
|
}
|
|
284
320
|
}
|
|
285
321
|
logWorkersResolverDiagnostics();
|
|
286
|
-
workersModulePromise ??=
|
|
322
|
+
workersModulePromise ??= importOptionalPackage('@zintrust/workers');
|
|
287
323
|
try {
|
|
288
324
|
return await workersModulePromise;
|
|
289
325
|
}
|
|
@@ -307,7 +343,8 @@ const handleQueueMonitorImportFailure = async (error) => {
|
|
|
307
343
|
filesChanged,
|
|
308
344
|
replacements,
|
|
309
345
|
});
|
|
310
|
-
queueMonitorModulePromise =
|
|
346
|
+
queueMonitorModulePromise =
|
|
347
|
+
importOptionalPackage('@zintrust/queue-monitor');
|
|
311
348
|
return queueMonitorModulePromise;
|
|
312
349
|
}
|
|
313
350
|
}
|
|
@@ -334,7 +371,8 @@ export const loadQueueMonitorModule = async () => {
|
|
|
334
371
|
return localFallback;
|
|
335
372
|
}
|
|
336
373
|
}
|
|
337
|
-
queueMonitorModulePromise ??=
|
|
374
|
+
queueMonitorModulePromise ??=
|
|
375
|
+
importOptionalPackage('@zintrust/queue-monitor');
|
|
338
376
|
try {
|
|
339
377
|
return await queueMonitorModulePromise;
|
|
340
378
|
}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
// @ts-ignore - config templates are excluded from the main TS project in this repo
|
|
2
|
+
import { Env } from '@zintrust/core';
|
|
3
|
+
import type { MiddlewaresType } from '@zintrust/core';
|
|
2
4
|
/**
|
|
3
5
|
* Middleware Configuration (template)
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* Full project middleware flow:
|
|
8
|
+
* 1. Create `app/Middleware/YourMiddleware.ts` and export a `Middleware` function.
|
|
9
|
+
* 2. Import it below.
|
|
10
|
+
* 3. Register route middleware under `route` or append global middleware under `global`.
|
|
11
|
+
* 4. Use the route key in `routes/*.ts`.
|
|
12
|
+
*
|
|
13
|
+
* For custom route keys, extend the framework type locally in your route file:
|
|
14
|
+
* `type AppMiddlewareKey = MiddlewareKey | 'yourMiddleware';`
|
|
8
15
|
*/
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
import
|
|
17
|
+
// Example custom middleware import:
|
|
18
|
+
// import { AuthMiddleware } from '@app/Middleware/AuthMiddleware';
|
|
12
19
|
|
|
13
20
|
export default {
|
|
14
21
|
skipPaths: Env.get('CSRF_SKIP_PATHS', '')
|
|
@@ -30,4 +37,10 @@ export default {
|
|
|
30
37
|
max: 20,
|
|
31
38
|
message: 'Too many user mutation requests, please try again later.',
|
|
32
39
|
},
|
|
40
|
+
global: [
|
|
41
|
+
// AuthMiddleware,
|
|
42
|
+
],
|
|
43
|
+
route: {
|
|
44
|
+
// authMiddleware: AuthMiddleware,
|
|
45
|
+
},
|
|
33
46
|
} as MiddlewaresType;
|