@zintrust/core 0.4.13 → 0.4.15
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 +88 -20
- package/src/cli/PromptHelper.d.ts.map +1 -1
- package/src/cli/PromptHelper.js +1 -0
- 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 +84 -5
- 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 +6 -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 +2 -0
- package/src/microservices/ServiceManifest.d.ts.map +1 -1
- package/src/microservices/ServiceManifest.js +10 -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 +26 -13
- 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 +9 -4
- 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/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;
|
|
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"}
|
|
@@ -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,28 +62,96 @@ const registerAppRoutes = async (resolvedBasePath, router) => {
|
|
|
63
62
|
mod.registerRoutes(router);
|
|
64
63
|
}
|
|
65
64
|
};
|
|
66
|
-
const
|
|
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
|
+
if (entry.loadEnv === false)
|
|
93
|
+
return;
|
|
94
|
+
const { EnvFileLoader } = await import('../../cli/utils/EnvFileLoader.js');
|
|
95
|
+
const projectRoot = getProjectRoot();
|
|
96
|
+
const envPath = resolveManifestServiceEnvDir(projectRoot, entry);
|
|
97
|
+
EnvFileLoader.ensureLoaded({
|
|
98
|
+
cwd: projectRoot,
|
|
99
|
+
includeCwd: true,
|
|
100
|
+
envPaths: [envPath],
|
|
101
|
+
});
|
|
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
|
+
}
|
|
67
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
|
+
};
|
|
132
|
+
const registerLoadedRoutes = (router, entry, registerRoutes, activeService) => {
|
|
133
|
+
const servicePrefix = resolveServicePrefix(entry);
|
|
134
|
+
if (activeService?.id === entry.id) {
|
|
135
|
+
registerRoutes(router);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
Router.group(router, servicePrefix, (scopedRouter) => {
|
|
139
|
+
registerRoutes(scopedRouter);
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
const registerManifestRoutes = async (router) => {
|
|
143
|
+
await loadRuntimeManifest();
|
|
68
144
|
const serviceManifest = ProjectRuntime.getServiceManifest();
|
|
69
145
|
if (serviceManifest.length === 0)
|
|
70
146
|
return;
|
|
147
|
+
const activeService = ProjectRuntime.getActiveService();
|
|
148
|
+
if (activeService !== undefined && isCloudflare)
|
|
149
|
+
return;
|
|
71
150
|
for (const entry of serviceManifest) {
|
|
72
|
-
if (entry
|
|
151
|
+
if (!shouldRegisterManifestEntry(entry, activeService))
|
|
73
152
|
continue;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// eslint-disable-next-line no-await-in-loop
|
|
77
|
-
const mod = await entry.loadRoutes();
|
|
78
|
-
const registerRoutes = isObject(mod) ? mod.registerRoutes : undefined;
|
|
79
|
-
if (typeof registerRoutes === 'function') {
|
|
80
|
-
Router.group(router, getServicePrefix(entry), (scopedRouter) => {
|
|
81
|
-
registerRoutes(scopedRouter);
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
Logger.warn(`Failed to register manifest routes for ${entry.id}`, error);
|
|
87
|
-
}
|
|
153
|
+
// eslint-disable-next-line no-await-in-loop
|
|
154
|
+
await registerManifestEntryRoutes(router, entry, activeService);
|
|
88
155
|
}
|
|
89
156
|
};
|
|
90
157
|
const registerFrameworkRoutes = async (resolvedBasePath, router) => {
|
|
@@ -104,14 +171,15 @@ const registerGlobalRoutes = (router) => {
|
|
|
104
171
|
};
|
|
105
172
|
export const registerMasterRoutes = async (resolvedBasePath, router) => {
|
|
106
173
|
try {
|
|
174
|
+
const activeService = ProjectRuntime.getActiveService();
|
|
107
175
|
if (isCloudflare) {
|
|
108
176
|
registerGlobalRoutes(router);
|
|
109
177
|
}
|
|
110
|
-
if (!isCloudflare) {
|
|
178
|
+
if (!isCloudflare && activeService === undefined) {
|
|
111
179
|
await registerAppRoutes(resolvedBasePath, router);
|
|
112
180
|
}
|
|
113
181
|
await registerManifestRoutes(router);
|
|
114
|
-
if (router.routes.length === 0) {
|
|
182
|
+
if (router.routes.length === 0 && activeService === undefined) {
|
|
115
183
|
await registerFrameworkRoutes(resolvedBasePath, router);
|
|
116
184
|
}
|
|
117
185
|
// Always register core framework routes (health, metrics, doc) after app routes
|
|
@@ -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,
|
|
@@ -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;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 && entry.loadEnv !== 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":"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;
|
|
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"}
|
|
@@ -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,7 +108,9 @@ 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}',
|
|
113
|
+
loadEnv: false,
|
|
111
114
|
port: ${options.port ?? 3001},
|
|
112
115
|
monolithEnabled: true,
|
|
113
116
|
loadRoutes: async () => ${routeImportExpression},
|
|
@@ -148,7 +151,9 @@ function updateServiceManifest(projectRoot, options) {
|
|
|
148
151
|
id: '${serviceId}',
|
|
149
152
|
domain: '${domain}',
|
|
150
153
|
name: '${options.name}',
|
|
154
|
+
configRoot: '${getServiceConfigRoot(domain, options.name)}',
|
|
151
155
|
prefix: '${serviceId}',
|
|
156
|
+
loadEnv: false,
|
|
152
157
|
port: ${options.port ?? 3001},
|
|
153
158
|
monolithEnabled: true,
|
|
154
159
|
loadRoutes: async () => ${routeImportExpression},
|
|
@@ -236,7 +241,7 @@ function generateServiceConfig(options) {
|
|
|
236
241
|
function generateServiceIndex(options) {
|
|
237
242
|
const domain = options.domain ?? 'default';
|
|
238
243
|
const serviceId = `${domain}/${options.name}`;
|
|
239
|
-
const configRoot =
|
|
244
|
+
const configRoot = getServiceConfigRoot(domain, options.name);
|
|
240
245
|
return `/**
|
|
241
246
|
* ${options.name} Service - Entry Point
|
|
242
247
|
* 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.15
|
|
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-24T09:07:10.631Z
|
|
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-24T09:07:10.598Z'; // 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":"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,OAAO,CAAC;IAClB,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,oBA2BhE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,aAAa,CAAC,oBAAoB,CAW3F,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,OAAO,OAAO,KAAG,oBAAoB,GAAG,SAarF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,OAAO,OAAO,KAAG,oBAa9D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,EACjB,aAAa,MAAM,EACnB,WAAW,aAAa,CAAC,MAAM,CAAC,KAC/B,OAGF,CAAC;;2BA9HmC,MAAM,QAAQ,MAAM,KAAG,MAAM;sCAElB,MAAM,QAAQ,MAAM,KAAG,MAAM;6BAgBtC;QACrC,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,KAAG,MAAM;kCAQkC,OAAO,KAAG,KAAK,IAAI,MAAM;iCAM1B;QACzC,EAAE,CAAC,EAAE,OAAO,CAAC;QACb,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,KAAG,MAAM;oCAOoC,OAAO,KAAG,KAAK,IAAI,oBAAoB;sCA6BrC,OAAO,KAAG,aAAa,CAAC,oBAAoB,CAAC;2CAaxC,OAAO,KAAG,oBAAoB,GAAG,SAAS;2CAe1C,OAAO,KAAG,oBAAoB;yCAgBtE,MAAM,eACJ,MAAM,aACR,aAAa,CAAC,MAAM,CAAC,KAC/B,OAAO;;AAKV,wBAWG"}
|
|
@@ -46,6 +46,14 @@ 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
|
+
}
|
|
53
|
+
const loadEnv = value['loadEnv'];
|
|
54
|
+
if (loadEnv !== undefined && typeof loadEnv !== 'boolean') {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
49
57
|
const loadRoutes = value['loadRoutes'];
|
|
50
58
|
if (loadRoutes !== undefined && !isFunction(loadRoutes)) {
|
|
51
59
|
return false;
|
|
@@ -59,6 +67,8 @@ export const normalizeServiceManifest = (value) => {
|
|
|
59
67
|
...entry,
|
|
60
68
|
id: toCanonicalServiceId(entry),
|
|
61
69
|
prefix: getServicePrefix(entry),
|
|
70
|
+
...(isNonEmptyString(entry.configRoot) ? { configRoot: entry.configRoot } : {}),
|
|
71
|
+
loadEnv: entry.loadEnv !== false,
|
|
62
72
|
monolithEnabled: entry.monolithEnabled !== false,
|
|
63
73
|
}));
|
|
64
74
|
};
|
|
@@ -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;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"}
|
|
@@ -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;
|
|
@@ -49,10 +52,27 @@ const tryImportNodeRuntimeCandidate = async (candidate) => {
|
|
|
49
52
|
return undefined;
|
|
50
53
|
}
|
|
51
54
|
};
|
|
52
|
-
const
|
|
55
|
+
const tryImportWorkerRuntimeLiteralCandidates = async () => {
|
|
53
56
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
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')));
|
|
56
76
|
}
|
|
57
77
|
catch {
|
|
58
78
|
return undefined;
|
|
@@ -76,7 +96,7 @@ export const ProjectRuntime = Object.freeze({
|
|
|
76
96
|
},
|
|
77
97
|
async tryLoadNodeRuntime() {
|
|
78
98
|
const cached = getCachedProjectRuntime();
|
|
79
|
-
if (cached
|
|
99
|
+
if (hasLoadedServiceManifest(cached))
|
|
80
100
|
return cached;
|
|
81
101
|
const projectRoot = getProjectRoot();
|
|
82
102
|
const candidates = getNodeRuntimeCandidates(projectRoot);
|
|
@@ -90,16 +110,9 @@ export const ProjectRuntime = Object.freeze({
|
|
|
90
110
|
},
|
|
91
111
|
async tryLoadWorkerRuntime() {
|
|
92
112
|
const cached = getCachedProjectRuntime();
|
|
93
|
-
if (cached
|
|
113
|
+
if (hasLoadedServiceManifest(cached))
|
|
94
114
|
return cached;
|
|
95
|
-
|
|
96
|
-
for (const moduleId of workerModuleIds) {
|
|
97
|
-
// eslint-disable-next-line no-await-in-loop
|
|
98
|
-
const loaded = await tryImportWorkerRuntimeCandidate(moduleId);
|
|
99
|
-
if (loaded !== undefined)
|
|
100
|
-
return loaded;
|
|
101
|
-
}
|
|
102
|
-
return undefined;
|
|
115
|
+
return tryImportWorkerRuntimeLiteralCandidates();
|
|
103
116
|
},
|
|
104
117
|
getServiceManifest() {
|
|
105
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;AAmUnE,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;
|
|
@@ -250,7 +253,7 @@ const handleImportFailure = async (error) => {
|
|
|
250
253
|
filesChanged,
|
|
251
254
|
replacements,
|
|
252
255
|
});
|
|
253
|
-
workersModulePromise =
|
|
256
|
+
workersModulePromise = importOptionalPackage('@zintrust/workers');
|
|
254
257
|
return workersModulePromise;
|
|
255
258
|
}
|
|
256
259
|
}
|
|
@@ -283,7 +286,7 @@ export const loadWorkersModule = async () => {
|
|
|
283
286
|
}
|
|
284
287
|
}
|
|
285
288
|
logWorkersResolverDiagnostics();
|
|
286
|
-
workersModulePromise ??=
|
|
289
|
+
workersModulePromise ??= importOptionalPackage('@zintrust/workers');
|
|
287
290
|
try {
|
|
288
291
|
return await workersModulePromise;
|
|
289
292
|
}
|
|
@@ -307,7 +310,8 @@ const handleQueueMonitorImportFailure = async (error) => {
|
|
|
307
310
|
filesChanged,
|
|
308
311
|
replacements,
|
|
309
312
|
});
|
|
310
|
-
queueMonitorModulePromise =
|
|
313
|
+
queueMonitorModulePromise =
|
|
314
|
+
importOptionalPackage('@zintrust/queue-monitor');
|
|
311
315
|
return queueMonitorModulePromise;
|
|
312
316
|
}
|
|
313
317
|
}
|
|
@@ -334,7 +338,8 @@ export const loadQueueMonitorModule = async () => {
|
|
|
334
338
|
return localFallback;
|
|
335
339
|
}
|
|
336
340
|
}
|
|
337
|
-
queueMonitorModulePromise ??=
|
|
341
|
+
queueMonitorModulePromise ??=
|
|
342
|
+
importOptionalPackage('@zintrust/queue-monitor');
|
|
338
343
|
try {
|
|
339
344
|
return await queueMonitorModulePromise;
|
|
340
345
|
}
|
|
@@ -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).
|