@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.
Files changed (43) hide show
  1. package/package.json +1 -1
  2. package/src/boot/bootstrap.js +5 -3
  3. package/src/boot/registry/registerRoute.d.ts.map +1 -1
  4. package/src/boot/registry/registerRoute.js +88 -20
  5. package/src/cli/PromptHelper.d.ts.map +1 -1
  6. package/src/cli/PromptHelper.js +1 -0
  7. package/src/cli/commands/NewCommand.d.ts +1 -1
  8. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  9. package/src/cli/commands/NewCommand.js +4 -1
  10. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  11. package/src/cli/commands/StartCommand.js +84 -5
  12. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  13. package/src/cli/scaffolding/ProjectScaffolder.js +1 -0
  14. package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
  15. package/src/cli/scaffolding/ServiceScaffolder.js +6 -1
  16. package/src/config/env.d.ts.map +1 -1
  17. package/src/config/env.js +13 -0
  18. package/src/functions/cloudflare.d.ts.map +1 -1
  19. package/src/functions/cloudflare.js +21 -1
  20. package/src/index.js +3 -3
  21. package/src/microservices/ServiceManifest.d.ts +2 -0
  22. package/src/microservices/ServiceManifest.d.ts.map +1 -1
  23. package/src/microservices/ServiceManifest.js +10 -0
  24. package/src/orm/Database.d.ts.map +1 -1
  25. package/src/orm/Database.js +5 -2
  26. package/src/orm/DatabaseConnectionRegistry.d.ts +8 -0
  27. package/src/orm/DatabaseConnectionRegistry.d.ts.map +1 -0
  28. package/src/orm/DatabaseConnectionRegistry.js +13 -0
  29. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  30. package/src/orm/DatabaseRuntimeRegistration.js +4 -2
  31. package/src/runtime/ProjectBootstrap.d.ts +6 -0
  32. package/src/runtime/ProjectBootstrap.d.ts.map +1 -0
  33. package/src/runtime/ProjectBootstrap.js +43 -0
  34. package/src/runtime/ProjectRuntime.d.ts.map +1 -1
  35. package/src/runtime/ProjectRuntime.js +26 -13
  36. package/src/runtime/WorkerAdapterImports.d.ts.map +1 -1
  37. package/src/runtime/WorkerAdapterImports.js +17 -0
  38. package/src/runtime/WorkersModule.d.ts.map +1 -1
  39. package/src/runtime/WorkersModule.js +9 -4
  40. package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
  41. package/src/runtime/adapters/CloudflareAdapter.js +8 -2
  42. package/src/start.js +2 -4
  43. package/src/templates/project/basic/src/zintrust.plugins.wg.ts.tpl +5 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.4.13",
