@zintrust/core 0.4.13 → 0.4.14
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.map +1 -1
- package/src/boot/registry/registerRoute.js +59 -7
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +84 -5
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +4 -1
- package/src/config/env.d.ts.map +1 -1
- package/src/config/env.js +13 -0
- package/src/functions/cloudflare.d.ts.map +1 -1
- package/src/functions/cloudflare.js +21 -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/orm/Database.d.ts.map +1 -1
- package/src/orm/Database.js +5 -2
- package/src/orm/DatabaseConnectionRegistry.d.ts +8 -0
- package/src/orm/DatabaseConnectionRegistry.d.ts.map +1 -0
- package/src/orm/DatabaseConnectionRegistry.js +13 -0
- package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
- package/src/orm/DatabaseRuntimeRegistration.js +4 -2
- package/src/runtime/ProjectBootstrap.d.ts +6 -0
- package/src/runtime/ProjectBootstrap.d.ts.map +1 -0
- package/src/runtime/ProjectBootstrap.js +43 -0
- package/src/runtime/ProjectRuntime.d.ts.map +1 -1
- package/src/runtime/ProjectRuntime.js +5 -2
- package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/CloudflareAdapter.js +8 -2
- package/src/start.js +2 -4
package/package.json
CHANGED
|
@@ -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;
|
|
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;AAiKF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,MAAM,EACxB,QAAQ,OAAO,KACd,OAAO,CAAC,IAAI,CAqBd,CAAC"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { appConfig } from '../../config/index.js';
|
|
2
2
|
import Logger from '../../config/logger.js';
|
|
3
3
|
import { Router } from '../../routes/Router.js';
|
|
4
|
-
import { isObject } from '../../helper/index.js';
|
|
5
|
-
import { getServicePrefix } from '../../microservices/ServiceManifest.js';
|
|
4
|
+
import { isNonEmptyString, isObject } from '../../helper/index.js';
|
|
6
5
|
import * as path from '../../node-singletons/path.js';
|
|
7
6
|
import { pathToFileURL } from '../../node-singletons/url.js';
|
|
8
7
|
import { detectRuntime } from '../../runtime/detectRuntime.js';
|
|
@@ -63,23 +62,75 @@ const registerAppRoutes = async (resolvedBasePath, router) => {
|
|
|
63
62
|
mod.registerRoutes(router);
|
|
64
63
|
}
|
|
65
64
|
};
|
|
65
|
+
const getProjectRoot = () => {
|
|
66
|
+
const fromEnv = process.env?.['ZINTRUST_PROJECT_ROOT'] ?? '';
|
|
67
|
+
if (fromEnv.trim() !== '')
|
|
68
|
+
return fromEnv.trim();
|
|
69
|
+
return process.cwd();
|
|
70
|
+
};
|
|
71
|
+
const resolveManifestServiceEnvDir = (projectRoot, entry) => {
|
|
72
|
+
const configRoot = entry.configRoot;
|
|
73
|
+
if (isNonEmptyString(configRoot)) {
|
|
74
|
+
return path.dirname(path.join(projectRoot, configRoot));
|
|
75
|
+
}
|
|
76
|
+
return path.join(projectRoot, 'src', 'services', entry.domain, entry.name);
|
|
77
|
+
};
|
|
78
|
+
const resolveServicePrefix = (entry) => {
|
|
79
|
+
const prefix = entry.prefix;
|
|
80
|
+
if (isNonEmptyString(prefix)) {
|
|
81
|
+
const segments = prefix
|
|
82
|
+
.split('/')
|
|
83
|
+
.map((segment) => segment.trim())
|
|
84
|
+
.filter((segment) => segment !== '');
|
|
85
|
+
return segments.length === 0 ? '/' : `/${segments.join('/')}`;
|
|
86
|
+
}
|
|
87
|
+
return `/${entry.domain}/${entry.name}`;
|
|
88
|
+
};
|
|
89
|
+
const ensureManifestServiceEnvLoaded = async (entry) => {
|
|
90
|
+
if (isCloudflare)
|
|
91
|
+
return;
|
|
92
|
+
const { EnvFileLoader } = await import('../../cli/utils/EnvFileLoader.js');
|
|
93
|
+
const projectRoot = getProjectRoot();
|
|
94
|
+
const envPath = resolveManifestServiceEnvDir(projectRoot, entry);
|
|
95
|
+
EnvFileLoader.ensureLoaded({
|
|
96
|
+
cwd: projectRoot,
|
|
97
|
+
includeCwd: true,
|
|
98
|
+
envPaths: [envPath],
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
const registerLoadedRoutes = (router, entry, registerRoutes, activeService) => {
|
|
102
|
+
const servicePrefix = resolveServicePrefix(entry);
|
|
103
|
+
if (activeService?.id === entry.id) {
|
|
104
|
+
registerRoutes(router);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
Router.group(router, servicePrefix, (scopedRouter) => {
|
|
108
|
+
registerRoutes(scopedRouter);
|
|
109
|
+
});
|
|
110
|
+
};
|
|
66
111
|
const registerManifestRoutes = async (router) => {
|
|
67
112
|
await ProjectRuntime.tryLoadNodeRuntime();
|
|
68
113
|
const serviceManifest = ProjectRuntime.getServiceManifest();
|
|
69
114
|
if (serviceManifest.length === 0)
|
|
70
115
|
return;
|
|
116
|
+
const activeService = ProjectRuntime.getActiveService();
|
|
117
|
+
if (activeService !== undefined && isCloudflare)
|
|
118
|
+
return;
|
|
71
119
|
for (const entry of serviceManifest) {
|
|
72
120
|
if (entry.monolithEnabled === false || typeof entry.loadRoutes !== 'function') {
|
|
73
121
|
continue;
|
|
74
122
|
}
|
|
123
|
+
if (activeService !== undefined && activeService.id !== entry.id) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
75
126
|
try {
|
|
127
|
+
// eslint-disable-next-line no-await-in-loop
|
|
128
|
+
await ensureManifestServiceEnvLoaded(entry);
|
|
76
129
|
// eslint-disable-next-line no-await-in-loop
|
|
77
130
|
const mod = await entry.loadRoutes();
|
|
78
131
|
const registerRoutes = isObject(mod) ? mod.registerRoutes : undefined;
|
|
79
132
|
if (typeof registerRoutes === 'function') {
|
|
80
|
-
|
|
81
|
-
registerRoutes(scopedRouter);
|
|
82
|
-
});
|
|
133
|
+
registerLoadedRoutes(router, entry, registerRoutes, activeService);
|
|
83
134
|
}
|
|
84
135
|
}
|
|
85
136
|
catch (error) {
|
|
@@ -104,14 +155,15 @@ const registerGlobalRoutes = (router) => {
|
|
|
104
155
|
};
|
|
105
156
|
export const registerMasterRoutes = async (resolvedBasePath, router) => {
|
|
106
157
|
try {
|
|
158
|
+
const activeService = ProjectRuntime.getActiveService();
|
|
107
159
|
if (isCloudflare) {
|
|
108
160
|
registerGlobalRoutes(router);
|
|
109
161
|
}
|
|
110
|
-
if (!isCloudflare) {
|
|
162
|
+
if (!isCloudflare && activeService === undefined) {
|
|
111
163
|
await registerAppRoutes(resolvedBasePath, router);
|
|
112
164
|
}
|
|
113
165
|
await registerManifestRoutes(router);
|
|
114
|
-
if (router.routes.length === 0) {
|
|
166
|
+
if (router.routes.length === 0 && activeService === undefined) {
|
|
115
167
|
await registerFrameworkRoutes(resolvedBasePath, router);
|
|
116
168
|
}
|
|
117
169
|
// Always register core framework routes (health, metrics, doc) after app routes
|
|
@@ -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;AA21BvF,eAAO,MAAM,YAAY;cACb,YAAY;EAmCtB,CAAC"}
|
|
@@ -2,11 +2,15 @@ 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';
|
|
5
6
|
import { readEnvString } from '../../common/ExternalServiceUtils.js';
|
|
6
7
|
import * as Common from '../../common/index.js';
|
|
7
8
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
8
|
-
import {
|
|
9
|
+
import { isNonEmptyString } from '../../helper/index.js';
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from '../../node-singletons/fs.js';
|
|
9
11
|
import * as path from '../../node-singletons/path.js';
|
|
12
|
+
import { ProjectRuntime } from '../../runtime/ProjectRuntime.js';
|
|
13
|
+
const isWranglerVarName = (value) => /^[A-Za-z_]\w*$/.test(value);
|
|
10
14
|
const isAbsolutePath = (value) => value.startsWith('/') || /^[A-Za-z]:[\\/]/.test(value);
|
|
11
15
|
const resolveNpmPath = () => {
|
|
12
16
|
try {
|
|
@@ -231,6 +235,55 @@ const buildStartEnv = (projectRoot) => ({
|
|
|
231
235
|
...process.env,
|
|
232
236
|
ZINTRUST_PROJECT_ROOT: projectRoot,
|
|
233
237
|
});
|
|
238
|
+
const buildWorkerDevVarsContent = () => {
|
|
239
|
+
return (Object.entries(process.env)
|
|
240
|
+
.filter((entry) => {
|
|
241
|
+
const [key, value] = entry;
|
|
242
|
+
return isWranglerVarName(key) && typeof value === 'string';
|
|
243
|
+
})
|
|
244
|
+
.map(([key, value]) => `${key}=${JSON.stringify(value)}`)
|
|
245
|
+
.join('\n') + '\n');
|
|
246
|
+
};
|
|
247
|
+
async function withWranglerEnvSnapshot(cwd, envName, fn) {
|
|
248
|
+
const normalizedEnv = typeof envName === 'string' ? envName.trim() : '';
|
|
249
|
+
const targetName = normalizedEnv === '' ? '.dev.vars' : `.dev.vars.${normalizedEnv}`;
|
|
250
|
+
const targetPath = path.join(cwd, targetName);
|
|
251
|
+
const backupPath = existsSync(targetPath)
|
|
252
|
+
? `${targetPath}.disabled-by-zin-${generateUuid()}`
|
|
253
|
+
: undefined;
|
|
254
|
+
if (backupPath !== undefined) {
|
|
255
|
+
renameSync(targetPath, backupPath);
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
writeFileSync(targetPath, buildWorkerDevVarsContent(), 'utf-8');
|
|
259
|
+
return await fn();
|
|
260
|
+
}
|
|
261
|
+
finally {
|
|
262
|
+
try {
|
|
263
|
+
if (existsSync(targetPath))
|
|
264
|
+
unlinkSync(targetPath);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// noop
|
|
268
|
+
}
|
|
269
|
+
if (backupPath !== undefined) {
|
|
270
|
+
try {
|
|
271
|
+
if (existsSync(backupPath))
|
|
272
|
+
renameSync(backupPath, targetPath);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
// noop
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const resolveManifestServiceEnvDir = (projectRoot, entry) => {
|
|
281
|
+
const configRoot = entry.configRoot;
|
|
282
|
+
if (isNonEmptyString(configRoot)) {
|
|
283
|
+
return path.dirname(path.join(projectRoot, configRoot));
|
|
284
|
+
}
|
|
285
|
+
return path.join(projectRoot, 'src', 'services', entry.domain, entry.name);
|
|
286
|
+
};
|
|
234
287
|
const ensureStartEnvLoaded = (context, options) => {
|
|
235
288
|
const envPath = resolveEnvPath(options, context.projectRoot);
|
|
236
289
|
const rootEnv = resolveRootEnvPreference(options);
|
|
@@ -242,6 +295,28 @@ const ensureStartEnvLoaded = (context, options) => {
|
|
|
242
295
|
...(envPath === undefined ? {} : { envPaths: [envPath] }),
|
|
243
296
|
});
|
|
244
297
|
};
|
|
298
|
+
const preloadManifestServiceEnv = async (context, options) => {
|
|
299
|
+
if (context.cwd !== context.projectRoot)
|
|
300
|
+
return;
|
|
301
|
+
if (resolveEnvPath(options, context.projectRoot) !== undefined)
|
|
302
|
+
return;
|
|
303
|
+
process.env['ZINTRUST_PROJECT_ROOT'] = context.projectRoot;
|
|
304
|
+
ProjectRuntime.clear();
|
|
305
|
+
await ProjectRuntime.tryLoadNodeRuntime();
|
|
306
|
+
const manifest = ProjectRuntime.getServiceManifest().filter((entry) => entry.monolithEnabled !== false);
|
|
307
|
+
if (manifest.length === 0)
|
|
308
|
+
return;
|
|
309
|
+
const envPaths = manifest
|
|
310
|
+
.map((entry) => resolveManifestServiceEnvDir(context.projectRoot, entry))
|
|
311
|
+
.filter((value, index, items) => items.indexOf(value) === index);
|
|
312
|
+
if (envPaths.length === 0)
|
|
313
|
+
return;
|
|
314
|
+
EnvFileLoader.ensureLoaded({
|
|
315
|
+
cwd: context.projectRoot,
|
|
316
|
+
includeCwd: resolveRootEnvPreference(options),
|
|
317
|
+
envPaths,
|
|
318
|
+
});
|
|
319
|
+
};
|
|
245
320
|
const isFrameworkRepo = (packageJson) => packageJson.name === '@zintrust/core';
|
|
246
321
|
const hasDevScript = (packageJson) => {
|
|
247
322
|
const scripts = packageJson.scripts;
|
|
@@ -358,10 +433,12 @@ const executeWranglerStart = async (cmd, context, port, runtime, envName, wrangl
|
|
|
358
433
|
}
|
|
359
434
|
logMySqlProxyHint(cmd);
|
|
360
435
|
cmd.info('Starting in Wrangler dev mode...');
|
|
361
|
-
const exitCode = await
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
436
|
+
const exitCode = await withWranglerEnvSnapshot(context.cwd, envName, async () => {
|
|
437
|
+
return SpawnUtil.spawnAndWait({
|
|
438
|
+
command: 'wrangler',
|
|
439
|
+
args: wranglerArgs,
|
|
440
|
+
env: buildStartEnv(context.projectRoot),
|
|
441
|
+
});
|
|
365
442
|
});
|
|
366
443
|
process.exit(exitCode);
|
|
367
444
|
};
|
|
@@ -511,7 +588,9 @@ const executeSplitStart = async (cmd, context, _options) => {
|
|
|
511
588
|
const executeStart = async (options, cmd) => {
|
|
512
589
|
const cwd = process.cwd();
|
|
513
590
|
const context = resolveStartContext(cwd);
|
|
591
|
+
process.env['ZINTRUST_PROJECT_ROOT'] = context.projectRoot;
|
|
514
592
|
ensureStartEnvLoaded(context, options);
|
|
593
|
+
await preloadManifestServiceEnv(context, options);
|
|
515
594
|
const mode = resolveMode(options);
|
|
516
595
|
const port = resolvePort(options);
|
|
517
596
|
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;
|
|
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;AAkcD,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC"}
|
|
@@ -9,6 +9,7 @@ const coreModuleSpecifier = ['@zintrust', 'core'].join('/');
|
|
|
9
9
|
const coreStartModuleSpecifier = `${coreModuleSpecifier}/start`;
|
|
10
10
|
const serviceManifestImportExpression = "import('./bootstrap/service-manifest.ts').catch(() => import('./bootstrap/service-manifest.js'))";
|
|
11
11
|
const buildRouteImportExpression = (domain, serviceName) => `import('../services/${domain}/${serviceName}/routes/api.ts').catch(() => import('../services/${domain}/${serviceName}/routes/api.js'))`;
|
|
12
|
+
const getServiceConfigRoot = (domain, serviceName) => `src/services/${domain}/${serviceName}/config`;
|
|
12
13
|
/**
|
|
13
14
|
* ServiceScaffolder generates microservices with all necessary files
|
|
14
15
|
*/
|
|
@@ -107,6 +108,7 @@ export const serviceManifest: ReadonlyArray<ServiceManifestEntry> = [
|
|
|
107
108
|
id: '${serviceId}',
|
|
108
109
|
domain: '${domain}',
|
|
109
110
|
name: '${options.name}',
|
|
111
|
+
configRoot: '${getServiceConfigRoot(domain, options.name)}',
|
|
110
112
|
prefix: '${serviceId}',
|
|
111
113
|
port: ${options.port ?? 3001},
|
|
112
114
|
monolithEnabled: true,
|
|
@@ -148,6 +150,7 @@ function updateServiceManifest(projectRoot, options) {
|
|
|
148
150
|
id: '${serviceId}',
|
|
149
151
|
domain: '${domain}',
|
|
150
152
|
name: '${options.name}',
|
|
153
|
+
configRoot: '${getServiceConfigRoot(domain, options.name)}',
|
|
151
154
|
prefix: '${serviceId}',
|
|
152
155
|
port: ${options.port ?? 3001},
|
|
153
156
|
monolithEnabled: true,
|
|
@@ -236,7 +239,7 @@ function generateServiceConfig(options) {
|
|
|
236
239
|
function generateServiceIndex(options) {
|
|
237
240
|
const domain = options.domain ?? 'default';
|
|
238
241
|
const serviceId = `${domain}/${options.name}`;
|
|
239
|
-
const configRoot =
|
|
242
|
+
const configRoot = getServiceConfigRoot(domain, options.name);
|
|
240
243
|
return `/**
|
|
241
244
|
* ${options.name} Service - Entry Point
|
|
242
245
|
* Port: ${options.port ?? 3001}
|
package/src/config/env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/config/env.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/config/env.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAsClF,eAAO,MAAM,cAAc,QAAO,WAAW,GAAG,SAAwB,CAAC;AAEzE,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,EAAE,WAAW,MAAM,KAAG,MAKzE,CAAC;AAGF,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,eAAe,MAAM,KAAG,MAIxD,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,KAAK,MAAM,EAAE,cAAc,MAAM,KAAG,MAI1D,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,eAAe,MAAM,KAAG,MAI7D,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,EAAE,eAAe,OAAO,KAAG,OAI7D,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,OAAO,MAAM,KAAG,IAGhD,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,KAAK,MAAM,KAAG,IAInC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,QAAQ,SAAS,GAAG,IAAI,KAAG,IAEpD,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAOhD,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAKjE,CAAC;AACF,eAAO,MAAM,mBAAmB,QAAuC,CAAC;AAKxE,eAAO,MAAM,GAAG;eA3DS,MAAM,iBAAiB,MAAM,KAAG,MAAM;kBAMnC,MAAM,gBAAgB,MAAM,KAAG,MAAM;mBAYpC,MAAM,iBAAiB,OAAO,KAAG,OAAO;oBANvC,MAAM,iBAAiB,MAAM,KAAG,MAAM;eAY3C,MAAM,SAAS,MAAM,KAAG,IAAI;iBAK1B,MAAM,KAAG,IAAI;wBAMN,SAAS,GAAG,IAAI,KAAG,IAAI;oBAI7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;cAgCJ,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAgOpB,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoFxF,CAAC;AAEH,eAAO,MAAM,aAAa,QAAO,MAchC,CAAC"}
|
package/src/config/env.js
CHANGED
|
@@ -8,11 +8,24 @@
|
|
|
8
8
|
// Cache process check once at module load time
|
|
9
9
|
const processLike = typeof process === 'undefined' ? undefined : process;
|
|
10
10
|
let externalEnvSource = null;
|
|
11
|
+
const getGlobalEnv = () => {
|
|
12
|
+
const env = globalThis.env;
|
|
13
|
+
if (env === undefined || env === null || typeof env !== 'object')
|
|
14
|
+
return undefined;
|
|
15
|
+
return env;
|
|
16
|
+
};
|
|
11
17
|
const getEnvSource = () => {
|
|
12
18
|
if (typeof externalEnvSource === 'function')
|
|
13
19
|
return externalEnvSource();
|
|
14
20
|
if (externalEnvSource !== null)
|
|
15
21
|
return externalEnvSource;
|
|
22
|
+
const globalEnv = getGlobalEnv();
|
|
23
|
+
if (globalEnv !== undefined) {
|
|
24
|
+
return {
|
|
25
|
+
...processLike?.env,
|
|
26
|
+
...globalEnv,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
16
29
|
return processLike?.env ?? {};
|
|
17
30
|
};
|
|
18
31
|
const normalizeEnvValue = (value) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/functions/cloudflare.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/functions/cloudflare.ts"],"names":[],"mappings":";mBA0JuB,OAAO,QAAQ,OAAO,QAAQ,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;;AADhF,wBAoCE"}
|
|
@@ -101,6 +101,25 @@ const injectIoredisModule = async () => {
|
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
let startupConfigOverridesPromise;
|
|
104
|
+
const WORKER_ENV_SNAPSHOT_KEY = 'ZINTRUST_WORKER_ENV_SNAPSHOT';
|
|
105
|
+
const resolveWorkersEnv = (env) => {
|
|
106
|
+
const bindings = typeof env === 'object' && env !== null ? { ...env } : {};
|
|
107
|
+
const rawSnapshot = bindings[WORKER_ENV_SNAPSHOT_KEY];
|
|
108
|
+
if (typeof rawSnapshot !== 'string' || rawSnapshot.trim() === '') {
|
|
109
|
+
return bindings;
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(rawSnapshot);
|
|
113
|
+
Reflect.deleteProperty(bindings, WORKER_ENV_SNAPSHOT_KEY);
|
|
114
|
+
return {
|
|
115
|
+
...parsed,
|
|
116
|
+
...bindings,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return bindings;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
104
123
|
const ensureStartupConfigOverridesLoaded = async () => {
|
|
105
124
|
startupConfigOverridesPromise ??= applyStartupConfigOverrides();
|
|
106
125
|
await startupConfigOverridesPromise;
|
|
@@ -108,8 +127,9 @@ const ensureStartupConfigOverridesLoaded = async () => {
|
|
|
108
127
|
export default {
|
|
109
128
|
async fetch(request, _env, _ctx) {
|
|
110
129
|
try {
|
|
130
|
+
const workersEnv = resolveWorkersEnv(_env);
|
|
111
131
|
// Make bindings available to framework code in Workers
|
|
112
|
-
globalThis.env =
|
|
132
|
+
globalThis.env = workersEnv;
|
|
113
133
|
const AppRoutes = (await import('@routes/' + 'api.ts'));
|
|
114
134
|
if (AppRoutes !== undefined) {
|
|
115
135
|
globalThis.__zintrustRoutes = AppRoutes;
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core v0.4.
|
|
2
|
+
* @zintrust/core v0.4.14
|
|
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-23T16:59:39.933Z
|
|
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-23T16:59:39.858Z'; // 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,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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"}
|
|
@@ -46,6 +46,10 @@ export const isServiceManifestEntry = (value) => {
|
|
|
46
46
|
if (prefix !== undefined && typeof prefix !== 'string') {
|
|
47
47
|
return false;
|
|
48
48
|
}
|
|
49
|
+
const configRoot = value['configRoot'];
|
|
50
|
+
if (configRoot !== undefined && typeof configRoot !== 'string') {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
49
53
|
const loadRoutes = value['loadRoutes'];
|
|
50
54
|
if (loadRoutes !== undefined && !isFunction(loadRoutes)) {
|
|
51
55
|
return false;
|
|
@@ -59,6 +63,7 @@ export const normalizeServiceManifest = (value) => {
|
|
|
59
63
|
...entry,
|
|
60
64
|
id: toCanonicalServiceId(entry),
|
|
61
65
|
prefix: getServicePrefix(entry),
|
|
66
|
+
...(isNonEmptyString(entry.configRoot) ? { configRoot: entry.configRoot } : {}),
|
|
62
67
|
monolithEnabled: entry.monolithEnabled !== false,
|
|
63
68
|
}));
|
|
64
69
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../../src/orm/Database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../../src/orm/Database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAYxD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,SAAS;IACxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,WAAW,IAAI,OAAO,CAAC;IACvB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACjF,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACpE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;IACnC,aAAa,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACzE,YAAY,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1F,cAAc,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1E,aAAa,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3F,kBAAkB,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;IACvD,OAAO,IAAI,eAAe,CAAC;IAC3B,SAAS,IAAI,cAAc,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAqhBD,eAAO,MAAM,QAAQ;IACnB;;OAEG;oBACa,cAAc,GAAG,SAAS;EAI1C,CAAC;AAIH,eAAO,MAAM,oBAAoB,GAC/B,SAAQ,cAAc,GAAG,SAAqB,EAC9C,uBAA0B,KACzB,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAMxC,CAAC;AAEF,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,UAAU,SAAY,GAAG,SAAS,CAsBtF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAYnD"}
|
package/src/orm/Database.js
CHANGED
|
@@ -12,6 +12,7 @@ import { D1Adapter } from './adapters/D1Adapter.js';
|
|
|
12
12
|
import { D1RemoteAdapter } from './adapters/D1RemoteAdapter.js';
|
|
13
13
|
import { MySQLAdapter } from './adapters/MySQLAdapter.js';
|
|
14
14
|
import { MySQLProxyAdapter } from './adapters/MySQLProxyAdapter.js';
|
|
15
|
+
import { DatabaseConnectionRegistry } from './DatabaseConnectionRegistry.js';
|
|
15
16
|
import { PostgreSQLAdapter } from './adapters/PostgreSQLAdapter.js';
|
|
16
17
|
import { PostgreSQLProxyAdapter } from './adapters/PostgreSQLProxyAdapter.js';
|
|
17
18
|
import { SQLiteAdapter } from './adapters/SQLiteAdapter.js';
|
|
@@ -432,14 +433,15 @@ export const useEnsureDbConnected = async (config = undefined, connectionName =
|
|
|
432
433
|
};
|
|
433
434
|
export function useDatabase(config, connection = 'default') {
|
|
434
435
|
if (databaseInstances.has(connection) === false) {
|
|
435
|
-
|
|
436
|
+
const resolvedConfig = config ?? DatabaseConnectionRegistry.get(connection);
|
|
437
|
+
if (resolvedConfig === undefined) {
|
|
436
438
|
// Diagnostic logging
|
|
437
439
|
Logger.error('[DEBUG] Database instances keys:', Array.from(databaseInstances.keys()));
|
|
438
440
|
Logger.error('[DEBUG] Requesting connection:', connection);
|
|
439
441
|
throw ErrorFactory.createConfigError(`Database connection '${connection}' is not registered. ` +
|
|
440
442
|
`Call useDatabase(config, '${connection}') during startup to register it.`);
|
|
441
443
|
}
|
|
442
|
-
databaseInstances.set(connection, Database.create(
|
|
444
|
+
databaseInstances.set(connection, Database.create(resolvedConfig));
|
|
443
445
|
}
|
|
444
446
|
const instance = databaseInstances.get(connection);
|
|
445
447
|
if (instance === undefined) {
|
|
@@ -459,4 +461,5 @@ export async function resetDatabase() {
|
|
|
459
461
|
});
|
|
460
462
|
await Promise.all(promises);
|
|
461
463
|
databaseInstances.clear();
|
|
464
|
+
DatabaseConnectionRegistry.clear();
|
|
462
465
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DatabaseConfig } from './DatabaseAdapter';
|
|
2
|
+
export declare const DatabaseConnectionRegistry: Readonly<{
|
|
3
|
+
clear(): void;
|
|
4
|
+
set(name: string, config: DatabaseConfig): void;
|
|
5
|
+
get(name: string): DatabaseConfig | undefined;
|
|
6
|
+
}>;
|
|
7
|
+
export default DatabaseConnectionRegistry;
|
|
8
|
+
//# sourceMappingURL=DatabaseConnectionRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatabaseConnectionRegistry.d.ts","sourceRoot":"","sources":["../../../src/orm/DatabaseConnectionRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D,eAAO,MAAM,0BAA0B;aAC5B,IAAI;cAIH,MAAM,UAAU,cAAc,GAAG,IAAI;cAIrC,MAAM,GAAG,cAAc,GAAG,SAAS;EAG7C,CAAC;AAEH,eAAe,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const state = new Map();
|
|
2
|
+
export const DatabaseConnectionRegistry = Object.freeze({
|
|
3
|
+
clear() {
|
|
4
|
+
state.clear();
|
|
5
|
+
},
|
|
6
|
+
set(name, config) {
|
|
7
|
+
state.set(name, config);
|
|
8
|
+
},
|
|
9
|
+
get(name) {
|
|
10
|
+
return state.get(name);
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
export default DatabaseConnectionRegistry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseRuntimeRegistration.d.ts","sourceRoot":"","sources":["../../../src/orm/DatabaseRuntimeRegistration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"DatabaseRuntimeRegistration.d.ts","sourceRoot":"","sources":["../../../src/orm/DatabaseRuntimeRegistration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,cAAc,CAAC;AA4DtB;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAapF"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* instances that can be selected via `useDatabase(undefined, name)`.
|
|
6
6
|
*/
|
|
7
7
|
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
8
|
+
import { DatabaseConnectionRegistry } from './DatabaseConnectionRegistry.js';
|
|
8
9
|
import { useDatabase } from './Database.js';
|
|
9
10
|
const toOrmConfig = (cfg) => {
|
|
10
11
|
switch (cfg.driver) {
|
|
@@ -50,9 +51,9 @@ const toOrmConfig = (cfg) => {
|
|
|
50
51
|
}
|
|
51
52
|
};
|
|
52
53
|
const registerConnections = (connections) => {
|
|
54
|
+
DatabaseConnectionRegistry.clear();
|
|
53
55
|
for (const [name, runtimeCfg] of Object.entries(connections)) {
|
|
54
|
-
|
|
55
|
-
useDatabase(toOrmConfig(runtimeCfg), name);
|
|
56
|
+
DatabaseConnectionRegistry.set(name, toOrmConfig(runtimeCfg));
|
|
56
57
|
}
|
|
57
58
|
};
|
|
58
59
|
import { Logger } from '../config/logger.js';
|
|
@@ -71,5 +72,6 @@ export function registerDatabasesFromRuntimeConfig(config) {
|
|
|
71
72
|
throw ErrorFactory.createConfigError(`Database default connection not configured: ${String(config.default ?? '')}`);
|
|
72
73
|
}
|
|
73
74
|
Logger.info(`✓ Registering default database connection: ${config.default}`);
|
|
75
|
+
useDatabase(toOrmConfig(defaultCfg), config.default);
|
|
74
76
|
useDatabase(toOrmConfig(defaultCfg), 'default');
|
|
75
77
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectBootstrap.d.ts","sourceRoot":"","sources":["../../../src/runtime/ProjectBootstrap.ts"],"names":[],"mappings":"AAgCA,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAU1D;;;;AAED,wBAEG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Logger } from '../config/logger.js';
|
|
2
|
+
import { existsSync } from '../node-singletons/fs.js';
|
|
3
|
+
import * as path from '../node-singletons/path.js';
|
|
4
|
+
import { pathToFileURL } from '../node-singletons/url.js';
|
|
5
|
+
const getProjectRoot = () => {
|
|
6
|
+
const fromEnv = process.env?.['ZINTRUST_PROJECT_ROOT'] ?? '';
|
|
7
|
+
if (fromEnv.trim() !== '')
|
|
8
|
+
return fromEnv.trim();
|
|
9
|
+
return process.cwd();
|
|
10
|
+
};
|
|
11
|
+
const getBootstrapCandidates = (projectRoot) => [
|
|
12
|
+
path.join(projectRoot, 'src', 'boot', 'bootstrap.ts'),
|
|
13
|
+
path.join(projectRoot, 'dist', 'src', 'boot', 'bootstrap.js'),
|
|
14
|
+
path.join(projectRoot, 'src', 'boot', 'bootstrap.js'),
|
|
15
|
+
];
|
|
16
|
+
const tryImportBootstrapCandidate = async (candidate) => {
|
|
17
|
+
if (!existsSync(candidate))
|
|
18
|
+
return false;
|
|
19
|
+
try {
|
|
20
|
+
await import(pathToFileURL(candidate).href);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
Logger.warn('Failed to import project bootstrap candidate', {
|
|
25
|
+
candidate,
|
|
26
|
+
error: error instanceof Error ? error.message : String(error),
|
|
27
|
+
});
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export async function loadProjectBootstrap() {
|
|
32
|
+
const projectRoot = getProjectRoot();
|
|
33
|
+
for (const candidate of getBootstrapCandidates(projectRoot)) {
|
|
34
|
+
// eslint-disable-next-line no-await-in-loop
|
|
35
|
+
const loaded = await tryImportBootstrapCandidate(candidate);
|
|
36
|
+
if (loaded)
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await import('../boot/bootstrap.js');
|
|
40
|
+
}
|
|
41
|
+
export default Object.freeze({
|
|
42
|
+
loadProjectBootstrap,
|
|
43
|
+
});
|
|
@@ -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;AA+ExC,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;0BAejD,aAAa,CAAC,oBAAoB,CAAC;wBAIrC,oBAAoB,GAAG,SAAS;EAGpD,CAAC;AAEH,eAAe,cAAc,CAAC"}
|
|
@@ -33,6 +33,9 @@ const cacheProjectRuntime = (module) => {
|
|
|
33
33
|
const getCachedProjectRuntime = () => {
|
|
34
34
|
return getRuntimeGlobal().__zintrustProjectRuntime;
|
|
35
35
|
};
|
|
36
|
+
const hasLoadedServiceManifest = (runtime) => {
|
|
37
|
+
return Array.isArray(runtime?.serviceManifest);
|
|
38
|
+
};
|
|
36
39
|
const tryImportNodeRuntimeCandidate = async (candidate) => {
|
|
37
40
|
if (!existsSync(candidate))
|
|
38
41
|
return undefined;
|
|
@@ -76,7 +79,7 @@ export const ProjectRuntime = Object.freeze({
|
|
|
76
79
|
},
|
|
77
80
|
async tryLoadNodeRuntime() {
|
|
78
81
|
const cached = getCachedProjectRuntime();
|
|
79
|
-
if (cached
|
|
82
|
+
if (hasLoadedServiceManifest(cached))
|
|
80
83
|
return cached;
|
|
81
84
|
const projectRoot = getProjectRoot();
|
|
82
85
|
const candidates = getNodeRuntimeCandidates(projectRoot);
|
|
@@ -90,7 +93,7 @@ export const ProjectRuntime = Object.freeze({
|
|
|
90
93
|
},
|
|
91
94
|
async tryLoadWorkerRuntime() {
|
|
92
95
|
const cached = getCachedProjectRuntime();
|
|
93
|
-
if (cached
|
|
96
|
+
if (hasLoadedServiceManifest(cached))
|
|
94
97
|
return cached;
|
|
95
98
|
const workerModuleIds = ['../' + 'zintrust.runtime.wg.js', '../' + 'zintrust.runtime.js'];
|
|
96
99
|
for (const moduleId of workerModuleIds) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudflareAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/adapters/CloudflareAdapter.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,aAAa,EAGb,cAAc,EACf,MAAM,yBAAyB,CAAC;AAGjC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;IAC5B;;OAEG;mBACY,aAAa,GAAG,cAAc;
|
|
1
|
+
{"version":3,"file":"CloudflareAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/adapters/CloudflareAdapter.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,aAAa,EAGb,cAAc,EACf,MAAM,yBAAyB,CAAC;AAGjC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;IAC5B;;OAEG;mBACY,aAAa,GAAG,cAAc;IA8D7C;;;OAGG;qBACc,OAAO;IAKxB;;;OAGG;qBACc,MAAM,GAAG,OAAO;EAIjC,CAAC;AAiKH;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACjC,EAAE,CAAC,EAAE;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { appConfig } from '../../config/index.js';
|
|
5
5
|
import { isUndefinedOrNull } from '../../helper/index.js';
|
|
6
6
|
import { Cloudflare } from '../../config/cloudflare.js';
|
|
7
|
-
import { Env } from '../../config/env.js';
|
|
7
|
+
import { Env, getProcessLike } from '../../config/env.js';
|
|
8
8
|
import { Logger } from '../../config/logger.js';
|
|
9
9
|
import { createMockHttpObjects, ErrorResponse, HttpResponse } from '../RuntimeAdapter.js';
|
|
10
10
|
/**
|
|
@@ -19,7 +19,13 @@ export const CloudflareAdapter = Object.freeze({
|
|
|
19
19
|
create(config) {
|
|
20
20
|
const workersEnv = Cloudflare.getWorkersEnv();
|
|
21
21
|
if (workersEnv !== null) {
|
|
22
|
-
|
|
22
|
+
const processEnv = getProcessLike()?.env;
|
|
23
|
+
const resolveEnvSource = () => {
|
|
24
|
+
if (processEnv === undefined)
|
|
25
|
+
return workersEnv;
|
|
26
|
+
return { ...processEnv, ...workersEnv };
|
|
27
|
+
};
|
|
28
|
+
Env.setSource(resolveEnvSource);
|
|
23
29
|
}
|
|
24
30
|
const logger = config.logger ?? createDefaultLogger();
|
|
25
31
|
return {
|
package/src/start.js
CHANGED
|
@@ -112,10 +112,8 @@ export const bootStandaloneService = async (importMetaUrl, activeService) => {
|
|
|
112
112
|
export const start = async () => {
|
|
113
113
|
if (!isNodeRuntime())
|
|
114
114
|
return;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// In unit tests, importing bootstrap has heavy side effects (starts server + exits).
|
|
118
|
-
await import('./boot/bootstrap.js');
|
|
115
|
+
const projectBootstrapModule = (await import('./runtime/ProjectBootstrap.js'));
|
|
116
|
+
await projectBootstrapModule.loadProjectBootstrap();
|
|
119
117
|
};
|
|
120
118
|
/**
|
|
121
119
|
* Cloudflare Workers entry (module worker style).
|