@zintrust/core 0.4.10 → 0.4.12
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/registry/registerRoute.d.ts +1 -1
- package/src/boot/registry/registerRoute.d.ts.map +1 -1
- package/src/boot/registry/registerRoute.js +8 -2
- package/src/cli/commands/RoutesCommand.d.ts.map +1 -1
- package/src/cli/commands/RoutesCommand.js +6 -2
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +5 -1
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +2 -0
- package/src/cli/utils/EnvFileLoader.d.ts +2 -1
- package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
- package/src/cli/utils/EnvFileLoader.js +23 -7
- package/src/cli/utils/spawn.d.ts.map +1 -1
- package/src/cli/utils/spawn.js +11 -1
- package/src/index.js +3 -3
- package/src/microservices/ServiceManifest.d.ts +13 -0
- package/src/microservices/ServiceManifest.d.ts.map +1 -1
- package/src/microservices/ServiceManifest.js +27 -0
- package/src/runtime/PluginAutoImports.d.ts.map +1 -1
- package/src/runtime/PluginAutoImports.js +66 -29
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type IRouter } from '../../routes/Router';
|
|
2
2
|
export declare const isCompiledJsModule: () => boolean;
|
|
3
3
|
export declare const tryImportOptional: <T>(modulePath: string) => Promise<T | undefined>;
|
|
4
4
|
export declare const tryImportOptionalR: <T>(modulePath: string) => Promise<T | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerRoute.d.ts","sourceRoot":"","sources":["../../../../src/boot/registry/registerRoute.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
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;AAW3D,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;AA4FF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,MAAM,EACxB,QAAQ,OAAO,KACd,OAAO,CAAC,IAAI,CAoBd,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { appConfig } from '../../config/index.js';
|
|
2
2
|
import Logger from '../../config/logger.js';
|
|
3
|
+
import { Router } from '../../routes/Router.js';
|
|
3
4
|
import { isObject } from '../../helper/index.js';
|
|
5
|
+
import { getServicePrefix } from '../../microservices/ServiceManifest.js';
|
|
4
6
|
import * as path from '../../node-singletons/path.js';
|
|
5
7
|
import { pathToFileURL } from '../../node-singletons/url.js';
|
|
6
8
|
import { detectRuntime } from '../../runtime/detectRuntime.js';
|
|
@@ -62,6 +64,7 @@ const registerAppRoutes = async (resolvedBasePath, router) => {
|
|
|
62
64
|
}
|
|
63
65
|
};
|
|
64
66
|
const registerManifestRoutes = async (router) => {
|
|
67
|
+
await ProjectRuntime.tryLoadNodeRuntime();
|
|
65
68
|
const serviceManifest = ProjectRuntime.getServiceManifest();
|
|
66
69
|
if (serviceManifest.length === 0)
|
|
67
70
|
return;
|
|
@@ -72,8 +75,11 @@ const registerManifestRoutes = async (router) => {
|
|
|
72
75
|
try {
|
|
73
76
|
// eslint-disable-next-line no-await-in-loop
|
|
74
77
|
const mod = await entry.loadRoutes();
|
|
75
|
-
|
|
76
|
-
|
|
78
|
+
const registerRoutes = isObject(mod) ? mod.registerRoutes : undefined;
|
|
79
|
+
if (typeof registerRoutes === 'function') {
|
|
80
|
+
Router.group(router, getServicePrefix(entry), (scopedRouter) => {
|
|
81
|
+
registerRoutes(scopedRouter);
|
|
82
|
+
});
|
|
77
83
|
}
|
|
78
84
|
}
|
|
79
85
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoutesCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/RoutesCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"RoutesCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/RoutesCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA2VvF,eAAO,MAAM,aAAa;cACd,YAAY;EAatB,CAAC;AAEH,eAAe,aAAa,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { Env } from '../../config/env.js';
|
|
|
7
7
|
import { Router } from '../../routes/Router.js';
|
|
8
8
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
9
9
|
import { isObject } from '../../helper/index.js';
|
|
10
|
+
import { getServicePrefix } from '../../microservices/ServiceManifest.js';
|
|
10
11
|
import { ProjectRuntime } from '../../runtime/ProjectRuntime.js';
|
|
11
12
|
const parseGroupBy = (value) => {
|
|
12
13
|
const raw = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
@@ -180,8 +181,11 @@ const registerManifestRoutes = async (router) => {
|
|
|
180
181
|
const beforeCount = Router.getRoutes(router).length;
|
|
181
182
|
// eslint-disable-next-line no-await-in-loop
|
|
182
183
|
const mod = await entry.loadRoutes();
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
const registerRoutes = isObject(mod) ? mod.registerRoutes : undefined;
|
|
185
|
+
if (typeof registerRoutes === 'function') {
|
|
186
|
+
Router.group(router, getServicePrefix(entry), (scopedRouter) => {
|
|
187
|
+
registerRoutes(scopedRouter);
|
|
188
|
+
});
|
|
185
189
|
annotateManifestRoutes(router, beforeCount, entry.id);
|
|
186
190
|
}
|
|
187
191
|
}
|
|
@@ -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;AAgtBvF,eAAO,MAAM,YAAY;cACb,YAAY;EA6BtB,CAAC"}
|
|
@@ -210,6 +210,10 @@ const buildStartEnv = (projectRoot) => ({
|
|
|
210
210
|
...process.env,
|
|
211
211
|
ZINTRUST_PROJECT_ROOT: projectRoot,
|
|
212
212
|
});
|
|
213
|
+
const ensureStartEnvLoaded = (context) => {
|
|
214
|
+
const extraCwds = context.cwd === context.projectRoot ? [] : [context.cwd];
|
|
215
|
+
EnvFileLoader.ensureLoaded({ cwd: context.projectRoot, extraCwds });
|
|
216
|
+
};
|
|
213
217
|
const isFrameworkRepo = (packageJson) => packageJson.name === '@zintrust/core';
|
|
214
218
|
const hasDevScript = (packageJson) => {
|
|
215
219
|
const scripts = packageJson.scripts;
|
|
@@ -479,7 +483,7 @@ const executeSplitStart = async (cmd, context, _options) => {
|
|
|
479
483
|
const executeStart = async (options, cmd) => {
|
|
480
484
|
const cwd = process.cwd();
|
|
481
485
|
const context = resolveStartContext(cwd);
|
|
482
|
-
|
|
486
|
+
ensureStartEnvLoaded(context);
|
|
483
487
|
const mode = resolveMode(options);
|
|
484
488
|
const port = resolvePort(options);
|
|
485
489
|
const runtime = resolveRuntime(options);
|
|
@@ -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;AAUD;;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;AAUD;;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;AAgcD,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC"}
|
|
@@ -107,6 +107,7 @@ export const serviceManifest: ReadonlyArray<ServiceManifestEntry> = [
|
|
|
107
107
|
id: '${serviceId}',
|
|
108
108
|
domain: '${domain}',
|
|
109
109
|
name: '${options.name}',
|
|
110
|
+
prefix: '${serviceId}',
|
|
110
111
|
port: ${options.port ?? 3001},
|
|
111
112
|
monolithEnabled: true,
|
|
112
113
|
loadRoutes: async () => ${routeImportExpression},
|
|
@@ -147,6 +148,7 @@ function updateServiceManifest(projectRoot, options) {
|
|
|
147
148
|
id: '${serviceId}',
|
|
148
149
|
domain: '${domain}',
|
|
149
150
|
name: '${options.name}',
|
|
151
|
+
prefix: '${serviceId}',
|
|
150
152
|
port: ${options.port ?? 3001},
|
|
151
153
|
monolithEnabled: true,
|
|
152
154
|
loadRoutes: async () => ${routeImportExpression},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
type node_env = 'development' | 'production' | 'testing';
|
|
2
2
|
type LoadOptions = {
|
|
3
3
|
cwd?: string;
|
|
4
|
+
extraCwds?: string[];
|
|
4
5
|
overrideExisting?: boolean;
|
|
5
6
|
};
|
|
6
7
|
type LoadState = {
|
|
@@ -15,7 +16,7 @@ type CliOverrides = {
|
|
|
15
16
|
};
|
|
16
17
|
export declare const EnvFileLoader: Readonly<{
|
|
17
18
|
load: (options?: LoadOptions) => LoadState;
|
|
18
|
-
ensureLoaded: () => LoadState;
|
|
19
|
+
ensureLoaded: (options?: Omit<LoadOptions, "overrideExisting">) => LoadState;
|
|
19
20
|
applyCliOverrides: (overrides: CliOverrides) => void;
|
|
20
21
|
getState: () => LoadState;
|
|
21
22
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnvFileLoader.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/EnvFileLoader.ts"],"names":[],"mappings":"AAQA,KAAK,QAAQ,GAAG,aAAa,GAAG,YAAY,GAAG,SAAS,CAAC;AAmIzD,KAAK,WAAW,GAAG;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;
|
|
1
|
+
{"version":3,"file":"EnvFileLoader.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/EnvFileLoader.ts"],"names":[],"mappings":"AAQA,KAAK,QAAQ,GAAG,aAAa,GAAG,YAAY,GAAG,SAAS,CAAC;AAmIzD,KAAK,WAAW,GAAG;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAkHF,eAAO,MAAM,aAAa;qBA7DH,WAAW,KAAQ,SAAS;6BAyBpB,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,KAAQ,SAAS;mCAG/C,YAAY,KAAG,IAAI;oBA+BpC,SAAS;EAO5B,CAAC"}
|
|
@@ -139,11 +139,7 @@ const filesLoader = (cwd, mode) => {
|
|
|
139
139
|
return files;
|
|
140
140
|
};
|
|
141
141
|
let cached;
|
|
142
|
-
const
|
|
143
|
-
if (cached !== undefined)
|
|
144
|
-
return cached;
|
|
145
|
-
const cwd = typeof options.cwd === 'string' && options.cwd !== '' ? options.cwd : process.cwd();
|
|
146
|
-
const overrideExisting = options.overrideExisting ?? true;
|
|
142
|
+
const loadFromCwd = (cwd, overrideExisting) => {
|
|
147
143
|
const mode = resolveAppMode(cwd);
|
|
148
144
|
const files = filesLoader(cwd, mode);
|
|
149
145
|
let baseApplied = false;
|
|
@@ -163,10 +159,30 @@ const load = (options = {}) => {
|
|
|
163
159
|
if (mode !== undefined) {
|
|
164
160
|
safeEnvSet('NODE_ENV', mode);
|
|
165
161
|
}
|
|
166
|
-
|
|
162
|
+
return { loadedFiles: files, mode };
|
|
163
|
+
};
|
|
164
|
+
const load = (options = {}) => {
|
|
165
|
+
if (cached !== undefined)
|
|
166
|
+
return cached;
|
|
167
|
+
const cwd = typeof options.cwd === 'string' && options.cwd !== '' ? options.cwd : process.cwd();
|
|
168
|
+
const extraCwds = Array.isArray(options.extraCwds)
|
|
169
|
+
? options.extraCwds.filter((value) => typeof value === 'string' && value.trim() !== '')
|
|
170
|
+
: [];
|
|
171
|
+
const overrideExisting = options.overrideExisting ?? true;
|
|
172
|
+
const roots = [cwd, ...extraCwds].filter((value, index, items) => items.indexOf(value) === index);
|
|
173
|
+
let mergedMode;
|
|
174
|
+
const loadedFiles = [];
|
|
175
|
+
for (let index = 0; index < roots.length; index += 1) {
|
|
176
|
+
const root = roots[index];
|
|
177
|
+
const state = loadFromCwd(root, index === 0 ? overrideExisting : true);
|
|
178
|
+
if (mergedMode === undefined && state.mode !== undefined)
|
|
179
|
+
mergedMode = state.mode;
|
|
180
|
+
loadedFiles.push(...state.loadedFiles);
|
|
181
|
+
}
|
|
182
|
+
cached = { loadedFiles, mode: mergedMode };
|
|
167
183
|
return cached;
|
|
168
184
|
};
|
|
169
|
-
const ensureLoaded = () => load({ overrideExisting: false });
|
|
185
|
+
const ensureLoaded = (options = {}) => load({ ...options, overrideExisting: false });
|
|
170
186
|
const applyCliOverrides = (overrides) => {
|
|
171
187
|
// Ensure base env is loaded first.
|
|
172
188
|
ensureLoaded();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/spawn.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/spawn.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA0CD,eAAO,MAAM,SAAS;wBACM,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;EA+E7D,CAAC"}
|
package/src/cli/utils/spawn.js
CHANGED
|
@@ -29,6 +29,16 @@ const resolveLocalBin = (command, cwd) => {
|
|
|
29
29
|
}
|
|
30
30
|
return command;
|
|
31
31
|
};
|
|
32
|
+
const buildCommandNotFoundMessage = (command) => {
|
|
33
|
+
if (command === 'tsx') {
|
|
34
|
+
return [
|
|
35
|
+
"Error: 'tsx' not found on PATH.",
|
|
36
|
+
'Install it in the project with "npm install -D tsx".',
|
|
37
|
+
'If you want a machine-wide fallback, install it globally with "npm install -g tsx".',
|
|
38
|
+
].join(' ');
|
|
39
|
+
}
|
|
40
|
+
return `Error: '${command}' not found on PATH.`;
|
|
41
|
+
};
|
|
32
42
|
export const SpawnUtil = Object.freeze({
|
|
33
43
|
async spawnAndWait(input) {
|
|
34
44
|
const cwd = input.cwd ?? process.cwd();
|
|
@@ -87,7 +97,7 @@ export const SpawnUtil = Object.freeze({
|
|
|
87
97
|
catch (error) {
|
|
88
98
|
const code = error?.code;
|
|
89
99
|
if (code === 'ENOENT') {
|
|
90
|
-
throw ErrorFactory.createCliError(
|
|
100
|
+
throw ErrorFactory.createCliError(buildCommandNotFoundMessage(input.command));
|
|
91
101
|
}
|
|
92
102
|
throw ErrorFactory.createTryCatchError('Failed to spawn child process', error);
|
|
93
103
|
}
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core v0.4.
|
|
2
|
+
* @zintrust/core v0.4.12
|
|
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-23T13:57:31.438Z
|
|
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-23T13:57:31.366Z'; // 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';
|
|
@@ -3,6 +3,7 @@ export interface ServiceManifestEntry {
|
|
|
3
3
|
id: string;
|
|
4
4
|
domain: string;
|
|
5
5
|
name: string;
|
|
6
|
+
prefix?: string;
|
|
6
7
|
version?: string;
|
|
7
8
|
description?: string;
|
|
8
9
|
port?: number;
|
|
@@ -21,6 +22,12 @@ export interface ProjectRuntimeModule {
|
|
|
21
22
|
activeService?: ActiveServiceRuntime;
|
|
22
23
|
}
|
|
23
24
|
export declare const getServiceId: (domain: string, name: string) => string;
|
|
25
|
+
export declare const getDefaultServicePrefix: (domain: string, name: string) => string;
|
|
26
|
+
export declare const getServicePrefix: (args: {
|
|
27
|
+
prefix?: unknown;
|
|
28
|
+
domain?: unknown;
|
|
29
|
+
name?: unknown;
|
|
30
|
+
}) => string;
|
|
24
31
|
export declare const isCanonicalServiceId: (value: unknown) => value is string;
|
|
25
32
|
export declare const toCanonicalServiceId: (args: {
|
|
26
33
|
id?: unknown;
|
|
@@ -34,6 +41,12 @@ export declare const normalizeProjectRuntimeModule: (value: unknown) => ProjectR
|
|
|
34
41
|
export declare const serviceMatchesAllowList: (serviceId: string, serviceName: string, allowList: ReadonlyArray<string>) => boolean;
|
|
35
42
|
declare const _default: Readonly<{
|
|
36
43
|
getServiceId: (domain: string, name: string) => string;
|
|
44
|
+
getDefaultServicePrefix: (domain: string, name: string) => string;
|
|
45
|
+
getServicePrefix: (args: {
|
|
46
|
+
prefix?: unknown;
|
|
47
|
+
domain?: unknown;
|
|
48
|
+
name?: unknown;
|
|
49
|
+
}) => string;
|
|
37
50
|
isCanonicalServiceId: (value: unknown) => value is string;
|
|
38
51
|
toCanonicalServiceId: (args: {
|
|
39
52
|
id?: unknown;
|
|
@@ -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,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,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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"}
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { isArray, isFunction, isNonEmptyString, isObject } from '../helper/index.js';
|
|
2
2
|
export const getServiceId = (domain, name) => `${domain}/${name}`;
|
|
3
|
+
export const getDefaultServicePrefix = (domain, name) => `/${getServiceId(domain, name)}`;
|
|
4
|
+
const normalizeServicePrefix = (value) => {
|
|
5
|
+
const trimmed = value.trim();
|
|
6
|
+
if (trimmed === '' || trimmed === '/')
|
|
7
|
+
return '/';
|
|
8
|
+
const segments = trimmed
|
|
9
|
+
.split('/')
|
|
10
|
+
.map((segment) => segment.trim())
|
|
11
|
+
.filter((segment) => segment.length > 0);
|
|
12
|
+
if (segments.length === 0)
|
|
13
|
+
return '/';
|
|
14
|
+
return `/${segments.join('/')}`;
|
|
15
|
+
};
|
|
16
|
+
export const getServicePrefix = (args) => {
|
|
17
|
+
if (typeof args.prefix === 'string')
|
|
18
|
+
return normalizeServicePrefix(args.prefix);
|
|
19
|
+
const domain = isNonEmptyString(args.domain) ? args.domain : 'default';
|
|
20
|
+
const name = isNonEmptyString(args.name) ? args.name : 'unknown';
|
|
21
|
+
return getDefaultServicePrefix(domain, name);
|
|
22
|
+
};
|
|
3
23
|
export const isCanonicalServiceId = (value) => {
|
|
4
24
|
if (!isNonEmptyString(value))
|
|
5
25
|
return false;
|
|
@@ -22,6 +42,10 @@ export const isServiceManifestEntry = (value) => {
|
|
|
22
42
|
return false;
|
|
23
43
|
if (!isNonEmptyString(value['name']))
|
|
24
44
|
return false;
|
|
45
|
+
const prefix = value['prefix'];
|
|
46
|
+
if (prefix !== undefined && typeof prefix !== 'string') {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
25
49
|
const loadRoutes = value['loadRoutes'];
|
|
26
50
|
if (loadRoutes !== undefined && !isFunction(loadRoutes)) {
|
|
27
51
|
return false;
|
|
@@ -34,6 +58,7 @@ export const normalizeServiceManifest = (value) => {
|
|
|
34
58
|
return value.filter(isServiceManifestEntry).map((entry) => ({
|
|
35
59
|
...entry,
|
|
36
60
|
id: toCanonicalServiceId(entry),
|
|
61
|
+
prefix: getServicePrefix(entry),
|
|
37
62
|
monolithEnabled: entry.monolithEnabled !== false,
|
|
38
63
|
}));
|
|
39
64
|
};
|
|
@@ -72,6 +97,8 @@ export const serviceMatchesAllowList = (serviceId, serviceName, allowList) => {
|
|
|
72
97
|
};
|
|
73
98
|
export default Object.freeze({
|
|
74
99
|
getServiceId,
|
|
100
|
+
getDefaultServicePrefix,
|
|
101
|
+
getServicePrefix,
|
|
75
102
|
isCanonicalServiceId,
|
|
76
103
|
toCanonicalServiceId,
|
|
77
104
|
isServiceManifestEntry,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginAutoImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginAutoImports.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,KAAK,YAAY,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,eAAe,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;
|
|
1
|
+
{"version":3,"file":"PluginAutoImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginAutoImports.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,KAAK,YAAY,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,eAAe,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA6MN,eAAO,MAAM,iBAAiB;uCACY,uBAAuB,GAAY,OAAO,CAAC,YAAY,CAAC;IAkBhG;;;;;;OAMG;mCACkC,OAAO,CAAC,YAAY,CAAC;qCAkEnB,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;EAavE,CAAC"}
|
|
@@ -94,6 +94,47 @@ const resolveLocalPackageSpecifier = (specifier) => {
|
|
|
94
94
|
return null;
|
|
95
95
|
return pathToFileURL(resolved).href;
|
|
96
96
|
};
|
|
97
|
+
const isMissingPackageImport = (error, specifier) => {
|
|
98
|
+
if (specifier.startsWith('.'))
|
|
99
|
+
return false;
|
|
100
|
+
if (error === null || typeof error !== 'object')
|
|
101
|
+
return false;
|
|
102
|
+
const maybe = error;
|
|
103
|
+
const message = typeof maybe.message === 'string' ? maybe.message : '';
|
|
104
|
+
if (maybe.code === 'ERR_MODULE_NOT_FOUND' && message.length === 0)
|
|
105
|
+
return true;
|
|
106
|
+
if (maybe.code === 'ERR_MODULE_NOT_FOUND' && message.includes(specifier))
|
|
107
|
+
return true;
|
|
108
|
+
return (message.includes(`Cannot find package '${specifier}'`) ||
|
|
109
|
+
message.includes(`Cannot find module '${specifier}'`));
|
|
110
|
+
};
|
|
111
|
+
const getMissingPackageStatus = (error, specifier) => {
|
|
112
|
+
if (isMissingPackageImport(error, specifier)) {
|
|
113
|
+
Logger.debug('[plugins] Optional auto-import package not installed', {
|
|
114
|
+
specifier,
|
|
115
|
+
});
|
|
116
|
+
return 'missing';
|
|
117
|
+
}
|
|
118
|
+
return 'failed';
|
|
119
|
+
};
|
|
120
|
+
const importFromLocalFallback = async (specifier, fallback) => {
|
|
121
|
+
try {
|
|
122
|
+
await import(fallback);
|
|
123
|
+
Logger.debug('[plugins] Loaded auto-import specifier from local fallback', {
|
|
124
|
+
specifier,
|
|
125
|
+
fallback,
|
|
126
|
+
});
|
|
127
|
+
return 'loaded';
|
|
128
|
+
}
|
|
129
|
+
catch (fallbackError) {
|
|
130
|
+
Logger.debug('[plugins] Failed auto-import local fallback', {
|
|
131
|
+
specifier,
|
|
132
|
+
fallback,
|
|
133
|
+
error: fallbackError instanceof Error ? fallbackError.message : String(fallbackError),
|
|
134
|
+
});
|
|
135
|
+
return getMissingPackageStatus(fallbackError, specifier);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
97
138
|
const importSingleSpecifier = async (entry) => {
|
|
98
139
|
const target = entry.specifier.startsWith('.')
|
|
99
140
|
? resolveRelativeSpecifier(entry)
|
|
@@ -101,52 +142,48 @@ const importSingleSpecifier = async (entry) => {
|
|
|
101
142
|
try {
|
|
102
143
|
await import(target);
|
|
103
144
|
Logger.debug('[plugins] Loaded auto-import specifier', { specifier: entry.specifier });
|
|
104
|
-
return
|
|
145
|
+
return 'loaded';
|
|
105
146
|
}
|
|
106
|
-
catch {
|
|
147
|
+
catch (error) {
|
|
107
148
|
const fallback = resolveLocalPackageSpecifier(entry.specifier);
|
|
108
|
-
if (fallback !== null)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Logger.debug('[plugins] Loaded auto-import specifier from local fallback', {
|
|
112
|
-
specifier: entry.specifier,
|
|
113
|
-
fallback,
|
|
114
|
-
});
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
catch (fallbackError) {
|
|
118
|
-
Logger.debug('[plugins] Failed auto-import local fallback', {
|
|
119
|
-
specifier: entry.specifier,
|
|
120
|
-
fallback,
|
|
121
|
-
error: fallbackError instanceof Error ? fallbackError.message : String(fallbackError),
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return false;
|
|
149
|
+
if (fallback !== null)
|
|
150
|
+
return importFromLocalFallback(entry.specifier, fallback);
|
|
151
|
+
return getMissingPackageStatus(error, entry.specifier);
|
|
126
152
|
}
|
|
127
153
|
};
|
|
128
154
|
const importSpecifiers = async (specifiers) => {
|
|
129
155
|
// Import all specifiers in parallel
|
|
130
156
|
const importPromises = Array.from(specifiers).map(async (entry) => {
|
|
131
|
-
const
|
|
132
|
-
return { specifier: entry.specifier,
|
|
157
|
+
const status = await importSingleSpecifier(entry);
|
|
158
|
+
return { specifier: entry.specifier, status };
|
|
133
159
|
});
|
|
134
160
|
const results = await Promise.allSettled(importPromises);
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
return results.reduce((summary, result) => {
|
|
162
|
+
if (result.status !== 'fulfilled') {
|
|
163
|
+
summary.failed += 1;
|
|
164
|
+
return summary;
|
|
165
|
+
}
|
|
166
|
+
if (result.value.status === 'loaded')
|
|
167
|
+
summary.loaded += 1;
|
|
168
|
+
else if (result.value.status === 'missing')
|
|
169
|
+
summary.missing += 1;
|
|
170
|
+
else
|
|
171
|
+
summary.failed += 1;
|
|
172
|
+
return summary;
|
|
173
|
+
}, { loaded: 0, missing: 0, failed: 0 });
|
|
137
174
|
};
|
|
138
175
|
export const PluginAutoImports = Object.freeze({
|
|
139
176
|
async tryImportRuntimeAutoImports(mode = 'base') {
|
|
140
177
|
const specifiers = OfficialPlugins.getAutoImports(mode);
|
|
141
|
-
const
|
|
142
|
-
if (
|
|
178
|
+
const summary = await importSpecifiers(specifiers.map((specifier) => ({ specifier, filePath: `official:${mode}` })));
|
|
179
|
+
if (summary.failed === 0) {
|
|
143
180
|
return { ok: true, loadedPath: `official:${mode}` };
|
|
144
181
|
}
|
|
145
182
|
return {
|
|
146
183
|
ok: false,
|
|
147
184
|
loadedPath: `official:${mode}`,
|
|
148
185
|
reason: 'import-failed',
|
|
149
|
-
errorMessage: `Loaded ${loaded}/${specifiers.length} official plugin imports`,
|
|
186
|
+
errorMessage: `Loaded ${summary.loaded}/${specifiers.length} official plugin imports`,
|
|
150
187
|
};
|
|
151
188
|
},
|
|
152
189
|
/**
|
|
@@ -209,8 +246,8 @@ export const PluginAutoImports = Object.freeze({
|
|
|
209
246
|
if (specifiers.length === 0) {
|
|
210
247
|
return { ok: false, reason: 'import-failed', errorMessage: 'No import specifiers found' };
|
|
211
248
|
}
|
|
212
|
-
const
|
|
213
|
-
if (loaded > 0) {
|
|
249
|
+
const summary = await importSpecifiers(specifiers);
|
|
250
|
+
if (summary.loaded > 0) {
|
|
214
251
|
return { ok: true, loadedPath: 'manual-imports' };
|
|
215
252
|
}
|
|
216
253
|
return { ok: false, reason: 'import-failed', errorMessage: 'All specifier imports failed' };
|