@zintrust/core 0.4.5 → 0.4.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"zintrust-main.d.ts","sourceRoot":"","sources":["../../bin/zintrust-main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuGH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAsEzC;AAED,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"zintrust-main.d.ts","sourceRoot":"","sources":["../../bin/zintrust-main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuGH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAgFzC;AAED,OAAO,EAAE,CAAC"}
@@ -4,6 +4,7 @@
4
4
  * This module contains the CLI implementation without a hashbang so that it can
5
5
  * be imported by other bin shortcuts (zin/z/zt) without parse errors.
6
6
  */
7
+ import { Logger } from '../src/config/logger.js';
7
8
  import fs from 'node:fs';
8
9
  import path from 'node:path';
9
10
  import { fileURLToPath } from 'node:url';
@@ -73,7 +74,6 @@ const normalizeProxyTargetArgs = (args) => {
73
74
  };
74
75
  const handleCliFatal = async (error, context) => {
75
76
  try {
76
- const { Logger } = await import('../src/config/logger.js');
77
77
  Logger.error(context, error);
78
78
  }
79
79
  catch {
@@ -120,7 +120,15 @@ export async function run() {
120
120
  // (This is driven by src/zintrust.plugins.ts generated by `zin plugin install`.)
121
121
  try {
122
122
  const { PluginAutoImports } = await import('../src/runtime/PluginAutoImports.js');
123
- await PluginAutoImports.tryImportProjectAutoImports();
123
+ const runtimeImportMode = process.env['DOCKER_WORKER'] === 'true' ? 'worker' : 'base';
124
+ const officialImports = await PluginAutoImports.tryImportRuntimeAutoImports(runtimeImportMode);
125
+ if (!officialImports.ok) {
126
+ Logger.warn('Official plugin auto-imports failed:', officialImports.errorMessage);
127
+ }
128
+ const projectImports = await PluginAutoImports.tryImportProjectAutoImports();
129
+ if (!projectImports.ok && projectImports.reason !== 'not-found') {
130
+ Logger.warn('Project plugin auto-imports failed:', projectImports.errorMessage);
131
+ }
124
132
  }
125
133
  catch {
126
134
  // best-effort; CLI should still run even if plugins file is missing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -26,6 +26,10 @@
26
26
  "types": "./src/cli.d.ts",
27
27
  "import": "./src/cli.js"
28
28
  },
29
+ "./worker-commands": {
30
+ "types": "./src/worker-commands.d.ts",
31
+ "import": "./src/worker-commands.js"
32
+ },
29
33
  "./proxy": {
30
34
  "types": "./src/proxy.d.ts",
31
35
  "import": "./src/proxy.js"
@@ -198,7 +198,14 @@ const BootstrapFunctions = Object.freeze({
198
198
  // (This is driven by src/zintrust.plugins.ts generated by `zin plugin install`.)
199
199
  try {
200
200
  const { PluginAutoImports } = await import('../runtime/PluginAutoImports.js');
201
- await PluginAutoImports.tryImportProjectAutoImports();
201
+ const officialImports = await PluginAutoImports.tryImportRuntimeAutoImports('base');
202
+ if (!officialImports.ok) {
203
+ Logger.warn('Official plugin auto-imports failed:', ErrorFactory.createGeneralError('officialImports', officialImports.errorMessage));
204
+ }
205
+ const projectImports = await PluginAutoImports.tryImportProjectAutoImports();
206
+ if (!projectImports.ok && projectImports.reason !== 'not-found') {
207
+ Logger.warn('Project plugin auto-imports failed:', ErrorFactory.createGeneralError('projectImports', projectImports.errorMessage));
208
+ }
202
209
  }
203
210
  catch (error) {
204
211
  // best-effort; run without plugins if loader fails (e.g. non-Node runtime)
@@ -1 +1 @@
1
- {"version":3,"file":"D1MigrateCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/D1MigrateCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA+GrE;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;cACO,YAAY;EAyBtB,CAAC"}
1
+ {"version":3,"file":"D1MigrateCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/D1MigrateCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA2HrE;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;cACO,YAAY;EAyBtB,CAAC"}
@@ -21,7 +21,14 @@ const getDbName = (projectRoot, options) => {
21
21
  const value = options['database'];
22
22
  if (typeof value === 'string' && value.trim() !== '')
23
23
  return value.trim();
24
- return WranglerConfig.getDefaultD1DatabaseName(projectRoot) ?? 'zintrust_db';
24
+ const resolution = WranglerConfig.resolveD1Database(projectRoot);
25
+ if (resolution.status === 'resolved') {
26
+ return WranglerConfig.getDefaultD1DatabaseName(projectRoot) ?? 'zintrust_db';
27
+ }
28
+ if (resolution.status === 'ambiguous') {
29
+ throw ErrorFactory.createCliError('Multiple D1 targets are configured. Re-run with --database <database_name|binding> to choose the intended Wrangler D1 target.');
30
+ }
31
+ return 'zintrust_db';
25
32
  };
26
33
  const buildExecutionContext = (options) => {
27
34
  const isWorkerCommand = process.argv.includes('d1:migrate:worker');
@@ -1 +1 @@
1
- {"version":3,"file":"DockerPushCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DockerPushCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA6FrE,eAAO,MAAM,iBAAiB;cAClB,YAAY;EA0BtB,CAAC"}
1
+ {"version":3,"file":"DockerPushCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DockerPushCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA+GrE,eAAO,MAAM,iBAAiB;cAClB,YAAY;EA8BtB,CAAC"}
@@ -26,7 +26,7 @@ const resolvePublishTags = (tag, alsoLatest) => {
26
26
  };
27
27
  const parseOnly = (value) => {
28
28
  const raw = (value ?? '').trim().toLowerCase();
29
- if (raw === 'runtime' || raw === 'gateway')
29
+ if (raw === 'runtime' || raw === 'worker' || raw === 'gateway')
30
30
  return raw;
31
31
  return 'both';
32
32
  };
@@ -36,16 +36,21 @@ const runPublishImages = async (options) => {
36
36
  const tags = resolvePublishTags(tag, options.alsoLatest);
37
37
  const only = parseOnly(options.only);
38
38
  const runtimeRepo = 'zintrust/zintrust';
39
+ const workerRepo = 'zintrust/zintrust-worker';
39
40
  const gatewayRepo = 'zintrust/zintrust-proxy-gateway';
40
- const buildArgsFor = (repo, context) => {
41
+ const buildArgsFor = (repo, context, target) => {
41
42
  const args = ['buildx', 'build', '--platform', platforms];
42
43
  for (const t of tags)
43
44
  args.push('-t', `${repo}:${t}`);
45
+ if (typeof target === 'string' && target.trim() !== '') {
46
+ args.push('--target', target);
47
+ }
44
48
  args.push('--push', context);
45
49
  return args;
46
50
  };
47
51
  Logger.info('Publishing images to Docker Hub via buildx...', {
48
52
  runtime: runtimeRepo,
53
+ worker: workerRepo,
49
54
  gateway: gatewayRepo,
50
55
  platforms,
51
56
  tags,
@@ -54,13 +59,23 @@ const runPublishImages = async (options) => {
54
59
  if (only === 'runtime' || only === 'both') {
55
60
  const runtimeExit = await SpawnUtil.spawnAndWait({
56
61
  command: 'docker',
57
- args: buildArgsFor(runtimeRepo, '.'),
62
+ args: buildArgsFor(runtimeRepo, '.', 'runtime'),
58
63
  env: process.env,
59
64
  });
60
65
  if (runtimeExit !== 0) {
61
66
  throw ErrorFactory.createCliError(`Failed to publish ${runtimeRepo} (exit code ${runtimeExit})`);
62
67
  }
63
68
  }
69
+ if (only === 'worker' || only === 'both') {
70
+ const workerExit = await SpawnUtil.spawnAndWait({
71
+ command: 'docker',
72
+ args: buildArgsFor(workerRepo, '.', 'worker'),
73
+ env: process.env,
74
+ });
75
+ if (workerExit !== 0) {
76
+ throw ErrorFactory.createCliError(`Failed to publish ${workerRepo} (exit code ${workerExit})`);
77
+ }
78
+ }
64
79
  if (only === 'gateway' || only === 'both') {
65
80
  const gatewayExit = await SpawnUtil.spawnAndWait({
66
81
  command: 'docker',
@@ -82,7 +97,7 @@ export const DockerPushCommand = Object.freeze({
82
97
  command.option('--tag <tag>', 'Docker image tag to publish. Defaults to current version and also tags :latest');
83
98
  command.option('--platforms <list>', 'Comma-separated platforms for buildx', 'linux/amd64,linux/arm64');
84
99
  command.option('--no-also-latest', 'When publishing a non-latest --tag, do not also push :latest');
85
- command.option('--only <target>', 'Publish only one image: runtime|gateway|both', 'both');
100
+ command.option('--only <target>', 'Publish only one image: runtime|worker|gateway|both', 'both');
86
101
  },
87
102
  execute: async (options) => {
88
103
  await runPublishImages(options);
@@ -1 +1 @@
1
- {"version":3,"file":"MigrateCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/MigrateCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA0erE;;GAEG;AACH,eAAO,MAAM,cAAc;IACzB;;OAEG;cACO,YAAY;EAUtB,CAAC"}
1
+ {"version":3,"file":"MigrateCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/MigrateCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAmfrE;;GAEG;AACH,eAAO,MAAM,cAAc;IACzB;;OAEG;cACO,YAAY;EAUtB,CAAC"}
@@ -169,9 +169,19 @@ const runD1Actions = async (params) => {
169
169
  cmd.warn('Note: MIGRATIONS_SEPARATE_TRACKING is ignored for D1 (Wrangler owns tracking).');
170
170
  }
171
171
  const isLocal = options['local'] === true || options['remote'] !== true;
172
- const dbName = typeof options['database'] === 'string' && options['database'].trim() !== ''
173
- ? options['database'].trim()
174
- : (WranglerConfig.getDefaultD1DatabaseName(projectRoot) ?? 'zintrust_db');
172
+ let dbName = 'zintrust_db';
173
+ if (typeof options['database'] === 'string' && options['database'].trim() !== '') {
174
+ dbName = options['database'].trim();
175
+ }
176
+ else {
177
+ const resolution = WranglerConfig.resolveD1Database(projectRoot);
178
+ if (resolution.status === 'resolved') {
179
+ dbName = WranglerConfig.getDefaultD1DatabaseName(projectRoot) ?? 'zintrust_db';
180
+ }
181
+ else if (resolution.status === 'ambiguous') {
182
+ throw ErrorFactory.createCliError('Multiple D1 targets are configured. Re-run with --database <database_name|binding> to choose the intended Wrangler D1 target.');
183
+ }
184
+ }
175
185
  const migrationsRelDir = WranglerConfig.getD1MigrationsDir(projectRoot, dbName);
176
186
  const outputDir = path.join(projectRoot, migrationsRelDir);
177
187
  cmd.info(`Generating D1 SQL migrations into ${migrationsRelDir}...`);
@@ -1,7 +1,8 @@
1
- import { type WranglerD1DatabaseConfig } from '../d1/WranglerConfig';
1
+ import { type WranglerD1DatabaseConfig, type WranglerD1ResolutionMatch } from '../d1/WranglerConfig';
2
2
  type ResolvedD1Target = {
3
3
  config: WranglerD1DatabaseConfig;
4
4
  databaseName: string;
5
+ matchedBy: WranglerD1ResolutionMatch;
5
6
  };
6
7
  export declare const LocalD1Resolver: Readonly<{
7
8
  resolveD1Binding(projectRoot: string, target?: string): ResolvedD1Target;
@@ -1 +1 @@
1
- {"version":3,"file":"LocalD1Resolver.d.ts","sourceRoot":"","sources":["../../../../src/cli/d1/LocalD1Resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAUvF,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,wBAAwB,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AA+EF,eAAO,MAAM,eAAe;kCACI,MAAM,WAAW,MAAM,GAAG,gBAAgB;oCAIxC,MAAM,WAAW,MAAM,GAAG,gBAAgB;0CAU9B,MAAM,WAAW,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;EAoCrF,CAAC"}
1
+ {"version":3,"file":"LocalD1Resolver.d.ts","sourceRoot":"","sources":["../../../../src/cli/d1/LocalD1Resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAE7B,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAYhC,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,wBAAwB,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,yBAAyB,CAAC;CACtC,CAAC;AAyHF,eAAO,MAAM,eAAe;kCACI,MAAM,WAAW,MAAM,GAAG,gBAAgB;oCAIxC,MAAM,WAAW,MAAM,GAAG,gBAAgB;0CAoB9B,MAAM,WAAW,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;EAoCrF,CAAC"}
@@ -1,41 +1,70 @@
1
+ import { WranglerConfig, } from '../d1/WranglerConfig.js';
2
+ import { WranglerD1 } from '../d1/WranglerD1.js';
1
3
  import { Logger } from '../../config/logger.js';
2
4
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
3
- import { WranglerConfig } from '../d1/WranglerConfig.js';
4
- import { WranglerD1 } from '../d1/WranglerD1.js';
5
5
  import { isNonEmptyString } from '../../helper/index.js';
6
6
  import { randomUUID } from '../../node-singletons/crypto.js';
7
7
  import fs from '../../node-singletons/fs.js';
8
8
  import * as path from '../../node-singletons/path.js';
9
9
  import { SQLiteAdapter } from '../../orm/adapters/SQLiteAdapter.js';
10
10
  const PROBE_TABLE = '__zintrust_d1_probe';
11
- const describeConfiguredTargets = (projectRoot) => {
12
- const configured = WranglerConfig.getD1Databases(projectRoot)
11
+ const describeTarget = (database) => {
12
+ const parts = [];
13
+ if (isNonEmptyString(database.database_name)) {
14
+ parts.push(`database_name=${database.database_name.trim()}`);
15
+ }
16
+ if (isNonEmptyString(database.binding)) {
17
+ parts.push(`binding=${database.binding.trim()}`);
18
+ }
19
+ return parts.length > 0 ? parts.join(', ') : 'unnamed-d1-entry';
20
+ };
21
+ const describeTargets = (configured) => {
22
+ const rendered = configured
13
23
  .map((database) => {
14
- const parts = [];
15
- if (isNonEmptyString(database.database_name)) {
16
- parts.push(`database_name=${database.database_name.trim()}`);
17
- }
18
- if (isNonEmptyString(database.binding)) {
19
- parts.push(`binding=${database.binding.trim()}`);
20
- }
21
- return parts.length > 0 ? parts.join(', ') : 'unnamed-d1-entry';
24
+ return describeTarget(database);
22
25
  })
23
26
  .filter((entry) => entry.length > 0);
24
- return configured.length > 0 ? configured.join(' | ') : 'none';
27
+ return rendered.length > 0 ? rendered.join(' | ') : 'none';
28
+ };
29
+ const getSelectionHint = (matchedBy) => {
30
+ if (matchedBy === 'database_name')
31
+ return 'database_name';
32
+ if (matchedBy === 'binding')
33
+ return 'binding';
34
+ return 'configured D1 entry';
35
+ };
36
+ const createResolutionError = (resolution) => {
37
+ const configuredTargets = describeTargets(resolution.configured);
38
+ const targetLabel = resolution.target ?? '';
39
+ if (resolution.status === 'ambiguous') {
40
+ if (resolution.matchedBy === 'multiple-configured') {
41
+ return ErrorFactory.createConfigError(`Multiple D1 targets are configured in wrangler.jsonc. Specify a target by database_name or binding. Configured D1 targets: ${configuredTargets}`);
42
+ }
43
+ return ErrorFactory.createConfigError(`D1 target "${targetLabel}" is ambiguous by ${getSelectionHint(resolution.matchedBy)}. Matching entries: ${describeTargets(resolution.matches)}. Configured D1 targets: ${configuredTargets}`);
44
+ }
45
+ if (resolution.target === undefined) {
46
+ return ErrorFactory.createConfigError(`Unable to resolve a default D1 target from wrangler.jsonc. Configured D1 targets: ${configuredTargets}`);
47
+ }
48
+ return ErrorFactory.createConfigError(`Unable to resolve D1 target "${targetLabel}" from wrangler.jsonc. Tried database_name first, then binding. Configured D1 targets: ${configuredTargets}`);
25
49
  };
26
50
  const resolveTarget = (projectRoot, target) => {
27
- const config = WranglerConfig.getD1Database(projectRoot, target);
51
+ const resolution = WranglerConfig.resolveD1Database(projectRoot, target);
52
+ if (resolution.status !== 'resolved') {
53
+ throw createResolutionError(resolution);
54
+ }
55
+ const config = resolution.config;
28
56
  const configuredDatabaseName = config?.database_name?.trim();
29
57
  const configuredBindingName = config?.binding?.trim();
30
58
  const databaseName = configuredDatabaseName ??
31
59
  (isNonEmptyString(configuredBindingName) ? configuredBindingName : undefined);
32
- if (config === undefined || !isNonEmptyString(databaseName)) {
33
- throw ErrorFactory.createConfigError(`Unable to resolve D1 target "${target ?? ''}" from wrangler.jsonc. Configured D1 targets: ${describeConfiguredTargets(projectRoot)}`);
60
+ if (!isNonEmptyString(databaseName)) {
61
+ throw ErrorFactory.createConfigError(`Resolved D1 target is missing both database_name and binding. Configured D1 targets: ${describeTargets(WranglerConfig.getD1Databases(projectRoot))}`);
34
62
  }
35
- return { config, databaseName };
63
+ return { config, databaseName, matchedBy: resolution.matchedBy };
36
64
  };
65
+ const getLocalStateDir = (projectRoot) => path.join(projectRoot, '.wrangler', 'state', 'v3', 'd1', 'miniflare-D1DatabaseObject');
37
66
  const listCandidateSqliteFiles = (projectRoot) => {
38
- const candidateDir = path.join(projectRoot, '.wrangler', 'state', 'v3', 'd1', 'miniflare-D1DatabaseObject');
67
+ const candidateDir = getLocalStateDir(projectRoot);
39
68
  if (!fs.existsSync(candidateDir))
40
69
  return [];
41
70
  return fs
@@ -66,6 +95,10 @@ export const LocalD1Resolver = Object.freeze({
66
95
  },
67
96
  ensureLocalD1Ready(projectRoot, target) {
68
97
  const resolved = resolveTarget(projectRoot, target);
98
+ Logger.info(`[LocalD1Resolver] Resolved D1 target (${resolved.matchedBy}): ${describeTarget(resolved.config)}`);
99
+ if (listCandidateSqliteFiles(projectRoot).length === 0) {
100
+ Logger.info(`[LocalD1Resolver] Local D1 state missing, bootstrapping with Wrangler for ${resolved.databaseName}`);
101
+ }
69
102
  WranglerD1.executeSql({
70
103
  dbName: resolved.databaseName,
71
104
  isLocal: true,
@@ -103,6 +136,6 @@ export const LocalD1Resolver = Object.freeze({
103
136
  Logger.warn(`[LocalD1Resolver] Failed to remove D1 probe token: ${String(error)}`);
104
137
  }
105
138
  }
106
- throw ErrorFactory.createConfigError(`Unable to resolve actual local D1 SQLite file for target "${resolved.databaseName}" under .wrangler/state/v3/d1/miniflare-D1DatabaseObject`);
139
+ throw ErrorFactory.createConfigError(`Unable to resolve actual local D1 SQLite file for target "${resolved.databaseName}" under ${getLocalStateDir(projectRoot)}. Resolved D1 target: ${describeTarget(resolved.config)}`);
107
140
  },
108
141
  });
@@ -4,9 +4,30 @@ export type WranglerD1DatabaseConfig = {
4
4
  database_id?: string;
5
5
  migrations_dir?: string;
6
6
  };
7
+ export type WranglerD1ResolutionMatch = 'database_name' | 'binding' | 'single-configured';
8
+ export type WranglerD1DatabaseResolution = {
9
+ status: 'resolved';
10
+ target?: string;
11
+ config: WranglerD1DatabaseConfig;
12
+ matchedBy: WranglerD1ResolutionMatch;
13
+ configured: WranglerD1DatabaseConfig[];
14
+ matches: WranglerD1DatabaseConfig[];
15
+ } | {
16
+ status: 'ambiguous';
17
+ target?: string;
18
+ matchedBy: 'database_name' | 'binding' | 'multiple-configured';
19
+ configured: WranglerD1DatabaseConfig[];
20
+ matches: WranglerD1DatabaseConfig[];
21
+ } | {
22
+ status: 'missing';
23
+ target?: string;
24
+ configured: WranglerD1DatabaseConfig[];
25
+ matches: WranglerD1DatabaseConfig[];
26
+ };
7
27
  export declare const WranglerConfig: Readonly<{
8
28
  getD1Databases(projectRoot: string): WranglerD1DatabaseConfig[];
9
29
  getD1Database(projectRoot: string, target?: string): WranglerD1DatabaseConfig | undefined;
30
+ resolveD1Database(projectRoot: string, target?: string): WranglerD1DatabaseResolution;
10
31
  getDefaultD1Database(projectRoot: string): WranglerD1DatabaseConfig | undefined;
11
32
  getDefaultD1DatabaseName(projectRoot: string): string | undefined;
12
33
  getD1MigrationsDir(projectRoot: string, dbName?: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"WranglerConfig.d.ts","sourceRoot":"","sources":["../../../../src/cli/d1/WranglerConfig.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAuNF,eAAO,MAAM,cAAc;gCACG,MAAM,GAAG,wBAAwB,EAAE;+BAIpC,MAAM,WAAW,MAAM,GAAG,wBAAwB,GAAG,SAAS;sCAIvD,MAAM,GAAG,wBAAwB,GAAG,SAAS;0CAIzC,MAAM,GAAG,MAAM,GAAG,SAAS;oCAIjC,MAAM,WAAW,MAAM,GAAG,MAAM;EAIhE,CAAC"}
1
+ {"version":3,"file":"WranglerConfig.d.ts","sourceRoot":"","sources":["../../../../src/cli/d1/WranglerConfig.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,eAAe,GAAG,SAAS,GAAG,mBAAmB,CAAC;AAE1F,MAAM,MAAM,4BAA4B,GACpC;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,yBAAyB,CAAC;IACrC,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACrC,GACD;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,eAAe,GAAG,SAAS,GAAG,qBAAqB,CAAC;IAC/D,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACrC,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACrC,CAAC;AA8TN,eAAO,MAAM,cAAc;gCACG,MAAM,GAAG,wBAAwB,EAAE;+BAIpC,MAAM,WAAW,MAAM,GAAG,wBAAwB,GAAG,SAAS;mCAI1D,MAAM,WAAW,MAAM,GAAG,4BAA4B;sCAInD,MAAM,GAAG,wBAAwB,GAAG,SAAS;0CAIzC,MAAM,GAAG,MAAM,GAAG,SAAS;oCAIjC,MAAM,WAAW,MAAM,GAAG,MAAM;EAIhE,CAAC"}
@@ -158,19 +158,106 @@ const getResolvedD1Name = (config) => {
158
158
  return config.binding.trim();
159
159
  return undefined;
160
160
  };
161
+ const getBindingName = (config) => {
162
+ if (config === undefined || !isNonEmptyString(config.binding))
163
+ return undefined;
164
+ return config.binding.trim();
165
+ };
166
+ const getDatabaseName = (config) => {
167
+ if (config === undefined || !isNonEmptyString(config.database_name))
168
+ return undefined;
169
+ return config.database_name.trim();
170
+ };
161
171
  const getD1Databases = (projectRoot) => {
162
172
  const parsed = readWranglerConfig(projectRoot);
163
173
  return Array.isArray(parsed?.d1_databases) ? parsed.d1_databases : [];
164
174
  };
165
- const getD1Database = (projectRoot, target) => {
166
- const list = getD1Databases(projectRoot);
167
- if (list.length === 0)
168
- return undefined;
175
+ const resolveImplicitD1Database = (configured, target) => {
176
+ if (configured.length === 1 && configured[0] !== undefined) {
177
+ return {
178
+ status: 'resolved',
179
+ target,
180
+ config: configured[0],
181
+ matchedBy: 'single-configured',
182
+ configured,
183
+ matches: [configured[0]],
184
+ };
185
+ }
186
+ return {
187
+ status: 'ambiguous',
188
+ target,
189
+ matchedBy: 'multiple-configured',
190
+ configured,
191
+ matches: configured,
192
+ };
193
+ };
194
+ const resolveTargetedD1Database = (configured, target) => {
195
+ const databaseNameMatches = configured.filter((database) => getDatabaseName(database) === target);
196
+ if (databaseNameMatches.length === 1 && databaseNameMatches[0] !== undefined) {
197
+ return {
198
+ status: 'resolved',
199
+ target,
200
+ config: databaseNameMatches[0],
201
+ matchedBy: 'database_name',
202
+ configured,
203
+ matches: databaseNameMatches,
204
+ };
205
+ }
206
+ if (databaseNameMatches.length > 1) {
207
+ return {
208
+ status: 'ambiguous',
209
+ target,
210
+ matchedBy: 'database_name',
211
+ configured,
212
+ matches: databaseNameMatches,
213
+ };
214
+ }
215
+ const bindingMatches = configured.filter((database) => getBindingName(database) === target);
216
+ if (bindingMatches.length === 1 && bindingMatches[0] !== undefined) {
217
+ return {
218
+ status: 'resolved',
219
+ target,
220
+ config: bindingMatches[0],
221
+ matchedBy: 'binding',
222
+ configured,
223
+ matches: bindingMatches,
224
+ };
225
+ }
226
+ if (bindingMatches.length > 1) {
227
+ return {
228
+ status: 'ambiguous',
229
+ target,
230
+ matchedBy: 'binding',
231
+ configured,
232
+ matches: bindingMatches,
233
+ };
234
+ }
235
+ return {
236
+ status: 'missing',
237
+ target,
238
+ configured,
239
+ matches: [],
240
+ };
241
+ };
242
+ const resolveD1Database = (projectRoot, target) => {
243
+ const configured = getD1Databases(projectRoot);
169
244
  const normalizedTarget = normalizeTarget(target);
170
- if (normalizedTarget === undefined)
171
- return list[0] ?? undefined;
172
- return list.find((database) => database.binding?.trim() === normalizedTarget ||
173
- database.database_name?.trim() === normalizedTarget);
245
+ if (configured.length === 0) {
246
+ return {
247
+ status: 'missing',
248
+ target: normalizedTarget,
249
+ configured,
250
+ matches: [],
251
+ };
252
+ }
253
+ if (normalizedTarget === undefined) {
254
+ return resolveImplicitD1Database(configured, normalizedTarget);
255
+ }
256
+ return resolveTargetedD1Database(configured, normalizedTarget);
257
+ };
258
+ const getD1Database = (projectRoot, target) => {
259
+ const resolution = resolveD1Database(projectRoot, target);
260
+ return resolution.status === 'resolved' ? resolution.config : undefined;
174
261
  };
175
262
  export const WranglerConfig = Object.freeze({
176
263
  getD1Databases(projectRoot) {
@@ -179,6 +266,9 @@ export const WranglerConfig = Object.freeze({
179
266
  getD1Database(projectRoot, target) {
180
267
  return getD1Database(projectRoot, target);
181
268
  },
269
+ resolveD1Database(projectRoot, target) {
270
+ return resolveD1Database(projectRoot, target);
271
+ },
182
272
  getDefaultD1Database(projectRoot) {
183
273
  return getD1Database(projectRoot);
184
274
  },
package/src/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @zintrust/core v0.4.5
2
+ * @zintrust/core v0.4.7
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-21T11:25:25.434Z
8
+ * Built: 2026-03-21T18:54:39.641Z
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-21T11:25:25.402Z'; // Replaced during build
24
+ export const ZINTRUST_BUILD_DATE = '2026-03-21T18:54:39.609Z'; // 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';
@@ -0,0 +1,10 @@
1
+ export type OfficialPluginImageMode = 'base' | 'worker';
2
+ export declare const OfficialPlugins: Readonly<{
3
+ basePackages: readonly string[];
4
+ workerPackages: readonly string[];
5
+ baseAutoImports: readonly string[];
6
+ workerAutoImports: readonly string[];
7
+ getPackages(mode?: OfficialPluginImageMode): ReadonlyArray<string>;
8
+ getAutoImports(mode?: OfficialPluginImageMode): ReadonlyArray<string>;
9
+ }>;
10
+ //# sourceMappingURL=OfficialPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OfficialPlugins.d.ts","sourceRoot":"","sources":["../../../src/runtime/OfficialPlugins.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,QAAQ,CAAC;AA+CxD,eAAO,MAAM,eAAe;;;;;uBAKR,uBAAuB,GAAY,aAAa,CAAC,MAAM,CAAC;0BAGrD,uBAAuB,GAAY,aAAa,CAAC,MAAM,CAAC;EAG7E,CAAC"}
@@ -0,0 +1,51 @@
1
+ const basePackages = Object.freeze([
2
+ '@zintrust/db-postgres',
3
+ '@zintrust/db-mysql',
4
+ '@zintrust/db-sqlserver',
5
+ '@zintrust/db-sqlite',
6
+ '@zintrust/queue-redis',
7
+ '@zintrust/queue-rabbitmq',
8
+ '@zintrust/queue-sqs',
9
+ '@zintrust/cache-redis',
10
+ '@zintrust/cache-mongodb',
11
+ '@zintrust/mail-nodemailer',
12
+ '@zintrust/mail-smtp',
13
+ '@zintrust/mail-sendgrid',
14
+ '@zintrust/mail-mailgun',
15
+ '@zintrust/storage-s3',
16
+ '@zintrust/storage-r2',
17
+ '@zintrust/storage-gcs',
18
+ ]);
19
+ const workerPackages = Object.freeze(['@zintrust/workers', '@zintrust/queue-monitor']);
20
+ const baseAutoImports = Object.freeze([
21
+ '@zintrust/db-postgres/register',
22
+ '@zintrust/db-mysql/register',
23
+ '@zintrust/db-sqlserver/register',
24
+ '@zintrust/db-sqlite/register',
25
+ '@zintrust/queue-redis/register',
26
+ '@zintrust/queue-rabbitmq/register',
27
+ '@zintrust/queue-sqs/register',
28
+ '@zintrust/cache-redis/register',
29
+ '@zintrust/cache-mongodb/register',
30
+ '@zintrust/mail-nodemailer/register',
31
+ '@zintrust/mail-smtp/register',
32
+ '@zintrust/mail-sendgrid/register',
33
+ '@zintrust/mail-mailgun/register',
34
+ '@zintrust/storage-s3/register',
35
+ '@zintrust/storage-r2/register',
36
+ '@zintrust/storage-gcs/register',
37
+ ]);
38
+ const workerAutoImports = Object.freeze(['@zintrust/workers/register']);
39
+ const unique = (values) => Object.freeze([...new Set(values)]);
40
+ export const OfficialPlugins = Object.freeze({
41
+ basePackages,
42
+ workerPackages,
43
+ baseAutoImports,
44
+ workerAutoImports,
45
+ getPackages(mode = 'base') {
46
+ return mode === 'worker' ? unique([...basePackages, ...workerPackages]) : basePackages;
47
+ },
48
+ getAutoImports(mode = 'base') {
49
+ return mode === 'worker' ? unique([...baseAutoImports, ...workerAutoImports]) : baseAutoImports;
50
+ },
51
+ });
@@ -1,3 +1,4 @@
1
+ import { type OfficialPluginImageMode } from './OfficialPlugins';
1
2
  type ImportResult = {
2
3
  ok: true;
3
4
  loadedPath: string;
@@ -8,6 +9,7 @@ type ImportResult = {
8
9
  errorMessage?: string;
9
10
  };
10
11
  export declare const PluginAutoImports: Readonly<{
12
+ tryImportRuntimeAutoImports(mode?: OfficialPluginImageMode): Promise<ImportResult>;
11
13
  /**
12
14
  * Best-effort import of a project's `src/zintrust.plugins.ts` file.
13
15
  *
@@ -1 +1 @@
1
- {"version":3,"file":"PluginAutoImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginAutoImports.ts"],"names":[],"mappings":"AAMA,KAAK,YAAY,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,eAAe,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA0GN,eAAO,MAAM,iBAAiB;IAC5B;;;;;;OAMG;mCACkC,OAAO,CAAC,YAAY,CAAC;qCAkEnB,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;EAavE,CAAC"}
1
+ {"version":3,"file":"PluginAutoImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginAutoImports.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,KAAK,YAAY,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,eAAe,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA0JN,eAAO,MAAM,iBAAiB;uCACY,uBAAuB,GAAY,OAAO,CAAC,YAAY,CAAC;IAkBhG;;;;;;OAMG;mCACkC,OAAO,CAAC,YAAY,CAAC;qCAkEnB,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;EAavE,CAAC"}
@@ -3,6 +3,7 @@ import { Logger } from '../config/logger.js';
3
3
  import { existsSync, readFile } from '../node-singletons/fs.js';
4
4
  import * as path from '../node-singletons/path.js';
5
5
  import { pathToFileURL } from '../node-singletons/url.js';
6
+ import { OfficialPlugins } from './OfficialPlugins.js';
6
7
  const getProjectCwd = () => process.cwd();
7
8
  const getProjectRootEnv = () => readEnvString('ZINTRUST_PROJECT_ROOT');
8
9
  const resolveProjectRoot = () => {
@@ -70,30 +71,86 @@ const resolveRelativeSpecifier = (entry) => {
70
71
  const resolved = candidates.find((candidate) => existsSync(candidate)) ?? basePath;
71
72
  return pathToFileURL(resolved).href;
72
73
  };
74
+ const resolveLocalPackageSpecifier = (specifier) => {
75
+ if (!specifier.startsWith('@zintrust/'))
76
+ return null;
77
+ const projectRoot = resolveProjectRoot();
78
+ const withoutScope = specifier.slice('@zintrust/'.length);
79
+ const segments = withoutScope.split('/');
80
+ const packageName = segments[0];
81
+ const subpath = segments.slice(1).join('/');
82
+ const basename = subpath === '' ? 'index.js' : `${subpath}.js`;
83
+ const sourceBasename = subpath === '' ? 'index.ts' : `${subpath}.ts`;
84
+ const candidates = [
85
+ path.join(projectRoot, 'dist', 'packages', packageName, 'dist', basename),
86
+ path.join(projectRoot, 'dist', 'packages', packageName, 'src', basename),
87
+ path.join(projectRoot, 'dist', 'packages', packageName, 'src', sourceBasename),
88
+ path.join(projectRoot, 'packages', packageName, 'dist', basename),
89
+ path.join(projectRoot, 'packages', packageName, 'src', basename),
90
+ path.join(projectRoot, 'packages', packageName, 'src', sourceBasename),
91
+ ];
92
+ const resolved = candidates.find((candidate) => existsSync(candidate));
93
+ return resolved ? pathToFileURL(resolved).href : null;
94
+ };
95
+ const importSingleSpecifier = async (entry) => {
96
+ const target = entry.specifier.startsWith('.')
97
+ ? resolveRelativeSpecifier(entry)
98
+ : entry.specifier;
99
+ try {
100
+ await import(target);
101
+ Logger.debug('[plugins] Loaded auto-import specifier', { specifier: entry.specifier });
102
+ return true;
103
+ }
104
+ catch (error) {
105
+ const fallback = resolveLocalPackageSpecifier(entry.specifier);
106
+ if (fallback !== null) {
107
+ try {
108
+ await import(fallback);
109
+ Logger.debug('[plugins] Loaded auto-import specifier from local fallback', {
110
+ specifier: entry.specifier,
111
+ fallback,
112
+ });
113
+ return true;
114
+ }
115
+ catch (fallbackError) {
116
+ Logger.debug('[plugins] Failed auto-import local fallback', {
117
+ specifier: entry.specifier,
118
+ fallback,
119
+ error: fallbackError instanceof Error ? fallbackError.message : String(fallbackError),
120
+ });
121
+ }
122
+ }
123
+ Logger.debug('[plugins] Failed auto-import specifier', {
124
+ specifier: entry.specifier,
125
+ error: error instanceof Error ? error.message : String(error),
126
+ });
127
+ return false;
128
+ }
129
+ };
73
130
  const importSpecifiers = async (specifiers) => {
74
131
  // Import all specifiers in parallel
75
132
  const importPromises = Array.from(specifiers).map(async (entry) => {
76
- const target = entry.specifier.startsWith('.')
77
- ? resolveRelativeSpecifier(entry)
78
- : entry.specifier;
79
- try {
80
- await import(target);
81
- Logger.debug('[plugins] Loaded auto-import specifier', { specifier: entry.specifier });
82
- return { specifier: entry.specifier, success: true };
83
- }
84
- catch (error) {
85
- Logger.debug('[plugins] Failed auto-import specifier', {
86
- specifier: entry.specifier,
87
- error: error instanceof Error ? error.message : String(error),
88
- });
89
- return { specifier: entry.specifier, success: false };
90
- }
133
+ const success = await importSingleSpecifier(entry);
134
+ return { specifier: entry.specifier, success };
91
135
  });
92
136
  const results = await Promise.allSettled(importPromises);
93
137
  // Count successful imports
94
138
  return results.filter((result) => result.status === 'fulfilled' && result.value.success).length;
95
139
  };
96
140
  export const PluginAutoImports = Object.freeze({
141
+ async tryImportRuntimeAutoImports(mode = 'base') {
142
+ const specifiers = OfficialPlugins.getAutoImports(mode);
143
+ const loaded = await importSpecifiers(specifiers.map((specifier) => ({ specifier, filePath: `official:${mode}` })));
144
+ if (loaded === specifiers.length) {
145
+ return { ok: true, loadedPath: `official:${mode}` };
146
+ }
147
+ return {
148
+ ok: false,
149
+ loadedPath: `official:${mode}`,
150
+ reason: 'import-failed',
151
+ errorMessage: `Loaded ${loaded}/${specifiers.length} official plugin imports`,
152
+ };
153
+ },
97
154
  /**
98
155
  * Best-effort import of a project's `src/zintrust.plugins.ts` file.
99
156
  *
@@ -0,0 +1,2 @@
1
+ export { WorkerCommands } from './cli/commands/WorkerCommands';
2
+ //# sourceMappingURL=worker-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-commands.d.ts","sourceRoot":"","sources":["../../src/worker-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1 @@
1
+ export { WorkerCommands } from './cli/commands/WorkerCommands.js';