@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.
- package/package.json +5 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +4 -0
- package/src/cli/commands/D1ProxyCommand.d.ts +6 -0
- package/src/cli/commands/D1ProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/D1ProxyCommand.js +229 -0
- package/src/cli/commands/InitContainerCommand.d.ts.map +1 -1
- package/src/cli/commands/InitContainerCommand.js +9 -96
- package/src/cli/commands/KvProxyCommand.d.ts +6 -0
- package/src/cli/commands/KvProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/KvProxyCommand.js +217 -0
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +8 -28
- package/src/cli/commands/ProxyCommand.d.ts.map +1 -1
- package/src/cli/commands/ProxyCommand.js +2 -0
- package/src/cli/commands/index.d.ts +2 -0
- package/src/cli/commands/index.d.ts.map +1 -1
- package/src/cli/commands/index.js +2 -0
- package/src/cli/index.d.ts +2 -0
- package/src/cli/index.d.ts.map +1 -1
- package/src/cli/index.js +2 -0
- package/src/cli/scaffolding/GovernanceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/GovernanceScaffolder.js +47 -3
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +39 -4
- package/src/cli/utils/DistPackager.d.ts +2 -2
- package/src/cli/utils/DistPackager.d.ts.map +1 -1
- package/src/cli/utils/DistPackager.js +9 -3
- package/src/index.js +3 -3
- package/src/proxy.d.ts +2 -0
- package/src/proxy.d.ts.map +1 -1
- package/src/proxy.js +2 -0
- 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.
|
|
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"
|
package/src/cli/CLI.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
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 @@
|
|
|
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;
|
|
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
|
-
#
|
|
10
|
-
#
|
|
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:
|
|
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
|
-
|
|
33
|
-
|
|
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
|
|
148
|
+
ENV HOST=0.0.0.0
|
|
149
|
+
ENV PORT=7772
|
|
237
150
|
|
|
238
151
|
HEALTHCHECK NONE
|
|
239
152
|
|
|
240
|
-
CMD ["node", "dist/
|
|
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
|
|
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 @@
|
|
|
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;
|
|
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', '
|
|
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 = (
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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(
|
|
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;
|
|
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';
|
package/src/cli/index.d.ts
CHANGED
|
@@ -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';
|
package/src/cli/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
57
|
-
|
|
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;
|
|
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
|
-
*
|
|
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":"
|
|
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
|
-
*
|
|
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.
|
|
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-
|
|
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-
|
|
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
|
package/src/proxy.d.ts.map
CHANGED
|
@@ -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';
|