@zintrust/core 0.4.27 → 0.4.29

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 (33) hide show
  1. package/package.json +5 -1
  2. package/src/cli/CLI.d.ts.map +1 -1
  3. package/src/cli/CLI.js +4 -0
  4. package/src/cli/commands/D1ProxyCommand.d.ts +6 -0
  5. package/src/cli/commands/D1ProxyCommand.d.ts.map +1 -0
  6. package/src/cli/commands/D1ProxyCommand.js +229 -0
  7. package/src/cli/commands/InitContainerCommand.d.ts.map +1 -1
  8. package/src/cli/commands/InitContainerCommand.js +9 -96
  9. package/src/cli/commands/KvProxyCommand.d.ts +6 -0
  10. package/src/cli/commands/KvProxyCommand.d.ts.map +1 -0
  11. package/src/cli/commands/KvProxyCommand.js +217 -0
  12. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  13. package/src/cli/commands/NewCommand.js +8 -28
  14. package/src/cli/commands/ProxyCommand.d.ts.map +1 -1
  15. package/src/cli/commands/ProxyCommand.js +2 -0
  16. package/src/cli/commands/index.d.ts +2 -0
  17. package/src/cli/commands/index.d.ts.map +1 -1
  18. package/src/cli/commands/index.js +2 -0
  19. package/src/cli/index.d.ts +2 -0
  20. package/src/cli/index.d.ts.map +1 -1
  21. package/src/cli/index.js +2 -0
  22. package/src/cli/scaffolding/GovernanceScaffolder.d.ts.map +1 -1
  23. package/src/cli/scaffolding/GovernanceScaffolder.js +47 -3
  24. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  25. package/src/cli/scaffolding/ProjectScaffolder.js +39 -4
  26. package/src/cli/utils/DistPackager.d.ts +2 -2
  27. package/src/cli/utils/DistPackager.d.ts.map +1 -1
  28. package/src/cli/utils/DistPackager.js +9 -3
  29. package/src/index.js +3 -3
  30. package/src/proxy.d.ts +2 -0
  31. package/src/proxy.d.ts.map +1 -1
  32. package/src/proxy.js +2 -0
  33. package/src/templates/project/basic/package.json.tpl +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.4.27",
3
+ "version": "0.4.29",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -34,6 +34,10 @@
34
34
  "types": "./src/proxy.d.ts",
35
35
  "import": "./src/proxy.js"
36
36
  },