3
+ "version": "0.4.15",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -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
- const officialImports = await PluginAutoImports.tryImportRuntimeAutoImports('base');
203
- if (!officialImports.ok) {
204
- Logger.warn('Official plugin auto-imports failed:', ErrorFactory.createGeneralError('officialImports', officialImports.errorMessage));
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;AAW3D,eAAO,MAAM,kBAAkB,QAAO,OAKrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAMpF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAOrF,CAAC;AA4FF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,MAAM,EACxB,QAAQ,OAAO,KACd,OAAO,CAAC,IAAI,CAoBd,CAAC"}
1
+ {"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 registerManifestRoutes = async (router) => {
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.monolithEnabled === false || typeof entry.loadRoutes !== 'function') {
151
+ if (!shouldRegisterManifestEntry(entry, activeService))
73
152
  continue;
74
- }
75
- try {
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;IAuBlB;;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"}
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"}
@@ -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;AAYhF,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;AAwPhD,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;AA0RD;;;GAGG;AACH,eAAO,MAAM,UAAU;IACrB;;OAEG;cACO,WAAW;EAGrB,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;AAmvBvF,eAAO,MAAM,YAAY;cACb,YAAY;EAmCtB,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 { existsSync, mkdirSync, readFileSync, writeFileSync } from '../../node-singletons/fs.js';
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 SpawnUtil.spawnAndWait({
362
- command: 'wrangler',
363
- args: wranglerArgs,
364
- env: buildStartEnv(context.projectRoot),
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;AA4ID;;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
+ {"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"}
@@ -480,6 +480,7 @@ dist/
480
480
  .env
481
481
  .env.*
482
482
  .env.local
483
+ .dev*
483
484
  .DS_Store
484
485
  coverage/
485
486
  logs/
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ServiceScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD;;GAEG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuB7F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAGnF;AAED;;GAEG;AAEH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAiDhC;AAgcD,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC"}
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 = `src/services/${domain}/${options.name}/config`;
244
+ const configRoot = getServiceConfigRoot(domain, options.name);
240
245
  return `/**
241
246
  * ${options.name} Service - Entry Point
242
247
  * Port: ${options.port ?? 3001}
@@ -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;AAuBlF,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"}
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":";mBAmIuB,OAAO,QAAQ,OAAO,QAAQ,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;;AADhF,wBAmCE"}
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 = _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.13
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-23T14:57:40.299Z
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-23T14:57:40.266Z'; // Replaced during build
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';
@@ -4,6 +4,8 @@ export interface ServiceManifestEntry {
4
4
  domain: string;
5
5
  name: string;
6
6
  prefix?: string;
7
+ configRoot?: string;
8
+ loadEnv?: boolean;
7
9
  version?: string;
8
10
  description?: string;
9
11
  port?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceManifest.d.ts","sourceRoot":"","sources":["../../../src/microservices/ServiceManifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ServiceManifest.d.ts","sourceRoot":"","sources":["../../../src/microservices/ServiceManifest.ts"],"names":[],"mappings":"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"}
@@ -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;AAWxD,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,CAoBtF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAWnD"}
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"}
@@ -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
- if (config === undefined) {
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(config));
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;AA0DtB;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAYpF"}
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
- // Register instance by name; a later call without config may now resolve.
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,6 @@
1
+ export declare function loadProjectBootstrap(): Promise<void>;
2
+ declare const _default: Readonly<{
3
+ loadProjectBootstrap: typeof loadProjectBootstrap;
4
+ }>;
5
+ export default _default;
6
+ //# sourceMappingURL=ProjectBootstrap.d.ts.map
@@ -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;AA2ExC,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"}
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 tryImportWorkerRuntimeCandidate = async (moduleId) => {
55
+ const tryImportWorkerRuntimeLiteralCandidates = async () => {
53
56
  try {
54
- const runtimeModule = (await import(moduleId));
55
- return cacheProjectRuntime(runtimeModule);
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 !== undefined)
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 !== undefined)
113
+ if (hasLoadedServiceManifest(cached))
94
114
  return cached;
95
- const workerModuleIds = ['../' + 'zintrust.runtime.wg.js', '../' + 'zintrust.runtime.js'];
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":"AAeA,eAAO,MAAM,oBAAoB;;;EAG/B,CAAC"}
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;AA+TnE,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,aAAa,CAwB/D,CAAC;AA2CF,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,kBAAkB,CAiBzE,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 = import('@zintrust/workers');
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 ??= import('@zintrust/workers');
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 = import('@zintrust/queue-monitor');
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 ??= import('@zintrust/queue-monitor');
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;IAwD7C;;;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"}
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
- Env.setSource(() => workersEnv);
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
- // Compiled output places bootstrap at `dist/src/boot/bootstrap.js`.
116
- // This file compiles to `dist/src/start.js`, so relative import is stable.
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).
@@ -6,3 +6,8 @@
6
6
  */
7
7
 
8
8
  // Intentionally empty by default.
9
+
10
+ import { ProjectRuntime } from '@zintrust/core';
11
+ import serviceManifest from './bootstrap/service-manifest';
12
+
13
+ ProjectRuntime.set({ serviceManifest });