@zintrust/core 0.1.43 → 0.1.44
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/README.md +1 -0
- package/package.json +2 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +6 -0
- package/src/cli/commands/DeployCommand.d.ts.map +1 -1
- package/src/cli/commands/DeployCommand.js +12 -1
- package/src/cli/commands/DeployContainersProxyCommand.d.ts +5 -0
- package/src/cli/commands/DeployContainersProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/DeployContainersProxyCommand.js +45 -0
- package/src/cli/commands/DockerCommand.d.ts +5 -0
- package/src/cli/commands/DockerCommand.d.ts.map +1 -0
- package/src/cli/commands/DockerCommand.js +74 -0
- package/src/cli/commands/InitContainersProxyCommand.d.ts +5 -0
- package/src/cli/commands/InitContainersProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/InitContainersProxyCommand.js +159 -0
- package/src/cli/commands/PutCommand.d.ts.map +1 -1
- package/src/cli/commands/PutCommand.js +15 -5
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +20 -3
- package/src/index.js +3 -3
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ Your API is now running at `http://localhost:7777`
|
|
|
24
24
|
If you’re targeting a different runtime:
|
|
25
25
|
|
|
26
26
|
- Cloudflare Workers (Wrangler): `zin start --wg`
|
|
27
|
+
- Cloudflare Containers proxy (Wrangler + Docker): `zin init:containers-proxy` then `zin docker -e staging`
|
|
27
28
|
- AWS Lambda adapter mode: `zin start --lambda`
|
|
28
29
|
- Deno adapter mode: `zin start --deno`
|
|
29
30
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.44",
|
|
4
4
|
"description": "Production-grade TypeScript backend framework for JavaScript",
|
|
5
5
|
"homepage": "https://zintrust.com",
|
|
6
6
|
"repository": {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"node-forge": "1.3.3",
|
|
66
66
|
"cross-spawn": "^7.0.5",
|
|
67
67
|
"glob": "^11.1.0",
|
|
68
|
+
"minimatch": "^10.2.1",
|
|
68
69
|
"undici": "^6.23.0"
|
|
69
70
|
},
|
|
70
71
|
"bin": {
|
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;AAoEH,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;AA0PD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
|
package/src/cli/CLI.js
CHANGED
|
@@ -14,10 +14,13 @@ import { DbSeedCommand } from './commands/DbSeedCommand.js';
|
|
|
14
14
|
import { DebugCommand } from './commands/DebugCommand.js';
|
|
15
15
|
import { DeployCommand } from './commands/DeployCommand.js';
|
|
16
16
|
import { DeployContainerProxiesCommand } from './commands/DeployContainerProxiesCommand.js';
|
|
17
|
+
import { DeployContainersProxyCommand } from './commands/DeployContainersProxyCommand.js';
|
|
17
18
|
import { DeployContainerWorkersCommand } from './commands/DeployContainerWorkersCommand.js';
|
|
19
|
+
import { DockerCommand } from './commands/DockerCommand.js';
|
|
18
20
|
import { DoctorArchitectureCommand } from './commands/DoctorArchitectureCommand.js';
|
|
19
21
|
import { FixCommand } from './commands/FixCommand.js';
|
|
20
22
|
import { InitContainerCommand } from './commands/InitContainerCommand.js';
|
|
23
|
+
import { InitContainersProxyCommand } from './commands/InitContainersProxyCommand.js';
|
|
21
24
|
import { InitEcosystemCommand } from './commands/InitEcosystemCommand.js';
|
|
22
25
|
import { InitProducerCommand } from './commands/InitProducerCommand.js';
|
|
23
26
|
import { InitProxyCommand } from './commands/InitProxyCommand.js';
|
|
@@ -75,6 +78,7 @@ const buildCommandRegistry = () => {
|
|
|
75
78
|
UpgradeCommand.create(),
|
|
76
79
|
PrepareCommand,
|
|
77
80
|
InitContainerCommand.create(),
|
|
81
|
+
InitContainersProxyCommand.create(),
|
|
78
82
|
InitProxyCommand.create(),
|
|
79
83
|
InitProducerCommand.create(),
|
|
80
84
|
InitEcosystemCommand.create(),
|
|
@@ -84,6 +88,7 @@ const buildCommandRegistry = () => {
|
|
|
84
88
|
CreateMigrationCommand.create(),
|
|
85
89
|
AddMigrationCommand.create(),
|
|
86
90
|
StartCommand.create(),
|
|
91
|
+
DockerCommand.create(),
|
|
87
92
|
QueueCommand.create(),
|
|
88
93
|
QueueRecoveryCommand.create(),
|
|
89
94
|
ScheduleListCommand.create(),
|
|
@@ -106,6 +111,7 @@ const buildCommandRegistry = () => {
|
|
|
106
111
|
PublishCommand.create(),
|
|
107
112
|
PutCommand.create(),
|
|
108
113
|
DeployCommand.create(),
|
|
114
|
+
DeployContainersProxyCommand.create(),
|
|
109
115
|
DeployContainerWorkersCommand.create(),
|
|
110
116
|
DeployContainerProxiesCommand.create(),
|
|
111
117
|
QACommand(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeployCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DeployCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"DeployCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DeployCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAyIrE;;;GAGG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;cACO,YAAY;EAGtB,CAAC"}
|
|
@@ -59,10 +59,20 @@ const runDeploy = async (target, options) => {
|
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
const environment = options.env ?? target ?? 'worker';
|
|
62
|
+
const config = typeof options.config === 'string' ? options.config.trim() : '';
|
|
63
|
+
if (config.length > 0) {
|
|
64
|
+
const full = join(process.cwd(), config);
|
|
65
|
+
if (existsSync(full)) {
|
|
66
|
+
// ok
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
throw ErrorFactory.createCliError(`Wrangler config not found: ${config}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
62
72
|
Logger.info(`Deploying to Cloudflare environment: ${environment}`);
|
|
63
73
|
const exitCode = await SpawnUtil.spawnAndWait({
|
|
64
74
|
command: 'wrangler',
|
|
65
|
-
args: ['deploy', '--env', environment],
|
|
75
|
+
args: ['deploy', ...(config.length > 0 ? ['--config', config] : []), '--env', environment],
|
|
66
76
|
});
|
|
67
77
|
if (exitCode !== 0) {
|
|
68
78
|
process.exit(exitCode);
|
|
@@ -76,6 +86,7 @@ const createDeployCommand = () => {
|
|
|
76
86
|
command
|
|
77
87
|
.argument('[target]', 'Deployment target (worker, d1-proxy, kv-proxy, production, cw, cp)', 'worker')
|
|
78
88
|
.option('-e, --env <env>', 'Wrangler environment (overrides target)');
|
|
89
|
+
command.option('-c, --config <path>', 'Wrangler config file (e.g. wrangler.containers-proxy.jsonc)');
|
|
79
90
|
},
|
|
80
91
|
execute: async (options) => {
|
|
81
92
|
// Note: BaseCommand.create sets up action handler that calls execute(options).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeployContainersProxyCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DeployContainersProxyCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA2CrE,eAAO,MAAM,4BAA4B;cAC7B,YAAY;EAatB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
+
import { SpawnUtil } from '../utils/spawn.js';
|
|
3
|
+
import { Logger } from '../../config/logger.js';
|
|
4
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
|
+
import { existsSync } from '../../node-singletons/fs.js';
|
|
6
|
+
import { join } from '../../node-singletons/path.js';
|
|
7
|
+
const DEFAULT_CONFIG = 'wrangler.containers-proxy.jsonc';
|
|
8
|
+
const resolveConfig = (cwd, raw) => {
|
|
9
|
+
const normalized = typeof raw === 'string' ? raw.trim() : '';
|
|
10
|
+
const candidate = normalized.length > 0 ? normalized : DEFAULT_CONFIG;
|
|
11
|
+
const full = join(cwd, candidate);
|
|
12
|
+
if (existsSync(full))
|
|
13
|
+
return candidate;
|
|
14
|
+
throw ErrorFactory.createCliError(`Wrangler config not found: ${candidate}`);
|
|
15
|
+
};
|
|
16
|
+
const resolveEnv = (raw) => {
|
|
17
|
+
const normalized = typeof raw === 'string' ? raw.trim() : '';
|
|
18
|
+
return normalized.length > 0 ? normalized : 'production';
|
|
19
|
+
};
|
|
20
|
+
const execute = async (options) => {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
const config = resolveConfig(cwd, options.config);
|
|
23
|
+
const env = resolveEnv(options.env);
|
|
24
|
+
Logger.info(`Deploying Containers proxy via Wrangler (env=${env})...`);
|
|
25
|
+
const exitCode = await SpawnUtil.spawnAndWait({
|
|
26
|
+
command: 'wrangler',
|
|
27
|
+
args: ['deploy', '--config', config, '--env', env],
|
|
28
|
+
env: process.env,
|
|
29
|
+
});
|
|
30
|
+
process.exit(exitCode);
|
|
31
|
+
};
|
|
32
|
+
export const DeployContainersProxyCommand = Object.freeze({
|
|
33
|
+
create() {
|
|
34
|
+
return BaseCommand.create({
|
|
35
|
+
name: 'deploy:ccp',
|
|
36
|
+
aliases: ['deploy:containers-proxy', 'deploy:cf-containers-proxy', 'd:ccp', 'ccp:deploy'],
|
|
37
|
+
description: 'Deploy Cloudflare Containers proxy Worker (wrangler.containers-proxy.jsonc)',
|
|
38
|
+
addOptions: (command) => {
|
|
39
|
+
command.option('-e, --env <name>', 'Wrangler environment name', 'production');
|
|
40
|
+
command.option('-c, --config <path>', 'Wrangler config file', DEFAULT_CONFIG);
|
|
41
|
+
},
|
|
42
|
+
execute: async (options) => execute(options),
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DockerCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DockerCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA0ErE,eAAO,MAAM,aAAa;cACd,YAAY;EAiBtB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
+
import { SpawnUtil } from '../utils/spawn.js';
|
|
3
|
+
import { Logger } from '../../config/logger.js';
|
|
4
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
|
+
import { existsSync } from '../../node-singletons/fs.js';
|
|
6
|
+
import { join } from '../../node-singletons/path.js';
|
|
7
|
+
const resolveDefaultWranglerConfig = (cwd) => {
|
|
8
|
+
const candidates = [
|
|
9
|
+
'wrangler.containers-proxy.jsonc',
|
|
10
|
+
'wrangler.containers-proxy.json',
|
|
11
|
+
'wrangler.containers-proxy.toml',
|
|
12
|
+
'wrangler.jsonc',
|
|
13
|
+
'wrangler.json',
|
|
14
|
+
'wrangler.toml',
|
|
15
|
+
];
|
|
16
|
+
for (const candidate of candidates) {
|
|
17
|
+
const full = join(cwd, candidate);
|
|
18
|
+
if (existsSync(full))
|
|
19
|
+
return candidate;
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
};
|
|
23
|
+
const resolvePort = (raw) => {
|
|
24
|
+
const value = typeof raw === 'string' ? raw.trim() : '';
|
|
25
|
+
if (value === '')
|
|
26
|
+
return undefined;
|
|
27
|
+
const parsed = Number.parseInt(value, 10);
|
|
28
|
+
if (!Number.isFinite(parsed) || parsed <= 0 || parsed >= 65536) {
|
|
29
|
+
throw ErrorFactory.createCliError(`Error: Invalid --port '${value}'. Expected 1-65535.`);
|
|
30
|
+
}
|
|
31
|
+
return String(parsed);
|
|
32
|
+
};
|
|
33
|
+
const resolveWranglerConfig = (cwd, options) => {
|
|
34
|
+
const fromCli = typeof options.wranglerConfig === 'string' ? options.wranglerConfig.trim() : '';
|
|
35
|
+
if (fromCli.length > 0) {
|
|
36
|
+
const full = join(cwd, fromCli);
|
|
37
|
+
if (existsSync(full))
|
|
38
|
+
return fromCli;
|
|
39
|
+
throw ErrorFactory.createCliError(`Wrangler config not found: ${fromCli}`);
|
|
40
|
+
}
|
|
41
|
+
const fallback = resolveDefaultWranglerConfig(cwd);
|
|
42
|
+
if (typeof fallback === 'string' && fallback.length > 0)
|
|
43
|
+
return fallback;
|
|
44
|
+
throw ErrorFactory.createCliError('Wrangler config not found. Expected wrangler.containers-proxy.jsonc (or wrangler.jsonc/toml).');
|
|
45
|
+
};
|
|
46
|
+
const executeDocker = async (options) => {
|
|
47
|
+
const cwd = process.cwd();
|
|
48
|
+
const config = resolveWranglerConfig(cwd, options);
|
|
49
|
+
const env = typeof options.env === 'string' ? options.env.trim() : '';
|
|
50
|
+
const port = resolvePort(options.port);
|
|
51
|
+
const args = ['dev', '--config', config];
|
|
52
|
+
if (typeof port === 'string' && port.length > 0)
|
|
53
|
+
args.push('--port', port);
|
|
54
|
+
if (env.length > 0)
|
|
55
|
+
args.push('--env', env);
|
|
56
|
+
Logger.info('Starting Wrangler dev (Containers/Docker-backed)...');
|
|
57
|
+
const exitCode = await SpawnUtil.spawnAndWait({ command: 'wrangler', args, env: process.env });
|
|
58
|
+
process.exit(exitCode);
|
|
59
|
+
};
|
|
60
|
+
export const DockerCommand = Object.freeze({
|
|
61
|
+
create() {
|
|
62
|
+
return BaseCommand.create({
|
|
63
|
+
name: 'docker',
|
|
64
|
+
aliases: ['dkr', 'dk'],
|
|
65
|
+
description: 'Run Wrangler dev using a Docker-backed Cloudflare Containers config',
|
|
66
|
+
addOptions: (command) => {
|
|
67
|
+
command.option('-c, --wrangler-config <path>', 'Wrangler config file (defaults if present)');
|
|
68
|
+
command.option('-e, --env <name>', 'Wrangler environment name');
|
|
69
|
+
command.option('-p, --port <number>', 'Port for wrangler dev');
|
|
70
|
+
},
|
|
71
|
+
execute: async (options) => executeDocker(options),
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InitContainersProxyCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/InitContainersProxyCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA6JlE,eAAO,MAAM,0BAA0B;cAC3B,YAAY;EAuBtB,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
+
import { PromptHelper } from '../PromptHelper.js';
|
|
3
|
+
import { Logger } from '../../config/logger.js';
|
|
4
|
+
import { copyFileSync, existsSync, mkdirSync, writeFileSync } from '../../node-singletons/fs.js';
|
|
5
|
+
import { join } from '../../node-singletons/path.js';
|
|
6
|
+
const WRANGLER_CONTAINERS_PROXY_TEMPLATE = `/**
|
|
7
|
+
* ============================================================================
|
|
8
|
+
* ZinTrust Cloudflare Containers Proxy
|
|
9
|
+
* ============================================================================
|
|
10
|
+
* This Worker acts as the "gateway" for the DB/KV/SMTP proxy stack.
|
|
11
|
+
*
|
|
12
|
+
* Requests are routed by path prefix:
|
|
13
|
+
* /mysql/* -> ZintrustMySqlProxyContainer (port 8789)
|
|
14
|
+
* /postgres/* -> ZintrustPostgresProxyContainer (port 8790)
|
|
15
|
+
* /redis/* -> ZintrustRedisProxyContainer (port 8791)
|
|
16
|
+
* /mongodb/* -> ZintrustMongoDbProxyContainer (port 8792)
|
|
17
|
+
* /sqlserver/* -> ZintrustSqlServerProxyContainer (port 8793)
|
|
18
|
+
* /smtp/* -> ZintrustSmtpProxyContainer (port 8794)
|
|
19
|
+
*
|
|
20
|
+
* Notes:
|
|
21
|
+
* - You must install the runtime package: "@zintrust/cloudflare-containers-proxy".
|
|
22
|
+
* - Secrets should be uploaded with the same config file.
|
|
23
|
+
* ============================================================================
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
{
|
|
27
|
+
"name": "zintrust-containers-proxy",
|
|
28
|
+
"main": "./src/containers-proxy.ts",
|
|
29
|
+
|
|
30
|
+
"compatibility_date": "2025-04-21",
|
|
31
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
32
|
+
|
|
33
|
+
"workers_dev": true,
|
|
34
|
+
"minify": false,
|
|
35
|
+
|
|
36
|
+
"containers": [
|
|
37
|
+
{ "class_name": "ZintrustMySqlProxyContainer", "image": "./Dockerfile", "max_instances": 10 },
|
|
38
|
+
{ "class_name": "ZintrustPostgresProxyContainer", "image": "./Dockerfile", "max_instances": 10 },
|
|
39
|
+
{ "class_name": "ZintrustRedisProxyContainer", "image": "./Dockerfile", "max_instances": 10 },
|
|
40
|
+
{ "class_name": "ZintrustMongoDbProxyContainer", "image": "./Dockerfile", "max_instances": 10 },
|
|
41
|
+
{ "class_name": "ZintrustSqlServerProxyContainer", "image": "./Dockerfile", "max_instances": 10 },
|
|
42
|
+
{ "class_name": "ZintrustSmtpProxyContainer", "image": "./Dockerfile", "max_instances": 10 }
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
"durable_objects": {
|
|
46
|
+
"bindings": [
|
|
47
|
+
{ "name": "ZT_PROXY_MYSQL", "class_name": "ZintrustMySqlProxyContainer" },
|
|
48
|
+
{ "name": "ZT_PROXY_POSTGRES", "class_name": "ZintrustPostgresProxyContainer" },
|
|
49
|
+
{ "name": "ZT_PROXY_REDIS", "class_name": "ZintrustRedisProxyContainer" },
|
|
50
|
+
{ "name": "ZT_PROXY_MONGODB", "class_name": "ZintrustMongoDbProxyContainer" },
|
|
51
|
+
{ "name": "ZT_PROXY_SQLSERVER", "class_name": "ZintrustSqlServerProxyContainer" },
|
|
52
|
+
{ "name": "ZT_PROXY_SMTP", "class_name": "ZintrustSmtpProxyContainer" }
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"migrations": [
|
|
57
|
+
{
|
|
58
|
+
"tag": "containers-proxy-v1",
|
|
59
|
+
"new_sqlite_classes": [
|
|
60
|
+
"ZintrustMySqlProxyContainer",
|
|
61
|
+
"ZintrustPostgresProxyContainer",
|
|
62
|
+
"ZintrustRedisProxyContainer",
|
|
63
|
+
"ZintrustMongoDbProxyContainer",
|
|
64
|
+
"ZintrustSqlServerProxyContainer",
|
|
65
|
+
"ZintrustSmtpProxyContainer"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
|
|
70
|
+
"env": {
|
|
71
|
+
"staging": {
|
|
72
|
+
"name": "zintrust-containers-proxy-staging",
|
|
73
|
+
"minify": false,
|
|
74
|
+
"vars": {
|
|
75
|
+
"ENVIRONMENT": "staging",
|
|
76
|
+
"APP_NAME": "ZinTrust",
|
|
77
|
+
"CSRF_SKIP_PATHS": "/api/*,/queue-monitor/*"
|
|
78
|
+
},
|
|
79
|
+
// Add routes here when ready:
|
|
80
|
+
// "routes": [{ "pattern": "proxy-staging.example.com", "custom_domain": true }]
|
|
81
|
+
},
|
|
82
|
+
"production": {
|
|
83
|
+
"name": "zintrust-containers-proxy-production",
|
|
84
|
+
"minify": true,
|
|
85
|
+
"vars": {
|
|
86
|
+
"ENVIRONMENT": "production",
|
|
87
|
+
"APP_NAME": "ZinTrust",
|
|
88
|
+
"CSRF_SKIP_PATHS": "/api/*,/queue-monitor/*"
|
|
89
|
+
},
|
|
90
|
+
// Add routes here when ready:
|
|
91
|
+
// "routes": [{ "pattern": "proxy.example.com", "custom_domain": true }]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
const WORKER_ENTRY_TEMPLATE = `export { default } from '@zintrust/cloudflare-containers-proxy';
|
|
97
|
+
export * from '@zintrust/cloudflare-containers-proxy';
|
|
98
|
+
`;
|
|
99
|
+
const backupSuffix = () => new Date().toISOString().replaceAll(/[:.]/g, '-');
|
|
100
|
+
const backupFileIfExists = (filePath) => {
|
|
101
|
+
if (!existsSync(filePath))
|
|
102
|
+
return;
|
|
103
|
+
const backupPath = `${filePath}.bak.${backupSuffix()}`;
|
|
104
|
+
copyFileSync(filePath, backupPath);
|
|
105
|
+
Logger.info(`🗂️ Backup created: ${backupPath}`);
|
|
106
|
+
};
|
|
107
|
+
async function writeWranglerConfig(cwd) {
|
|
108
|
+
const configPath = join(cwd, 'wrangler.containers-proxy.jsonc');
|
|
109
|
+
let shouldWrite = true;
|
|
110
|
+
if (existsSync(configPath)) {
|
|
111
|
+
shouldWrite = await PromptHelper.confirm('wrangler.containers-proxy.jsonc already exists. Overwrite?', false);
|
|
112
|
+
}
|
|
113
|
+
if (!shouldWrite) {
|
|
114
|
+
Logger.info('Skipped wrangler.containers-proxy.jsonc');
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
backupFileIfExists(configPath);
|
|
118
|
+
writeFileSync(configPath, WRANGLER_CONTAINERS_PROXY_TEMPLATE);
|
|
119
|
+
Logger.info('✅ Created wrangler.containers-proxy.jsonc');
|
|
120
|
+
}
|
|
121
|
+
async function writeWorkerEntry(cwd) {
|
|
122
|
+
const srcDir = join(cwd, 'src');
|
|
123
|
+
const entryPath = join(srcDir, 'containers-proxy.ts');
|
|
124
|
+
if (!existsSync(srcDir)) {
|
|
125
|
+
mkdirSync(srcDir, { recursive: true });
|
|
126
|
+
}
|
|
127
|
+
let shouldWrite = true;
|
|
128
|
+
if (existsSync(entryPath)) {
|
|
129
|
+
shouldWrite = await PromptHelper.confirm('src/containers-proxy.ts already exists. Overwrite?', false);
|
|
130
|
+
}
|
|
131
|
+
if (!shouldWrite) {
|
|
132
|
+
Logger.info('Skipped src/containers-proxy.ts');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
backupFileIfExists(entryPath);
|
|
136
|
+
writeFileSync(entryPath, WORKER_ENTRY_TEMPLATE);
|
|
137
|
+
Logger.info('✅ Created src/containers-proxy.ts');
|
|
138
|
+
}
|
|
139
|
+
export const InitContainersProxyCommand = Object.freeze({
|
|
140
|
+
create() {
|
|
141
|
+
return BaseCommand.create({
|
|
142
|
+
name: 'init:containers-proxy',
|
|
143
|
+
aliases: ['init:ccp', 'init:cf-containers-proxy'],
|
|
144
|
+
description: 'Scaffold Cloudflare Containers proxy Worker (wrangler.containers-proxy.jsonc)',
|
|
145
|
+
async execute() {
|
|
146
|
+
Logger.info('Initializing Cloudflare Containers proxy scaffolding...');
|
|
147
|
+
const cwd = process.cwd();
|
|
148
|
+
await writeWranglerConfig(cwd);
|
|
149
|
+
await writeWorkerEntry(cwd);
|
|
150
|
+
Logger.info('✅ Containers proxy scaffolding complete.');
|
|
151
|
+
Logger.info('Install runtime: npm i @zintrust/cloudflare-containers-proxy');
|
|
152
|
+
Logger.info('Dev (Wrangler + Docker): zin docker --wrangler-config wrangler.containers-proxy.jsonc --env staging');
|
|
153
|
+
Logger.info('Dev (short): zin dk -e staging');
|
|
154
|
+
Logger.info('Deploy (short): zin d:ccp');
|
|
155
|
+
await Promise.resolve();
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PutCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/PutCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"PutCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/PutCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA0OvF,eAAO,MAAM,UAAU;cACX,YAAY;EAWtB,CAAC;AAEH,eAAe,UAAU,CAAC"}
|
|
@@ -74,9 +74,14 @@ const getPutTimeoutMs = () => {
|
|
|
74
74
|
return 120000;
|
|
75
75
|
return parsed;
|
|
76
76
|
};
|
|
77
|
-
const putSecret = (wranglerEnv, key, value) => {
|
|
77
|
+
const putSecret = (wranglerEnv, key, value, configPath) => {
|
|
78
78
|
const npmPath = resolveNpmPath();
|
|
79
|
-
|
|
79
|
+
const args = ['exec', '--yes', '--', 'wrangler'];
|
|
80
|
+
if (typeof configPath === 'string' && configPath.trim().length > 0) {
|
|
81
|
+
args.push('--config', configPath.trim());
|
|
82
|
+
}
|
|
83
|
+
args.push('secret', 'put', key, '--env', wranglerEnv);
|
|
84
|
+
execFileSync(npmPath, args, {
|
|
80
85
|
stdio: ['pipe', 'inherit', 'inherit'],
|
|
81
86
|
input: value,
|
|
82
87
|
encoding: 'utf8',
|
|
@@ -91,6 +96,7 @@ const addOptions = (command) => {
|
|
|
91
96
|
.option('--wg <env...>', 'Wrangler environment target(s), e.g. d1-proxy kv-proxy')
|
|
92
97
|
.option('--var <configKey...>', 'Config array key(s) from .zintrust.json (e.g. d1_env kv_env)')
|
|
93
98
|
.option('--env_path <path>', 'Path to env file used as source values', '.env')
|
|
99
|
+
.option('-c, --config <path>', 'Wrangler config file to target (optional)')
|
|
94
100
|
.option('--dry-run', 'Show what would be uploaded without calling wrangler');
|
|
95
101
|
};
|
|
96
102
|
const ensureCloudflareProvider = (providerRaw) => {
|
|
@@ -122,7 +128,7 @@ const reportResult = (cmd, pushed, failures) => {
|
|
|
122
128
|
cmd.warn(`${item.key} -> ${item.wranglerEnv}: ${item.reason}`);
|
|
123
129
|
}
|
|
124
130
|
};
|
|
125
|
-
const processPut = (cmd, wranglerEnvs, selectedKeys, envMap, dryRun) => {
|
|
131
|
+
const processPut = (cmd, wranglerEnvs, selectedKeys, envMap, dryRun, configPath) => {
|
|
126
132
|
let pushed = 0;
|
|
127
133
|
const failures = [];
|
|
128
134
|
for (const wranglerEnv of wranglerEnvs) {
|
|
@@ -135,7 +141,7 @@ const processPut = (cmd, wranglerEnvs, selectedKeys, envMap, dryRun) => {
|
|
|
135
141
|
try {
|
|
136
142
|
if (!dryRun) {
|
|
137
143
|
cmd.info(`putting ${key} -> ${wranglerEnv}...`);
|
|
138
|
-
putSecret(wranglerEnv, key, value);
|
|
144
|
+
putSecret(wranglerEnv, key, value, configPath);
|
|
139
145
|
}
|
|
140
146
|
pushed += 1;
|
|
141
147
|
cmd.info(`${dryRun ? '[dry-run] ' : ''}put ${key} -> ${wranglerEnv}`);
|
|
@@ -156,7 +162,11 @@ const execute = async (cmd, options) => {
|
|
|
156
162
|
const envMap = await EnvFile.read({ cwd, path: envFilePath });
|
|
157
163
|
const wranglerEnvs = resolveWranglerEnvs(options);
|
|
158
164
|
const dryRun = options.dryRun === true;
|
|
159
|
-
const
|
|
165
|
+
const configPath = typeof options.config === 'string' ? options.config.trim() : '';
|
|
166
|
+
if (configPath !== '' && !existsSync(path.join(cwd, configPath))) {
|
|
167
|
+
throw ErrorFactory.createCliError(`Wrangler config not found: ${configPath}`);
|
|
168
|
+
}
|
|
169
|
+
const result = processPut(cmd, wranglerEnvs, selectedKeys, envMap, dryRun, configPath === '' ? undefined : configPath);
|
|
160
170
|
reportResult(cmd, result.pushed, result.failures);
|
|
161
171
|
};
|
|
162
172
|
export const PutCommand = Object.freeze({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAwnBvF,eAAO,MAAM,YAAY;cACb,YAAY;EA6BtB,CAAC"}
|
|
@@ -241,16 +241,29 @@ const resolveNodeProdCommand = (cwd) => {
|
|
|
241
241
|
}
|
|
242
242
|
return { command: 'node', args: [compiled] };
|
|
243
243
|
};
|
|
244
|
-
const executeWranglerStart = async (cmd, cwd, port, runtime, envName) => {
|
|
244
|
+
const executeWranglerStart = async (cmd, cwd, port, runtime, envName, wranglerConfig) => {
|
|
245
245
|
if (runtime !== undefined) {
|
|
246
246
|
throw ErrorFactory.createCliError('Error: --runtime is not supported with --wrangler (Wrangler controls Workers runtime).');
|
|
247
247
|
}
|
|
248
|
-
const
|
|
248
|
+
const normalizedConfig = typeof wranglerConfig === 'string' ? wranglerConfig.trim() : '';
|
|
249
|
+
const explicitConfigFullPath = normalizedConfig.length > 0 ? path.join(cwd, normalizedConfig) : undefined;
|
|
250
|
+
const configPath = explicitConfigFullPath ?? findWranglerConfig(cwd);
|
|
249
251
|
const entry = resolveWranglerEntry(cwd);
|
|
252
|
+
if (explicitConfigFullPath !== undefined) {
|
|
253
|
+
if (existsSync(explicitConfigFullPath)) {
|
|
254
|
+
// ok
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
throw ErrorFactory.createCliError(`Error: Wrangler config not found: ${normalizedConfig}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
250
260
|
if (configPath === undefined && entry === undefined) {
|
|
251
261
|
throw ErrorFactory.createCliError("Error: wrangler config not found (wrangler.toml/json). Run 'wrangler init' first.");
|
|
252
262
|
}
|
|
253
263
|
const wranglerArgs = ['dev'];
|
|
264
|
+
if (normalizedConfig !== '') {
|
|
265
|
+
wranglerArgs.push('--config', normalizedConfig);
|
|
266
|
+
}
|
|
254
267
|
if (configPath === undefined && entry !== undefined) {
|
|
255
268
|
wranglerArgs.push(entry);
|
|
256
269
|
}
|
|
@@ -429,7 +442,10 @@ const executeStart = async (options, cmd) => {
|
|
|
429
442
|
...(typeof cacheEnabled === 'boolean' ? { cacheEnabled } : {}),
|
|
430
443
|
});
|
|
431
444
|
if (variant === 'wrangler') {
|
|
432
|
-
|
|
445
|
+
const wranglerConfig = typeof options.wranglerConfig === 'string' && options.wranglerConfig.trim() !== ''
|
|
446
|
+
? options.wranglerConfig.trim()
|
|
447
|
+
: undefined;
|
|
448
|
+
await executeWranglerStart(cmd, cwd, port, runtime, envName === '' ? undefined : envName, wranglerConfig);
|
|
433
449
|
return;
|
|
434
450
|
}
|
|
435
451
|
if (envName !== '') {
|
|
@@ -461,6 +477,7 @@ export const StartCommand = Object.freeze({
|
|
|
461
477
|
.option('--no-watch', 'Disable watch mode (Node only)')
|
|
462
478
|
.option('--mode <development|production|testing>', 'Override app mode')
|
|
463
479
|
.option('--env <name>', 'Wrangler environment name (Wrangler mode only)')
|
|
480
|
+
.option('--wrangler-config <path>', 'Wrangler config path (Wrangler mode only)')
|
|
464
481
|
.option('--runtime <nodejs|cloudflare|lambda|deno|auto>', 'Set RUNTIME for spawned Node')
|
|
465
482
|
.option('-p, --port <number>', 'Override server port');
|
|
466
483
|
};
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core v0.1.
|
|
2
|
+
* @zintrust/core v0.1.44
|
|
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-02-
|
|
8
|
+
* Built: 2026-02-19T18:45:53.851Z
|
|
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-02-
|
|
24
|
+
export const ZINTRUST_BUILD_DATE = '2026-02-19T18:45:53.822Z'; // 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';
|