37
+ "./proxy/*": {
38
+ "types": "./src/proxy/*.d.ts",
39
+ "import": "./src/proxy/*.js"
40
+ },
37
41
  "./collections": {
38
42
  "types": "./src/collections/index.d.ts",
39
43
  "import": "./src/collections/index.js"
@@ -1 +1 @@
1
- {"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,WAAW,IAAI;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,IAAI,OAAO,CAAC;CACvB;AAsPD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
1
+ {"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,WAAW,IAAI;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,IAAI,OAAO,CAAC;CACvB;AAwPD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
package/src/cli/CLI.js CHANGED
@@ -11,6 +11,7 @@ import { ContainerWorkersCommand } from './commands/ContainerWorkersCommand.js';
11
11
  import { AddMigrationCommand, CreateCommand, CreateMigrationCommand, } from './commands/CreateCommand.js';
12
12
  import { D1LearnCommand } from './commands/D1LearnCommand.js';
13
13
  import { D1MigrateCommand } from './commands/D1MigrateCommand.js';
14
+ import { D1ProxyCommand } from './commands/D1ProxyCommand.js';
14
15
  import { DbSeedCommand } from './commands/DbSeedCommand.js';
15
16
  import { DebugCommand } from './commands/DebugCommand.js';
16
17
  import { DeployCommand } from './commands/DeployCommand.js';
@@ -28,6 +29,7 @@ import { InitProducerCommand } from './commands/InitProducerCommand.js';
28
29
  import { InitProxyCommand } from './commands/InitProxyCommand.js';
29
30
  import { JwtDevCommand } from './commands/JwtDevCommand.js';
30
31
  import { KeyGenerateCommand } from './commands/KeyGenerateCommand.js';
32
+ import { KvProxyCommand } from './commands/KvProxyCommand.js';
31
33
  import { MakeMailTemplateCommand } from './commands/MakeMailTemplateCommand.js';
32
34
  import { MakeNotificationTemplateCommand } from './commands/MakeNotificationTemplateCommand.js';
33
35
  import { MigrateCommand } from './commands/MigrateCommand.js';
@@ -128,6 +130,8 @@ const buildCommandRegistry = () => {
128
130
  RoutesCommand.create(),
129
131
  JwtDevCommand,
130
132
  ProxyCommand.create(),
133
+ D1ProxyCommand.create(),
134
+ KvProxyCommand.create(),
131
135
  MySqlProxyCommand.create(),
132
136
  PostgresProxyCommand.create(),
133
137
  MongoDBProxyCommand.create(),
@@ -0,0 +1,6 @@
1
+ import type { IBaseCommand } from '../BaseCommand';
2
+ export declare const D1ProxyCommand: Readonly<{
3
+ create(): IBaseCommand;
4
+ }>;
5
+ export default D1ProxyCommand;
6
+ //# sourceMappingURL=D1ProxyCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"D1ProxyCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/D1ProxyCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA4PrE,eAAO,MAAM,cAAc;cACf,YAAY;EAwCtB,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -0,0 +1,229 @@
1
+ import { BaseCommand } from '../BaseCommand.js';
2
+ import { maybeRunProxyWatchMode } from '../commands/ProxyCommandUtils.js';
3
+ import { SpawnUtil } from '../utils/spawn.js';
4
+ import { Env } from '../../config/env.js';
5
+ import { Logger } from '../../config/logger.js';
6
+ import { ErrorFactory } from '../../exceptions/ZintrustError.js';
7
+ import { isNonEmptyString } from '../../helper/index.js';
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from '../../node-singletons/fs.js';
9
+ import { join } from '../../node-singletons/path.js';
10
+ const DEFAULT_CONFIG = 'wrangler.jsonc';
11
+ const DEFAULT_COMPATIBILITY_DATE = '2026-03-12';
12
+ const DEFAULT_BINDING = 'ZIN_DB';
13
+ const DEFAULT_DATABASE_NAME = 'd1-proxy-db';
14
+ const DEFAULT_DATABASE_ID = '<your-d1-database-id>';
15
+ const DEFAULT_MIGRATIONS_DIR = 'database/migrations/d1';
16
+ const DEFAULT_ENTRY_FILE = 'src/proxy/d1/ZintrustD1Proxy.ts';
17
+ const trimOption = (value) => {
18
+ if (!isNonEmptyString(value))
19
+ return undefined;
20
+ const trimmed = value.trim();
21
+ return trimmed.length > 0 ? trimmed : undefined;
22
+ };
23
+ const resolveConfigPath = (raw) => {
24
+ const trimmed = trimOption(raw);
25
+ return trimmed ?? DEFAULT_CONFIG;
26
+ };
27
+ const isJsonWhitespace = (char) => {
28
+ return char === ' ' || char === '\n' || char === '\r' || char === '\t';
29
+ };
30
+ const findJsonKeyValueStart = (content, key) => {
31
+ const keyPosition = content.indexOf(`"${key}"`);
32
+ if (keyPosition < 0)
33
+ return -1;
34
+ let cursor = keyPosition + key.length + 2;
35
+ while (isJsonWhitespace(content[cursor]))
36
+ cursor++;
37
+ if (content[cursor] !== ':')
38
+ return -1;
39
+ cursor++;
40
+ while (isJsonWhitespace(content[cursor]))
41
+ cursor++;
42
+ return cursor;
43
+ };
44
+ const findQuotedValue = (content, key) => {
45
+ const valueStart = findJsonKeyValueStart(content, key);
46
+ if (valueStart < 0 || content[valueStart] !== '"')
47
+ return undefined;
48
+ const valueEnd = content.indexOf('"', valueStart + 1);
49
+ if (valueEnd < 0)
50
+ return undefined;
51
+ return trimOption(content.slice(valueStart + 1, valueEnd));
52
+ };
53
+ const hasEnvBlock = (content, envName) => {
54
+ const valueStart = findJsonKeyValueStart(content, envName);
55
+ return valueStart >= 0 && content[valueStart] === '{';
56
+ };
57
+ const findEnvObjectStart = (content) => {
58
+ const valueStart = findJsonKeyValueStart(content, 'env');
59
+ if (valueStart < 0 || content[valueStart] !== '{')
60
+ return -1;
61
+ return valueStart;
62
+ };
63
+ const isObjectEffectivelyEmpty = (content, objectStart) => {
64
+ let cursor = objectStart + 1;
65
+ while (isJsonWhitespace(content[cursor]))
66
+ cursor++;
67
+ return content[cursor] === '}';
68
+ };
69
+ const resolveConfigValues = (content, options) => {
70
+ const fileContent = content ?? '';
71
+ return {
72
+ binding: trimOption(options.binding) ??
73
+ trimOption(Env.get('D1_BINDING', '')) ??
74
+ findQuotedValue(fileContent, 'D1_BINDING') ??
75
+ findQuotedValue(fileContent, 'binding') ??
76
+ DEFAULT_BINDING,
77
+ databaseName: trimOption(options.databaseName) ??
78
+ trimOption(Env.get('D1_DATABASE_NAME', '')) ??
79
+ findQuotedValue(fileContent, 'database_name') ??
80
+ DEFAULT_DATABASE_NAME,
81
+ databaseId: trimOption(options.databaseId) ??
82
+ trimOption(Env.get('D1_DATABASE_ID', '')) ??
83
+ findQuotedValue(fileContent, 'database_id') ??
84
+ DEFAULT_DATABASE_ID,
85
+ migrationsDir: trimOption(options.migrationsDir) ??
86
+ findQuotedValue(fileContent, 'migrations_dir') ??
87
+ DEFAULT_MIGRATIONS_DIR,
88
+ };
89
+ };
90
+ const renderD1ProxyEnvBlock = (values) => {
91
+ return [
92
+ ' "d1-proxy": {',
93
+ ' "name": "zintrust-d1-proxy",',
94
+ ' "main": "./src/proxy/d1/ZintrustD1Proxy.ts",',
95
+ ' "compatibility_flags": ["nodejs_compat"],',
96
+ ` "compatibility_date": "${DEFAULT_COMPATIBILITY_DATE}",`,
97
+ ' "vars": {',
98
+ ` "D1_BINDING": "${values.binding}",`,
99
+ ' "ZT_PROXY_SIGNING_WINDOW_MS": "60000",',
100
+ ' "ZT_MAX_BODY_BYTES": "131072",',
101
+ ' "ZT_MAX_SQL_BYTES": "32768",',
102
+ ' "ZT_MAX_PARAMS": "256",',
103
+ ' "NODE_ENV": "development",',
104
+ String.raw ` "ZT_D1_STATEMENTS_JSON": "{\"health\":\"select 1 as ok\"}"`,
105
+ ' },',
106
+ ' "d1_databases": [',
107
+ ' {',
108
+ ` "binding": "${values.binding}",`,
109
+ ` "database_name": "${values.databaseName}",`,
110
+ ` "database_id": "${values.databaseId}",`,
111
+ ` "migrations_dir": "${values.migrationsDir}"`,
112
+ ' }',
113
+ ' ]',
114
+ ' }',
115
+ ].join('\n');
116
+ };
117
+ const renderDefaultWranglerConfig = (values) => {
118
+ return [
119
+ '{',
120
+ ' "name": "zintrust-api",',
121
+ ' "main": "./src/functions/cloudflare.ts",',
122
+ ` "compatibility_date": "${DEFAULT_COMPATIBILITY_DATE}",`,
123
+ ' "compatibility_flags": ["nodejs_compat"],',
124
+ ' "env": {',
125
+ renderD1ProxyEnvBlock(values),
126
+ ' }',
127
+ '}',
128
+ '',
129
+ ].join('\n');
130
+ };
131
+ const ensureProxyEntrypoint = (cwd) => {
132
+ const entryFilePath = join(cwd, DEFAULT_ENTRY_FILE);
133
+ if (existsSync(entryFilePath)) {
134
+ return { created: false, entryFilePath };
135
+ }
136
+ mkdirSync(join(cwd, 'src/proxy/d1'), { recursive: true });
137
+ writeFileSync(entryFilePath, [
138
+ "export { ZintrustD1Proxy } from '../../proxy.js';",
139
+ "export { ZintrustD1Proxy as default } from '../../proxy.js';",
140
+ '',
141
+ ].join('\n'), 'utf-8');
142
+ return { created: true, entryFilePath };
143
+ };
144
+ const injectEnvBlock = (content, block) => {
145
+ if (hasEnvBlock(content, 'd1-proxy'))
146
+ return content;
147
+ const envObjectStart = findEnvObjectStart(content);
148
+ if (envObjectStart >= 0 && isObjectEffectivelyEmpty(content, envObjectStart)) {
149
+ const closingBraceIndex = content.indexOf('}', envObjectStart);
150
+ if (closingBraceIndex >= 0) {
151
+ return `${content.slice(0, envObjectStart)}{\n${block}\n }${content.slice(closingBraceIndex + 1)}`;
152
+ }
153
+ }
154
+ if (envObjectStart >= 0) {
155
+ return `${content.slice(0, envObjectStart + 1)}\n${block},${content.slice(envObjectStart + 1)}`;
156
+ }
157
+ const closingIndex = content.lastIndexOf('}');
158
+ if (closingIndex < 0) {
159
+ throw ErrorFactory.createCliError('Invalid wrangler.jsonc: missing closing brace.');
160
+ }
161
+ const before = content.slice(0, closingIndex).trimEnd();
162
+ const suffix = before.endsWith('{') ? '\n' : ',\n';
163
+ return `${before}${suffix} "env": {\n${block}\n }\n}\n`;
164
+ };
165
+ const ensureWranglerConfig = (configPath, options) => {
166
+ if (!existsSync(configPath)) {
167
+ const values = resolveConfigValues(undefined, options);
168
+ writeFileSync(configPath, renderDefaultWranglerConfig(values), 'utf-8');
169
+ return { createdFile: true, insertedEnv: true, values };
170
+ }
171
+ const content = readFileSync(configPath, 'utf-8');
172
+ const values = resolveConfigValues(content, options);
173
+ const next = injectEnvBlock(content, renderD1ProxyEnvBlock(values));
174
+ if (next !== content) {
175
+ writeFileSync(configPath, next, 'utf-8');
176
+ return { createdFile: false, insertedEnv: true, values };
177
+ }
178
+ return { createdFile: false, insertedEnv: false, values };
179
+ };
180
+ const warnOnPlaceholderDatabaseId = (values) => {
181
+ if (values.databaseId !== DEFAULT_DATABASE_ID)
182
+ return;
183
+ Logger.warn('Could not resolve a D1 database id automatically. Update wrangler.jsonc or pass --database-id before relying on the generated d1-proxy environment.');
184
+ };
185
+ const addOptions = (command) => {
186
+ command.option('-c, --config <path>', 'Wrangler config file', DEFAULT_CONFIG);
187
+ command.option('--watch', 'Auto-restart proxy on file changes');
188
+ command.option('--binding <name>', 'D1 binding name', DEFAULT_BINDING);
189
+ command.option('--database-name <name>', 'Cloudflare D1 database name');
190
+ command.option('--database-id <id>', 'Cloudflare D1 database id');
191
+ command.option('--migrations-dir <path>', 'Cloudflare D1 migrations directory', DEFAULT_MIGRATIONS_DIR);
192
+ };
193
+ export const D1ProxyCommand = Object.freeze({
194
+ create() {
195
+ return BaseCommand.create({
196
+ name: 'proxy:d1',
197
+ aliases: ['d1:proxy'],
198
+ description: 'Start the local Cloudflare D1 proxy Worker via Wrangler and scaffold env.d1-proxy in wrangler.jsonc when missing',
199
+ addOptions,
200
+ execute: async (options) => {
201
+ await maybeRunProxyWatchMode(options.watch);
202
+ const cwd = process.cwd();
203
+ const entrypoint = ensureProxyEntrypoint(cwd);
204
+ const configPath = join(cwd, resolveConfigPath(options.config));
205
+ const result = ensureWranglerConfig(configPath, options);
206
+ if (entrypoint.created) {
207
+ Logger.info(`Created ${entrypoint.entryFilePath} from @zintrust/core proxy entrypoint.`);
208
+ }
209
+ if (result.createdFile) {
210
+ Logger.info(`Created ${configPath} with a default d1-proxy environment.`);
211
+ }
212
+ else if (result.insertedEnv) {
213
+ Logger.info(`Added env.d1-proxy to ${configPath}.`);
214
+ }
215
+ warnOnPlaceholderDatabaseId(result.values);
216
+ const exitCode = await SpawnUtil.spawnAndWait({
217
+ command: 'wrangler',
218
+ args: ['dev', '--config', configPath, '--env', 'd1-proxy'],
219
+ env: process.env,
220
+ forwardSignals: false,
221
+ });
222
+ if (exitCode !== 0) {
223
+ process.exit(exitCode);
224
+ }
225
+ },
226
+ });
227
+ },
228
+ });
229
+ export default D1ProxyCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"InitContainerCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/InitContainerCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAqSlE,eAAO,MAAM,oBAAoB;cACrB,YAAY;EAqBtB,CAAC"}
1
+ {"version":3,"file":"InitContainerCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/InitContainerCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA8MlE,eAAO,MAAM,oBAAoB;cACrB,YAAY;EAqBtB,CAAC"}
@@ -6,15 +6,14 @@ import { join } from '../../node-singletons/path.js';
6
6
  const DOCKER_COMPOSE_WORKERS_TEMPLATE = `name: zintrust-workers
7
7
 
8
8
  services:
9
- # Workers/Jobs API Service (Port 7772)
10
- # Exposes the Workers API to create/manage jobs using the project worker overlay image.
9
+ # Worker runtime service (Port 7772)
10
+ # Boots the full ZinTrust server so the worker pages stay reachable while workers auto-start.
11
11
  workers-api:
12
12
  image: \${WORKERS_IMAGE:-zintrust-workers-local:latest}
13
13
  build:
14
14
  context: .
15
15
  dockerfile: Dockerfile.workers
16
- target: runtime
17
- command: ["node", "--experimental-specifier-resolution=node", "dist/src/boot/bootstrap.js"]
16
+ target: worker
18
17
  environment:
19
18
  # Runtime
20
19
  - NODE_ENV=\${NODE_ENV:-development}
@@ -29,8 +28,8 @@ services:
29
28
  - LOG_LEVEL=\${LOG_LEVEL:-info}
30
29
 
31
30
  # Workers & Queue
32
- - WORKER_ENABLED=\${WORKER_ENABLED:-false}
33
- - WORKER_AUTO_START=\${WORKER_AUTO_START:-false}
31
+ - WORKER_ENABLED=\${WORKER_ENABLED:-true}
32
+ - WORKER_AUTO_START=\${WORKER_AUTO_START:-true}
34
33
  - QUEUE_ENABLED=true
35
34
  - QUEUE_MONITOR_ENABLED=\${QUEUE_MONITOR_ENABLED:-false}
36
35
  - QUEUE_MONITOR_MIDDLEWARE=\${QUEUE_MONITOR_MIDDLEWARE:-}
@@ -96,92 +95,6 @@ services:
96
95
  ports:
97
96
  - '7772:7772'
98
97
 
99
- # Dedicated background worker runner.
100
- # Uses the same project overlay image but boots the worker target.
101
- worker-runner:
102
- image: \${WORKERS_RUNNER_IMAGE:-zintrust-workers-local:latest}
103
- build:
104
- context: .
105
- dockerfile: Dockerfile.workers
106
- target: worker
107
- environment:
108
- # Runtime
109
- - NODE_ENV=\${NODE_ENV:-development}
110
- - HOST=0.0.0.0
111
-
112
- # Application
113
- - APP_NAME=\${APP_NAME:-ZinTrust}
114
- - APP_KEY=\${APP_KEY}
115
- - ENCRYPTION_CIPHER=\${ENCRYPTION_CIPHER:-aes-256-cbc}
116
- - LOG_LEVEL=\${LOG_LEVEL:-info}
117
-
118
- # Workers & Queue
119
- - DOCKER_WORKER=true
120
- - WORKER_ENABLED=\${WORKER_ENABLED:-true}
121
- - WORKER_AUTO_START=\${WORKER_AUTO_START:-true}
122
- - QUEUE_ENABLED=true
123
- - QUEUE_MONITOR_ENABLED=\${QUEUE_MONITOR_ENABLED:-false}
124
- - QUEUE_MONITOR_MIDDLEWARE=\${QUEUE_MONITOR_MIDDLEWARE:-}
125
- - WORKER_PERSISTENCE_DRIVER=\${WORKER_PERSISTENCE_DRIVER:-redis}
126
- - WORKER_PERSISTENCE_DB_CONNECTION=\${WORKER_PERSISTENCE_DB_CONNECTION:-mysql}
127
- - WORKER_PERSISTENCE_REDIS_KEY_PREFIX=\${WORKER_PERSISTENCE_REDIS_KEY_PREFIX}
128
- - QUEUE_DRIVER=\${QUEUE_DRIVER:-redis}
129
- - QUEUE_CONNECTION=\${QUEUE_CONNECTION:-redis}
130
- - CACHE_DRIVER=\${CACHE_DRIVER:-redis}
131
-
132
- # Redis
133
- - REDIS_HOST=\${DOCKER_REDIS_HOST:-host.docker.internal}
134
- - REDIS_PORT=\${REDIS_PORT:-6379}
135
- - REDIS_PASSWORD=\${REDIS_PASSWORD}
136
- - REDIS_QUEUE_DB=\${REDIS_QUEUE_DB:-1}
137
-
138
- # Database
139
- - DB_CONNECTION=\${DB_CONNECTION:-postgres}
140
- - DB_HOST=\${DOCKER_DB_HOST:-host.docker.internal}
141
- - DB_PORT=\${DB_PORT:-3306}
142
- - DB_DATABASE=\${DB_DATABASE:-zintrust}
143
- - DB_USERNAME=\${DB_USERNAME:-zintrust}
144
- - DB_PASSWORD=\${DB_PASSWORD:-}
145
-
146
- # SMTP Mail
147
- - MAIL_DRIVER=\${MAIL_DRIVER:-smtp}
148
- - MAIL_CONNECTION=\${MAIL_CONNECTION:-smtp}
149
- - MAIL_HOST=\${MAIL_HOST}
150
- - MAIL_PORT=\${MAIL_PORT:-587}
151
- - MAIL_SECURE=\${MAIL_SECURE:-false}
152
- - MAIL_USERNAME=\${MAIL_USERNAME}
153
- - MAIL_PASSWORD=\${MAIL_PASSWORD}
154
- - MAIL_FROM_ADDRESS=\${MAIL_FROM_ADDRESS}
155
- - MAIL_FROM_NAME=\${MAIL_FROM_NAME:-ZinTrust}
156
-
157
- # PostgreSQL
158
- - DB_PORT_POSTGRESQL=\${DB_PORT_POSTGRESQL:-5432}
159
- - DB_DATABASE_POSTGRESQL=\${DB_DATABASE_POSTGRESQL:-zintrust}
160
- - DB_USERNAME_POSTGRESQL=\${DB_USERNAME_POSTGRESQL:-zintrust}
161
- - DB_PASSWORD_POSTGRESQL=\${DB_PASSWORD_POSTGRESQL:-}
162
-
163
- # MySQL
164
- - DB_PORT_MYSQL=\${DB_PORT_MYSQL:-3306}
165
- - DB_DATABASE_MYSQL=\${DB_DATABASE_MYSQL:-zintrust}
166
- - DB_USERNAME_MYSQL=\${DB_USERNAME_MYSQL:-zintrust}
167
- - DB_PASSWORD_MYSQL=\${DB_PASSWORD_MYSQL:-}
168
-
169
- # Cloudflare D1
170
- - D1_DATABASE_ID=\${D1_DATABASE_ID}
171
- - D1_ACCOUNT_ID=\${D1_ACCOUNT_ID}
172
- - D1_API_TOKEN=\${D1_API_TOKEN}
173
- - D1_REMOTE_URL=\${D1_REMOTE_URL}
174
- - D1_REMOTE_KEY_ID=\${D1_REMOTE_KEY_ID}
175
- - D1_REMOTE_SECRET=\${D1_REMOTE_SECRET}
176
-
177
- # Cloudflare KV
178
- - KV_NAMESPACE_ID=\${KV_NAMESPACE_ID}
179
- - KV_ACCOUNT_ID=\${KV_ACCOUNT_ID}
180
- - KV_API_TOKEN=\${KV_API_TOKEN}
181
- - KV_REMOTE_URL=\${KV_REMOTE_URL}
182
- - KV_REMOTE_KEY_ID=\${KV_REMOTE_KEY_ID}
183
- - KV_REMOTE_SECRET=\${KV_REMOTE_SECRET}
184
-
185
98
  `;
186
99
  const DOCKERFILE_TEMPLATE = String.raw `# Multi-stage worker overlay image.
187
100
  #
@@ -229,15 +142,15 @@ COPY --from=worker-overlay --chown=nodejs:nodejs /overlay/dist/ /app/dist/
229
142
 
230
143
  FROM runtime AS worker
231
144
 
232
- ENV DOCKER_WORKER=true
233
145
  ENV WORKER_ENABLED=true
234
146
  ENV WORKER_AUTO_START=true
235
147
  ENV QUEUE_ENABLED=true
236
- ENV PORT=0
148
+ ENV HOST=0.0.0.0
149
+ ENV PORT=7772
237
150
 
238
151
  HEALTHCHECK NONE
239
152
 
240
- CMD ["node", "dist/bin/zin.js", "worker:start-all"]
153
+ CMD ["node", "--experimental-specifier-resolution=node", "dist/src/boot/bootstrap.js"]
241
154
  `;
242
155
  const backupSuffix = () => new Date().toISOString().replaceAll(/[:.]/g, '-');
243
156
  const backupFileIfExists = (filePath) => {
@@ -290,7 +203,7 @@ export const InitContainerCommand = Object.freeze({
290
203
  await writeDockerfile(cwd);
291
204
  Logger.info('✅ Container worker scaffolding complete.');
292
205
  Logger.info('Run with: docker compose -f docker-compose.workers.yml up');
293
- Logger.info('Build worker runner with: docker build -f Dockerfile.workers --target worker .');
206
+ Logger.info('Build worker runtime with: docker build -f Dockerfile.workers --target worker .');
294
207
  await Promise.resolve();
295
208
  },
296
209
  });
@@ -0,0 +1,6 @@
1
+ import type { IBaseCommand } from '../BaseCommand';
2
+ export declare const KvProxyCommand: Readonly<{
3
+ create(): IBaseCommand;
4
+ }>;
5
+ export default KvProxyCommand;
6
+ //# sourceMappingURL=KvProxyCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KvProxyCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/KvProxyCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAyOrE,eAAO,MAAM,cAAc;cACf,YAAY;EAwCtB,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -0,0 +1,217 @@
1
+ import { BaseCommand } from '../BaseCommand.js';
2
+ import { maybeRunProxyWatchMode } from '../commands/ProxyCommandUtils.js';
3
+ import { SpawnUtil } from '../utils/spawn.js';
4
+ import { Env } from '../../config/env.js';
5
+ import { Logger } from '../../config/logger.js';
6
+ import { ErrorFactory } from '../../exceptions/ZintrustError.js';
7
+ import { isNonEmptyString } from '../../helper/index.js';
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from '../../node-singletons/fs.js';
9
+ import { join } from '../../node-singletons/path.js';
10
+ const DEFAULT_CONFIG = 'wrangler.jsonc';
11
+ const DEFAULT_COMPATIBILITY_DATE = '2026-03-12';
12
+ const DEFAULT_BINDING = 'ZIN_KV';
13
+ const DEFAULT_NAMESPACE_ID = '<your-kv-namespace-id>';
14
+ const DEFAULT_ENTRY_FILE = 'src/proxy/kv/ZintrustKvProxy.ts';
15
+ const trimOption = (value) => {
16
+ if (!isNonEmptyString(value))
17
+ return undefined;
18
+ const trimmed = value.trim();
19
+ return trimmed.length > 0 ? trimmed : undefined;
20
+ };
21
+ const resolveConfigPath = (raw) => trimOption(raw) ?? DEFAULT_CONFIG;
22
+ const isJsonWhitespace = (char) => {
23
+ return char === ' ' || char === '\n' || char === '\r' || char === '\t';
24
+ };
25
+ const findJsonKeyValueStart = (content, key) => {
26
+ const keyPosition = content.indexOf(`"${key}"`);
27
+ if (keyPosition < 0)
28
+ return -1;
29
+ let cursor = keyPosition + key.length + 2;
30
+ while (isJsonWhitespace(content[cursor]))
31
+ cursor++;
32
+ if (content[cursor] !== ':')
33
+ return -1;
34
+ cursor++;
35
+ while (isJsonWhitespace(content[cursor]))
36
+ cursor++;
37
+ return cursor;
38
+ };
39
+ const findQuotedValue = (content, key) => {
40
+ const valueStart = findJsonKeyValueStart(content, key);
41
+ if (valueStart < 0 || content[valueStart] !== '"')
42
+ return undefined;
43
+ const valueEnd = content.indexOf('"', valueStart + 1);
44
+ if (valueEnd < 0)
45
+ return undefined;
46
+ return trimOption(content.slice(valueStart + 1, valueEnd));
47
+ };
48
+ const hasEnvBlock = (content, envName) => {
49
+ const valueStart = findJsonKeyValueStart(content, envName);
50
+ return valueStart >= 0 && content[valueStart] === '{';
51
+ };
52
+ const findEnvObjectStart = (content) => {
53
+ const valueStart = findJsonKeyValueStart(content, 'env');
54
+ if (valueStart < 0 || content[valueStart] !== '{')
55
+ return -1;
56
+ return valueStart;
57
+ };
58
+ const isObjectEffectivelyEmpty = (content, objectStart) => {
59
+ let cursor = objectStart + 1;
60
+ while (isJsonWhitespace(content[cursor]))
61
+ cursor++;
62
+ return content[cursor] === '}';
63
+ };
64
+ const resolveConfigValues = (content, options) => {
65
+ const fileContent = content ?? '';
66
+ const namespaceId = trimOption(options.namespaceId) ??
67
+ trimOption(Env.get('KV_NAMESPACE_ID', '')) ??
68
+ findQuotedValue(fileContent, 'preview_id') ??
69
+ findQuotedValue(fileContent, 'id') ??
70
+ DEFAULT_NAMESPACE_ID;
71
+ return {
72
+ binding: trimOption(options.binding) ??
73
+ trimOption(Env.get('KV_NAMESPACE', '')) ??
74
+ findQuotedValue(fileContent, 'KV_NAMESPACE') ??
75
+ findQuotedValue(fileContent, 'binding') ??
76
+ DEFAULT_BINDING,
77
+ namespaceId,
78
+ previewId: trimOption(options.previewId) ??
79
+ trimOption(Env.get('KV_NAMESPACE_PREVIEW_ID', '')) ??
80
+ findQuotedValue(fileContent, 'preview_id') ??
81
+ namespaceId,
82
+ };
83
+ };
84
+ const renderKvProxyEnvBlock = (values) => {
85
+ return [
86
+ ' "kv-proxy": {',
87
+ ' "name": "zintrust-kv-proxy",',
88
+ ' "main": "./src/proxy/kv/ZintrustKvProxy.ts",',
89
+ ' "compatibility_flags": ["nodejs_compat"],',
90
+ ` "compatibility_date": "${DEFAULT_COMPATIBILITY_DATE}",`,
91
+ ' "vars": {',
92
+ ` "KV_NAMESPACE": "${values.binding}",`,
93
+ ' "NODE_ENV": "development"',
94
+ ' },',
95
+ ' "kv_namespaces": [',
96
+ ' {',
97
+ ` "binding": "${values.binding}",`,
98
+ ` "id": "${values.namespaceId}",`,
99
+ ` "preview_id": "${values.previewId}",`,
100
+ ' "remote": false',
101
+ ' }',
102
+ ' ]',
103
+ ' }',
104
+ ].join('\n');
105
+ };
106
+ const renderDefaultWranglerConfig = (values) => {
107
+ return [
108
+ '{',
109
+ ' "name": "zintrust-api",',
110
+ ' "main": "./src/functions/cloudflare.ts",',
111
+ ` "compatibility_date": "${DEFAULT_COMPATIBILITY_DATE}",`,
112
+ ' "compatibility_flags": ["nodejs_compat"],',
113
+ ' "env": {',
114
+ renderKvProxyEnvBlock(values),
115
+ ' }',
116
+ '}',
117
+ '',
118
+ ].join('\n');
119
+ };
120
+ const ensureProxyEntrypoint = (cwd) => {
121
+ const entryFilePath = join(cwd, DEFAULT_ENTRY_FILE);
122
+ if (existsSync(entryFilePath)) {
123
+ return { created: false, entryFilePath };
124
+ }
125
+ mkdirSync(join(cwd, 'src/proxy/kv'), { recursive: true });
126
+ writeFileSync(entryFilePath, [
127
+ "export { ZintrustKvProxy } from '../../proxy.js';",
128
+ "export { ZintrustKvProxy as default } from '../../proxy.js';",
129
+ '',
130
+ ].join('\n'), 'utf-8');
131
+ return { created: true, entryFilePath };
132
+ };
133
+ const injectEnvBlock = (content, block) => {
134
+ if (hasEnvBlock(content, 'kv-proxy'))
135
+ return content;
136
+ const envObjectStart = findEnvObjectStart(content);
137
+ if (envObjectStart >= 0 && isObjectEffectivelyEmpty(content, envObjectStart)) {
138
+ const closingBraceIndex = content.indexOf('}', envObjectStart);
139
+ if (closingBraceIndex >= 0) {
140
+ return `${content.slice(0, envObjectStart)}{\n${block}\n }${content.slice(closingBraceIndex + 1)}`;
141
+ }
142
+ }
143
+ if (envObjectStart >= 0) {
144
+ return `${content.slice(0, envObjectStart + 1)}\n${block},${content.slice(envObjectStart + 1)}`;
145
+ }
146
+ const closingIndex = content.lastIndexOf('}');
147
+ if (closingIndex < 0) {
148
+ throw ErrorFactory.createCliError('Invalid wrangler.jsonc: missing closing brace.');
149
+ }
150
+ const before = content.slice(0, closingIndex).trimEnd();
151
+ const suffix = before.endsWith('{') ? '\n' : ',\n';
152
+ return `${before}${suffix} "env": {\n${block}\n }\n}\n`;
153
+ };
154
+ const ensureWranglerConfig = (configPath, options) => {
155
+ if (!existsSync(configPath)) {
156
+ const values = resolveConfigValues(undefined, options);
157
+ writeFileSync(configPath, renderDefaultWranglerConfig(values), 'utf-8');
158
+ return { createdFile: true, insertedEnv: true, values };
159
+ }
160
+ const content = readFileSync(configPath, 'utf-8');
161
+ const values = resolveConfigValues(content, options);
162
+ const next = injectEnvBlock(content, renderKvProxyEnvBlock(values));
163
+ if (next !== content) {
164
+ writeFileSync(configPath, next, 'utf-8');
165
+ return { createdFile: false, insertedEnv: true, values };
166
+ }
167
+ return { createdFile: false, insertedEnv: false, values };
168
+ };
169
+ const warnOnPlaceholderNamespaceId = (values) => {
170
+ if (values.namespaceId !== DEFAULT_NAMESPACE_ID)
171
+ return;
172
+ Logger.warn('Could not resolve a KV namespace id automatically. Update wrangler.jsonc or pass --namespace-id before relying on the generated kv-proxy environment.');
173
+ };
174
+ const addOptions = (command) => {
175
+ command.option('-c, --config <path>', 'Wrangler config file', DEFAULT_CONFIG);
176
+ command.option('--watch', 'Auto-restart proxy on file changes');
177
+ command.option('--binding <name>', 'KV binding name', DEFAULT_BINDING);
178
+ command.option('--namespace-id <id>', 'Cloudflare KV namespace id');
179
+ command.option('--preview-id <id>', 'Cloudflare KV preview namespace id');
180
+ };
181
+ export const KvProxyCommand = Object.freeze({
182
+ create() {
183
+ return BaseCommand.create({
184
+ name: 'proxy:kv',
185
+ aliases: ['kv:proxy'],
186
+ description: 'Start the local Cloudflare KV proxy Worker via Wrangler and scaffold env.kv-proxy in wrangler.jsonc when missing',
187
+ addOptions,
188
+ execute: async (options) => {
189
+ await maybeRunProxyWatchMode(options.watch);
190
+ const cwd = process.cwd();
191
+ const entrypoint = ensureProxyEntrypoint(cwd);
192
+ const configPath = join(cwd, resolveConfigPath(options.config));
193
+ const result = ensureWranglerConfig(configPath, options);
194
+ if (entrypoint.created) {
195
+ Logger.info(`Created ${entrypoint.entryFilePath} from @zintrust/core proxy entrypoint.`);
196
+ }
197
+ if (result.createdFile) {
198
+ Logger.info(`Created ${configPath} with a default kv-proxy environment.`);
199
+ }
200
+ else if (result.insertedEnv) {
201
+ Logger.info(`Added env.kv-proxy to ${configPath}.`);
202
+ }
203
+ warnOnPlaceholderNamespaceId(result.values);
204
+ const exitCode = await SpawnUtil.spawnAndWait({
205
+ command: 'wrangler',
206
+ args: ['dev', '--config', configPath, '--env', 'kv-proxy'],
207
+ env: process.env,
208
+ forwardSignals: false,
209
+ });
210
+ if (exitCode !== 0) {
211
+ process.exit(exitCode);
212
+ }
213
+ },
214
+ });
215
+ },
216
+ });
217
+ export default KvProxyCommand;
@@ -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,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"}
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;AAerE,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;AAoQD;;;GAGG;AACH,eAAO,MAAM,UAAU;IACrB;;OAEG;cACO,WAAW;EAGrB,CAAC"}
@@ -8,7 +8,6 @@ import { extractErrorMessage, resolvePackageManager } from '../../common/index.j
8
8
  import { appConfig } from '../../config/app.js';
9
9
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
10
10
  import { execFileSync } from '../../node-singletons/child-process.js';
11
- import fs from '../../node-singletons/fs.js';
12
11
  import * as path from '../../node-singletons/path.js';
13
12
  import chalk from 'chalk';
14
13
  const getGitBinary = () => 'git';
@@ -237,38 +236,19 @@ const addOptions = (command) => {
237
236
  command.option('--install', 'Force dependency installation (useful to override CI defaults)');
238
237
  command.option('--package-manager <manager>', 'Package manager to use (npm, yarn, pnpm)');
239
238
  command.option('--governance', 'Install governance tooling (ESLint + architecture tests)', false);
240
- command.option('--with-d1-proxy', 'Add @zintrust/cloudflare-d1-proxy to package.json (for deploying the D1 proxy worker)', false);
239
+ command.option('--with-d1-proxy', 'Show D1 proxy setup guidance for repo-managed proxy Workers', false);
241
240
  command.option('--force', 'Overwrite existing directory');
242
241
  command.option('--overwrite', 'Overwrite existing directory');
243
242
  };
244
- const maybeAddD1ProxyDependency = (projectPath, options, log) => {
243
+ const maybeAddD1ProxyDependency = (options, log) => {
245
244
  const enabled = options['withD1Proxy'] === true || options['with-d1-proxy'] === true;
246
245
  if (!enabled)
247
246
  return;
248
- const packageJsonPath = path.join(projectPath, 'package.json');
249
- if (!fs.existsSync(packageJsonPath)) {
250
- log.warn(`Could not add @zintrust/cloudflare-d1-proxy (missing package.json at ${packageJsonPath})`);
251
- return;
252
- }
253
- try {
254
- const raw = fs.readFileSync(packageJsonPath, 'utf8');
255
- const pkg = JSON.parse(raw);
256
- const dependencies = { ...pkg.dependencies };
257
- if (typeof dependencies['@zintrust/cloudflare-d1-proxy'] !== 'string') {
258
- // Avoid pinning to core version (they can differ). Use a safe caret range.
259
- dependencies['@zintrust/cloudflare-d1-proxy'] = '^0.1.42';
260
- }
261
- const next = {
262
- ...pkg,
263
- dependencies,
264
- };
265
- fs.writeFileSync(packageJsonPath, JSON.stringify(next, null, 2) + '\n');
266
- log.info('✅ Added @zintrust/cloudflare-d1-proxy to dependencies');
267
- }
268
- catch (error) {
269
- ErrorFactory.createCliError('Failed to update package.json with D1 proxy dependency', error);
270
- log.warn('Please add @zintrust/cloudflare-d1-proxy manually if you need the proxy worker.');
271
- }
247
+ log.info([
248
+ 'D1 proxy Workers are now repo-managed and are not scaffolded as a standalone app dependency.',
249
+ 'Use @zintrust/core/proxy for the Worker entrypoint export,',
250
+ 'run zin proxy:d1 for local dev, and zin deploy d1-proxy for deployment.',
251
+ ].join(' '));
272
252
  };
273
253
  const resolveProjectName = async (options) => {
274
254
  const argName = options.args?.[0];
@@ -320,7 +300,7 @@ const createProject = async (target, options, command) => {
320
300
  }
321
301
  }
322
302
  // Optional dependency injection must happen before `npm/yarn/pnpm install`.
323
- maybeAddD1ProxyDependency(target.projectPath, options, command);
303
+ maybeAddD1ProxyDependency(options, command);
324
304
  };
325
305
  const maybeInitializeGit = (options, command, target) => {
326
306
  if (options['git'] !== false) {
@@ -1 +1 @@
1
- {"version":3,"file":"ProxyCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ProxyCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrE,OAAO,oBAAoB,CAAC;AAC5B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,0BAA0B,CAAC;AAClC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,sBAAsB,CAAC;AAyD9B,eAAO,MAAM,YAAY;cACb,YAAY;EAyBtB,CAAC;AAEH,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ProxyCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ProxyCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrE,OAAO,oBAAoB,CAAC;AAC5B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,0BAA0B,CAAC;AAClC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,sBAAsB,CAAC;AA2D9B,eAAO,MAAM,YAAY;cACb,YAAY;EAyBtB,CAAC;AAEH,eAAe,YAAY,CAAC"}
@@ -10,6 +10,8 @@ import '../../proxy/postgres/register.js';
10
10
  import '../../proxy/redis/register.js';
11
11
  import '../../proxy/smtp/register.js';
12
12
  const PROXY_TARGET_MAP = Object.freeze({
13
+ d1: 'proxy:d1',
14
+ kv: 'proxy:kv',
13
15
  mysql: 'proxy:mysql',
14
16
  my: 'proxy:mysql',
15
17
  postgres: 'proxy:postgres',
@@ -6,8 +6,10 @@ export { BroadcastWorkCommand } from '../commands/BroadcastWorkCommand';
6
6
  export { ConfigCommand } from '../commands/ConfigCommand';
7
7
  export { ContainerWorkersCommand } from '../commands/ContainerWorkersCommand';
8
8
  export { AddMigrationCommand, CreateCommand, CreateMigrationCommand, } from '../commands/CreateCommand';
9
+ export { D1ProxyCommand } from '../commands/D1ProxyCommand';
9
10
  export { DebugCommand } from '../commands/DebugCommand';
10
11
  export { JwtDevCommand } from '../commands/JwtDevCommand';
12
+ export { KvProxyCommand } from '../commands/KvProxyCommand';
11
13
  export { LogsCleanupCommand } from '../commands/LogsCleanupCommand';
12
14
  export { MakeMailTemplateCommand } from '../commands/MakeMailTemplateCommand';
13
15
  export { MakeNotificationTemplateCommand } from '../commands/MakeNotificationTemplateCommand';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,+CAA+C,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,+CAA+C,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
@@ -6,8 +6,10 @@ export { BroadcastWorkCommand } from '../commands/BroadcastWorkCommand.js';
6
6
  export { ConfigCommand } from '../commands/ConfigCommand.js';
7
7
  export { ContainerWorkersCommand } from '../commands/ContainerWorkersCommand.js';
8
8
  export { AddMigrationCommand, CreateCommand, CreateMigrationCommand, } from '../commands/CreateCommand.js';
9
+ export { D1ProxyCommand } from '../commands/D1ProxyCommand.js';
9
10
  export { DebugCommand } from '../commands/DebugCommand.js';
10
11
  export { JwtDevCommand } from '../commands/JwtDevCommand.js';
12
+ export { KvProxyCommand } from '../commands/KvProxyCommand.js';
11
13
  export { LogsCleanupCommand } from '../commands/LogsCleanupCommand.js';
12
14
  export { MakeMailTemplateCommand } from '../commands/MakeMailTemplateCommand.js';
13
15
  export { MakeNotificationTemplateCommand } from '../commands/MakeNotificationTemplateCommand.js';
@@ -8,7 +8,9 @@ export { EXIT_CODES, ErrorHandler } from './ErrorHandler';
8
8
  export { PromptHelper, type PromptOptions } from './PromptHelper';
9
9
  export { AddCommand } from './commands/AddCommand';
10
10
  export { ConfigCommand } from './commands/ConfigCommand';
11
+ export { D1ProxyCommand } from './commands/D1ProxyCommand';
11
12
  export { DebugCommand } from './commands/DebugCommand';
13
+ export { KvProxyCommand } from './commands/KvProxyCommand';
12
14
  export { MigrateCommand } from './commands/MigrateCommand';
13
15
  export { MySqlProxyCommand } from './commands/MySqlProxyCommand';
14
16
  export { NewCommand } from './commands/NewCommand';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC"}
package/src/cli/index.js CHANGED
@@ -9,7 +9,9 @@ export { PromptHelper } from './PromptHelper.js';
9
9
  // Export commands
10
10
  export { AddCommand } from './commands/AddCommand.js';
11
11
  export { ConfigCommand } from './commands/ConfigCommand.js';
12
+ export { D1ProxyCommand } from './commands/D1ProxyCommand.js';
12
13
  export { DebugCommand } from './commands/DebugCommand.js';
14
+ export { KvProxyCommand } from './commands/KvProxyCommand.js';
13
15
  export { MigrateCommand } from './commands/MigrateCommand.js';
14
16
  export { MySqlProxyCommand } from './commands/MySqlProxyCommand.js';
15
17
  export { NewCommand } from './commands/NewCommand.js';
@@ -1 +1 @@
1
- {"version":3,"file":"GovernanceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/GovernanceScaffolder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmBH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AA8RH,eAAO,MAAM,oBAAoB;0BAEhB,MAAM,YACV,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC;EA+DpC,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"GovernanceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/GovernanceScaffolder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AA8UH,eAAO,MAAM,oBAAoB;0BAEhB,MAAM,YACV,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC;EA+DpC,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
@@ -6,6 +6,7 @@
6
6
  * - Architecture tests (Vitest)
7
7
  */
8
8
  import { FileGenerator } from '../scaffolding/FileGenerator.js';
9
+ import { VersionChecker } from '../services/VersionChecker.js';
9
10
  import { SpawnUtil } from '../utils/spawn.js';
10
11
  import { resolvePackageManager } from '../../common/index.js';
11
12
  import { Logger } from '../../config/logger.js';
@@ -49,12 +50,55 @@ const ensureDevDependency = (devDependencies, name, version) => {
49
50
  devDependencies[name] = version;
50
51
  }
51
52
  };
53
+ const extractMajorMinorVersion = (value) => {
54
+ const trimmed = value.trim();
55
+ let start = -1;
56
+ for (let index = 0; index < trimmed.length; index++) {
57
+ const char = trimmed[index];
58
+ if (char !== undefined && char >= '0' && char <= '9') {
59
+ start = index;
60
+ break;
61
+ }
62
+ }
63
+ if (start < 0)
64
+ return undefined;
65
+ let end = start;
66
+ while (end < trimmed.length) {
67
+ const char = trimmed[end];
68
+ const isDigit = char !== undefined && char >= '0' && char <= '9';
69
+ if (!isDigit && char !== '.')
70
+ break;
71
+ end++;
72
+ }
73
+ const parts = trimmed.slice(start, end).split('.');
74
+ if (parts.length < 3)
75
+ return undefined;
76
+ const [major, minor, patch] = parts;
77
+ if (!major || !minor || !patch)
78
+ return undefined;
79
+ return { major, minor };
80
+ };
81
+ const toCompatibleGovernanceVersion = (value) => {
82
+ const parsed = extractMajorMinorVersion(value);
83
+ if (parsed === undefined)
84
+ return undefined;
85
+ return `^${parsed.major}.${parsed.minor}.0`;
86
+ };
52
87
  const inferGovernanceVersion = (pkg) => {
53
88
  const deps = getStringRecord(pkg.dependencies);
54
89
  const core = deps?.['@zintrust/core'];
55
- if (typeof core === 'string' && core.trim() !== '')
56
- return core;
57
- return '^0.1.0';
90
+ if (typeof core === 'string' && core.trim() !== '') {
91
+ const compatibleFromCore = toCompatibleGovernanceVersion(core);
92
+ if (compatibleFromCore !== undefined)
93
+ return compatibleFromCore;
94
+ }
95
+ const currentVersion = VersionChecker.getCurrentVersion().trim();
96
+ if (currentVersion !== '' && currentVersion !== '0.0.0') {
97
+ const compatibleFromCli = toCompatibleGovernanceVersion(currentVersion);
98
+ if (compatibleFromCli !== undefined)
99
+ return compatibleFromCli;
100
+ }
101
+ return '^0.4.0';
58
102
  };
59
103
  const writeEslintConfig = (projectRoot) => {
60
104
  const eslintConfigPath = path.join(projectRoot, 'eslint.config.mjs');
@@ -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;AA6ID;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,GAAE,MAAsB,GAAG,kBAAkB,CAsB/F;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAEhC;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;EAM5B,CAAC"}
1
+ {"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;AA0fD,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;AA8ID;;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"}
@@ -20,6 +20,40 @@ const loadCoreVersion = () => {
20
20
  return '0.0.0';
21
21
  }
22
22
  };
23
+ const extractMajorMinorVersion = (value) => {
24
+ const trimmed = value.trim();
25
+ let start = -1;
26
+ for (let index = 0; index < trimmed.length; index++) {
27
+ const char = trimmed[index];
28
+ if (char !== undefined && char >= '0' && char <= '9') {
29
+ start = index;
30
+ break;
31
+ }
32
+ }
33
+ if (start < 0)
34
+ return undefined;
35
+ let end = start;
36
+ while (end < trimmed.length) {
37
+ const char = trimmed[end];
38
+ const isDigit = char !== undefined && char >= '0' && char <= '9';
39
+ if (!isDigit && char !== '.')
40
+ break;
41
+ end++;
42
+ }
43
+ const parts = trimmed.slice(start, end).split('.');
44
+ if (parts.length < 3)
45
+ return undefined;
46
+ const [major, minor, patch] = parts;
47
+ if (!major || !minor || !patch)
48
+ return undefined;
49
+ return { major, minor };
50
+ };
51
+ const toCompatibleGovernanceVersion = (version) => {
52
+ const parsed = extractMajorMinorVersion(version);
53
+ if (parsed !== undefined)
54
+ return `^${parsed.major}.${parsed.minor}.0`;
55
+ return '^0.4.0';
56
+ };
23
57
  const createDirectories = (projectPath, directories) => {
24
58
  let count = 0;
25
59
  if (!fs.existsSync(projectPath)) {
@@ -239,11 +273,11 @@ const readTemplateJson = (templateJsonPath) => {
239
273
  }
240
274
  };
241
275
  const resolveTemplateMetadata = (templateName, meta, fallback) => {
242
- const name = typeof meta.name === 'string' ? meta.name : fallback?.name ?? templateName;
243
- const description = typeof meta.description === 'string' ? meta.description : fallback?.description ?? '';
276
+ const name = typeof meta.name === 'string' ? meta.name : (fallback?.name ?? templateName);
277
+ const description = typeof meta.description === 'string' ? meta.description : (fallback?.description ?? '');
244
278
  const directories = Array.isArray(meta.directories)
245
279
  ? coerceStringArray(meta.directories)
246
- : fallback?.directories ?? [];
280
+ : (fallback?.directories ?? []);
247
281
  return { name, description, directories };
248
282
  };
249
283
  const loadTemplateFiles = (templateDir) => {
@@ -451,6 +485,8 @@ const prepareContext = (state, options) => {
451
485
  .replaceAll(/[-:T.Z]/g, '')
452
486
  .slice(0, 14);
453
487
  state.variables = {
488
+ coreVersion: loadCoreVersion(),
489
+ governanceVersion: toCompatibleGovernanceVersion(loadCoreVersion()),
454
490
  projectName: options.name,
455
491
  projectSlug: options.name,
456
492
  author: options.author ?? 'Your Name',
@@ -459,7 +495,6 @@ const prepareContext = (state, options) => {
459
495
  database: options.database ?? 'sqlite',
460
496
  template: state.templateName,
461
497
  migrationTimestamp,
462
- coreVersion: loadCoreVersion(),
463
498
  };
464
499
  };
465
500
  const createDirectoriesForState = (state) => {
@@ -1,7 +1,7 @@
1
1
  export declare const DistPackager: Readonly<{
2
2
  /**
3
- * Creates minimal metadata so `dist/` can be installed via `file:/.../dist`.
4
- * This is intended for local dev/simulate apps, not publishing.
3
+ * Creates minimal metadata so `dist/` can be installed via `file:/.../dist`
4
+ * without clobbering the publishable package manifest.
5
5
  */
6
6
  prepare(distPath: string, rootPath?: string): void;
7
7
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"DistPackager.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/DistPackager.ts"],"names":[],"mappings":"AAsLA,eAAO,MAAM,YAAY;IACvB;;;OAGG;sBACe,MAAM,aAAY,MAAM,GAAmB,IAAI;EAgBjE,CAAC"}
1
+ {"version":3,"file":"DistPackager.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/DistPackager.ts"],"names":[],"mappings":"AAmKA,eAAO,MAAM,YAAY;IACvB;;;OAGG;sBACe,MAAM,aAAY,MAAM,GAAmB,IAAI;EAgBjE,CAAC"}
@@ -30,7 +30,6 @@ const buildDistPackageJson = (rootPkg) => {
30
30
  return {
31
31
  name,
32
32
  version,
33
- private: true,
34
33
  type: 'module',
35
34
  main: './index.js',
36
35
  types: './index.d.ts',
@@ -57,6 +56,10 @@ const buildDistPackageJson = (rootPkg) => {
57
56
  types: './src/proxy.d.ts',
58
57
  default: './src/proxy.js',
59
58
  },
59
+ './proxy/*': {
60
+ types: './src/proxy/*.d.ts',
61
+ default: './src/proxy/*.js',
62
+ },
60
63
  './collections': {
61
64
  types: './src/collections/index.d.ts',
62
65
  default: './src/collections/index.js',
@@ -76,6 +79,9 @@ const buildDistPackageJson = (rootPkg) => {
76
79
  './package.json': './package.json',
77
80
  },
78
81
  dependencies: coerceDependencies(rootPkg.dependencies),
82
+ publishConfig: {
83
+ access: 'public',
84
+ },
79
85
  };
80
86
  };
81
87
  const writeDistEntrypoints = (distPath) => {
@@ -110,8 +116,8 @@ const warnIfMissingDistArtifacts = (distPath) => {
110
116
  };
111
117
  export const DistPackager = Object.freeze({
112
118
  /**
113
- * Creates minimal metadata so `dist/` can be installed via `file:/.../dist`.
114
- * This is intended for local dev/simulate apps, not publishing.
119
+ * Creates minimal metadata so `dist/` can be installed via `file:/.../dist`
120
+ * without clobbering the publishable package manifest.
115
121
  */
116
122
  prepare(distPath, rootPath = process.cwd()) {
117
123
  if (!fs.existsSync(distPath)) {
package/src/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @zintrust/core v0.4.27
2
+ * @zintrust/core v0.4.29
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-28T14:15:33.465Z
8
+ * Built: 2026-03-29T12:19:31.273Z
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-28T14:15:33.427Z'; // Replaced during build
24
+ export const ZINTRUST_BUILD_DATE = '2026-03-29T12:19:31.239Z'; // 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';
package/src/proxy.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { ErrorHandler } from './proxy/ErrorHandler';
2
2
  export { RequestValidator } from './proxy/RequestValidator';
3
3
  export { SigningService } from './proxy/SigningService';
4
+ export { ZintrustD1Proxy } from './proxy/d1/ZintrustD1Proxy';
5
+ export { ZintrustKvProxy } from './proxy/kv/ZintrustKvProxy';
4
6
  //# sourceMappingURL=proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC"}
package/src/proxy.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export { ErrorHandler } from './proxy/ErrorHandler.js';
2
2
  export { RequestValidator } from './proxy/RequestValidator.js';
3
3
  export { SigningService } from './proxy/SigningService.js';
4
+ export { ZintrustD1Proxy } from './proxy/d1/ZintrustD1Proxy.js';
5
+ export { ZintrustKvProxy } from './proxy/kv/ZintrustKvProxy.js';
@@ -13,7 +13,7 @@
13
13
  "dependencies": {
14
14
  "@zintrust/core": "^{{coreVersion}}",
15
15
  "@zintrust/d1-migrator": "^0.4.6",
16
- "@zintrust/governance": "^0.1.25"
16
+ "@zintrust/governance": "{{governanceVersion}}"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "^25.0.3",