@zintrust/core 0.1.43 → 0.1.46
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 +3 -1
- package/packages/workers/src/http/middleware/FeaturesValidator.d.ts.map +1 -1
- package/packages/workers/src/http/middleware/FeaturesValidator.js +5 -4
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +8 -0
- package/src/cli/commands/ContainerComposeLifecycle.d.ts +20 -0
- package/src/cli/commands/ContainerComposeLifecycle.d.ts.map +1 -0
- package/src/cli/commands/ContainerComposeLifecycle.js +46 -0
- package/src/cli/commands/ContainerProxiesCommand.d.ts.map +1 -1
- package/src/cli/commands/ContainerProxiesCommand.js +7 -44
- package/src/cli/commands/ContainerWorkersCommand.d.ts.map +1 -1
- package/src/cli/commands/ContainerWorkersCommand.js +7 -30
- 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 +156 -0
- package/src/cli/commands/DockerPushCommand.d.ts +5 -0
- package/src/cli/commands/DockerPushCommand.d.ts.map +1 -0
- package/src/cli/commands/DockerPushCommand.js +92 -0
- package/src/cli/commands/InitContainerCommand.d.ts.map +1 -1
- package/src/cli/commands/InitContainerCommand.js +1 -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/config/queue.d.ts.map +1 -1
- package/src/config/queue.js +27 -8
- package/src/index.js +3 -3
- package/src/orm/Database.d.ts.map +1 -1
- package/src/orm/Database.js +36 -2
- package/src/performance/Optimizer.js +1 -1
- package/src/proxy/ProxyServer.d.ts.map +1 -1
- package/src/proxy/ProxyServer.js +9 -0
- package/src/session/SessionManager.js +1 -1
- package/src/templates/docker/docker-compose.schedules.yml.tpl +78 -7
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.46",
|
|
4
4
|
"description": "Production-grade TypeScript backend framework for JavaScript",
|
|
5
5
|
"homepage": "https://zintrust.com",
|
|
6
6
|
"repository": {
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"./package.json": "./package.json"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
+
"@cloudflare/containers": "^0.1.0",
|
|
52
53
|
"@zintrust/workers": "^0.1.31",
|
|
53
54
|
"bcryptjs": "^3.0.3",
|
|
54
55
|
"bullmq": "^5.69.3",
|
|
@@ -65,6 +66,7 @@
|
|
|
65
66
|
"node-forge": "1.3.3",
|
|
66
67
|
"cross-spawn": "^7.0.5",
|
|
67
68
|
"glob": "^11.1.0",
|
|
69
|
+
"minimatch": "^10.2.1",
|
|
68
70
|
"undici": "^6.23.0"
|
|
69
71
|
},
|
|
70
72
|
"bin": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeaturesValidator.d.ts","sourceRoot":"","sources":["../../../../../../packages/workers/src/http/middleware/FeaturesValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"FeaturesValidator.d.ts","sourceRoot":"","sources":["../../../../../../packages/workers/src/http/middleware/FeaturesValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAgBnF,eAAO,MAAM,sBAAsB,GAAI,SAAS,YAAY,KAAG,YAoD9D,CAAC"}
|
|
@@ -20,8 +20,8 @@ export const withFeaturesValidation = (handler) => {
|
|
|
20
20
|
if (!features) {
|
|
21
21
|
return handler(req, res); // Skip validation if features is not provided
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
if (
|
|
23
|
+
const isPlainObject = Object.prototype.toString.call(features) === '[object Object]' && !Array.isArray(features);
|
|
24
|
+
if (!isPlainObject) {
|
|
25
25
|
return res.setStatus(400).json({
|
|
26
26
|
error: 'Invalid features configuration',
|
|
27
27
|
message: 'Features must be an object',
|
|
@@ -29,7 +29,8 @@ export const withFeaturesValidation = (handler) => {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
// Validate each feature key and value
|
|
32
|
-
const
|
|
32
|
+
const featuresObj = features;
|
|
33
|
+
const featureKeys = Object.keys(featuresObj);
|
|
33
34
|
for (const key of featureKeys) {
|
|
34
35
|
if (!VALID_FEATURES.has(key)) {
|
|
35
36
|
return res.setStatus(400).json({
|
|
@@ -38,7 +39,7 @@ export const withFeaturesValidation = (handler) => {
|
|
|
38
39
|
code: 'INVALID_FEATURE',
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
|
-
const value =
|
|
42
|
+
const value = featuresObj[key];
|
|
42
43
|
if (typeof value !== 'boolean') {
|
|
43
44
|
return res.setStatus(400).json({
|
|
44
45
|
error: 'Invalid feature value',
|
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;AAqEH,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;AA2PD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
|
package/src/cli/CLI.js
CHANGED
|
@@ -14,10 +14,14 @@ 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';
|
|
20
|
+
import { DockerPushCommand } from './commands/DockerPushCommand.js';
|
|
18
21
|
import { DoctorArchitectureCommand } from './commands/DoctorArchitectureCommand.js';
|
|
19
22
|
import { FixCommand } from './commands/FixCommand.js';
|
|
20
23
|
import { InitContainerCommand } from './commands/InitContainerCommand.js';
|
|
24
|
+
import { InitContainersProxyCommand } from './commands/InitContainersProxyCommand.js';
|
|
21
25
|
import { InitEcosystemCommand } from './commands/InitEcosystemCommand.js';
|
|
22
26
|
import { InitProducerCommand } from './commands/InitProducerCommand.js';
|
|
23
27
|
import { InitProxyCommand } from './commands/InitProxyCommand.js';
|
|
@@ -75,6 +79,7 @@ const buildCommandRegistry = () => {
|
|
|
75
79
|
UpgradeCommand.create(),
|
|
76
80
|
PrepareCommand,
|
|
77
81
|
InitContainerCommand.create(),
|
|
82
|
+
InitContainersProxyCommand.create(),
|
|
78
83
|
InitProxyCommand.create(),
|
|
79
84
|
InitProducerCommand.create(),
|
|
80
85
|
InitEcosystemCommand.create(),
|
|
@@ -84,6 +89,8 @@ const buildCommandRegistry = () => {
|
|
|
84
89
|
CreateMigrationCommand.create(),
|
|
85
90
|
AddMigrationCommand.create(),
|
|
86
91
|
StartCommand.create(),
|
|
92
|
+
DockerCommand.create(),
|
|
93
|
+
DockerPushCommand.create(),
|
|
87
94
|
QueueCommand.create(),
|
|
88
95
|
QueueRecoveryCommand.create(),
|
|
89
96
|
ScheduleListCommand.create(),
|
|
@@ -106,6 +113,7 @@ const buildCommandRegistry = () => {
|
|
|
106
113
|
PublishCommand.create(),
|
|
107
114
|
PutCommand.create(),
|
|
108
115
|
DeployCommand.create(),
|
|
116
|
+
DeployContainersProxyCommand.create(),
|
|
109
117
|
DeployContainerWorkersCommand.create(),
|
|
110
118
|
DeployContainerProxiesCommand.create(),
|
|
111
119
|
QACommand(),
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type ComposeBuildOptions = {
|
|
2
|
+
noCache?: boolean;
|
|
3
|
+
pull?: boolean;
|
|
4
|
+
};
|
|
5
|
+
type ComposeUpOptions = {
|
|
6
|
+
detach?: boolean;
|
|
7
|
+
removeOrphans?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type ComposeDownOptions = {
|
|
10
|
+
volumes?: boolean;
|
|
11
|
+
removeOrphans?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export declare const ContainerComposeLifecycle: Readonly<{
|
|
14
|
+
normalizeAction<const Allowed extends readonly string[]>(raw: string | undefined, allowed: Allowed, usageMessage: string): Allowed[number];
|
|
15
|
+
runBuild(composePath: string, options: ComposeBuildOptions, logMessage: string): Promise<void>;
|
|
16
|
+
runUp(composePath: string, options: ComposeUpOptions, logMessage: string): Promise<void>;
|
|
17
|
+
runDown(composePath: string, options: ComposeDownOptions, logMessage: string): Promise<void>;
|
|
18
|
+
}>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=ContainerComposeLifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContainerComposeLifecycle.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ContainerComposeLifecycle.ts"],"names":[],"mappings":"AAIA,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,yBAAyB;0BACd,OAAO,SAAS,SAAS,MAAM,EAAE,OAChD,MAAM,GAAG,SAAS,WACd,OAAO,gBACF,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC;0BASH,MAAM,WACV,mBAAmB,cAChB,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;uBAeS,MAAM,WAAW,gBAAgB,cAAc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;yBAgB/E,MAAM,WACV,kBAAkB,cACf,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;EAchB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { runComposeWithFallback } from '../commands/DockerComposeCommandUtils.js';
|
|
2
|
+
import { Logger } from '../../config/logger.js';
|
|
3
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
4
|
+
export const ContainerComposeLifecycle = Object.freeze({
|
|
5
|
+
normalizeAction(raw, allowed, usageMessage) {
|
|
6
|
+
const value = (raw ?? '').trim().toLowerCase();
|
|
7
|
+
for (const item of allowed) {
|
|
8
|
+
if (value === item)
|
|
9
|
+
return item;
|
|
10
|
+
}
|
|
11
|
+
throw ErrorFactory.createCliError(usageMessage);
|
|
12
|
+
},
|
|
13
|
+
async runBuild(composePath, options, logMessage) {
|
|
14
|
+
const args = ['compose', '-f', composePath, 'build'];
|
|
15
|
+
if (options.noCache === true) {
|
|
16
|
+
args.push('--no-cache');
|
|
17
|
+
}
|
|
18
|
+
if (options.pull === true) {
|
|
19
|
+
args.push('--pull');
|
|
20
|
+
}
|
|
21
|
+
Logger.info(logMessage);
|
|
22
|
+
await runComposeWithFallback(args);
|
|
23
|
+
},
|
|
24
|
+
async runUp(composePath, options, logMessage) {
|
|
25
|
+
const args = ['compose', '-f', composePath, 'up'];
|
|
26
|
+
if (options.detach === true) {
|
|
27
|
+
args.push('-d');
|
|
28
|
+
}
|
|
29
|
+
if (options.removeOrphans === true) {
|
|
30
|
+
args.push('--remove-orphans');
|
|
31
|
+
}
|
|
32
|
+
Logger.info(logMessage);
|
|
33
|
+
await runComposeWithFallback(args);
|
|
34
|
+
},
|
|
35
|
+
async runDown(composePath, options, logMessage) {
|
|
36
|
+
const args = ['compose', '-f', composePath, 'down'];
|
|
37
|
+
if (options.volumes === true) {
|
|
38
|
+
args.push('-v');
|
|
39
|
+
}
|
|
40
|
+
if (options.removeOrphans === true) {
|
|
41
|
+
args.push('--remove-orphans');
|
|
42
|
+
}
|
|
43
|
+
Logger.info(logMessage);
|
|
44
|
+
await runComposeWithFallback(args);
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContainerProxiesCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ContainerProxiesCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ContainerProxiesCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ContainerProxiesCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAyBrE,eAAO,MAAM,uBAAuB;cACxB,YAAY;EAgDtB,CAAC"}
|
|
@@ -1,45 +1,8 @@
|
|
|
1
1
|
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
|
-
const runBuild = async (composePath, options) => {
|
|
6
|
-
const args = ['compose', '-f', composePath, 'build'];
|
|
7
|
-
if (options.noCache === true) {
|
|
8
|
-
args.push('--no-cache');
|
|
9
|
-
}
|
|
10
|
-
if (options.pull === true) {
|
|
11
|
-
args.push('--pull');
|
|
12
|
-
}
|
|
13
|
-
Logger.info('Building proxy stack image...');
|
|
14
|
-
await runComposeWithFallback(args);
|
|
15
|
-
};
|
|
16
|
-
const runUp = async (composePath, options) => {
|
|
17
|
-
const args = ['compose', '-f', composePath, 'up'];
|
|
18
|
-
if (options.detach === true) {
|
|
19
|
-
args.push('-d');
|
|
20
|
-
}
|
|
21
|
-
if (options.removeOrphans === true) {
|
|
22
|
-
args.push('--remove-orphans');
|
|
23
|
-
}
|
|
24
|
-
Logger.info('Starting proxy stack...');
|
|
25
|
-
await runComposeWithFallback(args);
|
|
26
|
-
};
|
|
27
|
-
const runDown = async (composePath, options) => {
|
|
28
|
-
const args = ['compose', '-f', composePath, 'down'];
|
|
29
|
-
if (options.removeOrphans === true) {
|
|
30
|
-
args.push('--remove-orphans');
|
|
31
|
-
}
|
|
32
|
-
if (options.volumes === true) {
|
|
33
|
-
args.push('--volumes');
|
|
34
|
-
}
|
|
35
|
-
Logger.info('Stopping proxy stack...');
|
|
36
|
-
await runComposeWithFallback(args);
|
|
37
|
-
};
|
|
2
|
+
import { ContainerComposeLifecycle } from '../commands/ContainerComposeLifecycle.js';
|
|
3
|
+
import { resolveComposePath } from '../commands/DockerComposeCommandUtils.js';
|
|
38
4
|
const normalizeAction = (raw) => {
|
|
39
|
-
|
|
40
|
-
if (value === 'build' || value === 'up' || value === 'down')
|
|
41
|
-
return value;
|
|
42
|
-
throw ErrorFactory.createCliError('Usage: zin cp <build|up|down> [options]');
|
|
5
|
+
return ContainerComposeLifecycle.normalizeAction(raw, ['build', 'up', 'down'], 'Usage: zin cp <build|up|down> [options]');
|
|
43
6
|
};
|
|
44
7
|
export const ContainerProxiesCommand = Object.freeze({
|
|
45
8
|
create() {
|
|
@@ -60,17 +23,17 @@ export const ContainerProxiesCommand = Object.freeze({
|
|
|
60
23
|
const action = normalizeAction(options.args?.[0]);
|
|
61
24
|
const composePath = resolveComposePath('docker-compose.proxy.yml', 'docker-compose.proxy.yml not found.');
|
|
62
25
|
if (action === 'build') {
|
|
63
|
-
await runBuild(composePath, options);
|
|
26
|
+
await ContainerComposeLifecycle.runBuild(composePath, options, 'Building proxy stack image...');
|
|
64
27
|
return;
|
|
65
28
|
}
|
|
66
29
|
if (action === 'down') {
|
|
67
|
-
await runDown(composePath, options);
|
|
30
|
+
await ContainerComposeLifecycle.runDown(composePath, options, 'Stopping proxy stack...');
|
|
68
31
|
return;
|
|
69
32
|
}
|
|
70
33
|
if (options.build === true) {
|
|
71
|
-
await runBuild(composePath, options);
|
|
34
|
+
await ContainerComposeLifecycle.runBuild(composePath, options, 'Building proxy stack image...');
|
|
72
35
|
}
|
|
73
|
-
await runUp(composePath, options);
|
|
36
|
+
await ContainerComposeLifecycle.runUp(composePath, options, 'Starting proxy stack...');
|
|
74
37
|
},
|
|
75
38
|
});
|
|
76
39
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContainerWorkersCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ContainerWorkersCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ContainerWorkersCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/ContainerWorkersCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAuBrE,eAAO,MAAM,uBAAuB;cACxB,YAAY;EA6CtB,CAAC"}
|
|
@@ -1,31 +1,8 @@
|
|
|
1
1
|
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
|
-
const runBuild = async (composePath, options) => {
|
|
6
|
-
const args = ['compose', '-f', composePath, 'build'];
|
|
7
|
-
if (options.noCache === true) {
|
|
8
|
-
args.push('--no-cache');
|
|
9
|
-
}
|
|
10
|
-
if (options.pull === true) {
|
|
11
|
-
args.push('--pull');
|
|
12
|
-
}
|
|
13
|
-
Logger.info('Building container workers image...');
|
|
14
|
-
await runComposeWithFallback(args);
|
|
15
|
-
};
|
|
16
|
-
const runUp = async (composePath, options) => {
|
|
17
|
-
const args = ['compose', '-f', composePath, 'up'];
|
|
18
|
-
if (options.detach === true) {
|
|
19
|
-
args.push('-d');
|
|
20
|
-
}
|
|
21
|
-
Logger.info('Starting container workers...');
|
|
22
|
-
await runComposeWithFallback(args);
|
|
23
|
-
};
|
|
2
|
+
import { ContainerComposeLifecycle } from '../commands/ContainerComposeLifecycle.js';
|
|
3
|
+
import { resolveComposePath } from '../commands/DockerComposeCommandUtils.js';
|
|
24
4
|
const normalizeAction = (raw) => {
|
|
25
|
-
|
|
26
|
-
if (value === 'build' || value === 'up')
|
|
27
|
-
return value;
|
|
28
|
-
throw ErrorFactory.createCliError('Usage: zin cw <build|up> [options]');
|
|
5
|
+
return ContainerComposeLifecycle.normalizeAction(raw, ['build', 'up'], 'Usage: zin cw <build|up> [options]');
|
|
29
6
|
};
|
|
30
7
|
export const ContainerWorkersCommand = Object.freeze({
|
|
31
8
|
create() {
|
|
@@ -34,7 +11,7 @@ export const ContainerWorkersCommand = Object.freeze({
|
|
|
34
11
|
aliases: ['container-workers'],
|
|
35
12
|
description: 'Build or start container-based workers',
|
|
36
13
|
addOptions: (command) => {
|
|
37
|
-
command.argument('<action>', 'Action to run (build
|
|
14
|
+
command.argument('<action>', 'Action to run (build, up)');
|
|
38
15
|
command.option('-d, --detach', 'Run containers in background (up only)');
|
|
39
16
|
command.option('--no-cache', 'Disable Docker build cache (build only)');
|
|
40
17
|
command.option('--pull', 'Always attempt to pull a newer base image (build only)');
|
|
@@ -44,13 +21,13 @@ export const ContainerWorkersCommand = Object.freeze({
|
|
|
44
21
|
const action = normalizeAction(options.args?.[0]);
|
|
45
22
|
const composePath = resolveComposePath('docker-compose.workers.yml', 'docker-compose.workers.yml not found. Run `zin init:cw` first.');
|
|
46
23
|
if (action === 'build') {
|
|
47
|
-
await runBuild(composePath, options);
|
|
24
|
+
await ContainerComposeLifecycle.runBuild(composePath, options, 'Building container workers image...');
|
|
48
25
|
return;
|
|
49
26
|
}
|
|
50
27
|
if (options.build === true) {
|
|
51
|
-
await runBuild(composePath, options);
|
|
28
|
+
await ContainerComposeLifecycle.runBuild(composePath, options, 'Building container workers image...');
|
|
52
29
|
}
|
|
53
|
-
await runUp(composePath, options);
|
|
30
|
+
await ContainerComposeLifecycle.runUp(composePath, options, 'Starting container workers...');
|
|
54
31
|
},
|
|
55
32
|
});
|
|
56
33
|
},
|
|
@@ -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":"AACA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA+JrE,eAAO,MAAM,aAAa;cACd,YAAY;EAuBtB,CAAC"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { generateUuid } from '../../common/utility.js';
|
|
2
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
3
|
+
import { DockerPushCommand } from '../commands/DockerPushCommand.js';
|
|
4
|
+
import { SpawnUtil } from '../utils/spawn.js';
|
|
5
|
+
import { Logger } from '../../config/logger.js';
|
|
6
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
7
|
+
import { existsSync, renameSync } from '../../node-singletons/fs.js';
|
|
8
|
+
import { join } from '../../node-singletons/path.js';
|
|
9
|
+
const resolveDefaultWranglerConfig = (cwd) => {
|
|
10
|
+
const candidates = [
|
|
11
|
+
'wrangler.containers-proxy.jsonc',
|
|
12
|
+
'wrangler.containers-proxy.json',
|
|
13
|
+
'wrangler.containers-proxy.toml',
|
|
14
|
+
'wrangler.jsonc',
|
|
15
|
+
'wrangler.json',
|
|
16
|
+
'wrangler.toml',
|
|
17
|
+
];
|
|
18
|
+
for (const candidate of candidates) {
|
|
19
|
+
const full = join(cwd, candidate);
|
|
20
|
+
if (existsSync(full))
|
|
21
|
+
return candidate;
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
};
|
|
25
|
+
const resolvePort = (raw) => {
|
|
26
|
+
const value = typeof raw === 'string' ? raw.trim() : '';
|
|
27
|
+
if (value === '')
|
|
28
|
+
return undefined;
|
|
29
|
+
const parsed = Number.parseInt(value, 10);
|
|
30
|
+
if (!Number.isFinite(parsed) || parsed <= 0 || parsed >= 65536) {
|
|
31
|
+
throw ErrorFactory.createCliError(`Error: Invalid --port '${value}'. Expected 1-65535.`);
|
|
32
|
+
}
|
|
33
|
+
return String(parsed);
|
|
34
|
+
};
|
|
35
|
+
const resolveWranglerConfig = (cwd, options) => {
|
|
36
|
+
const fromCli = typeof options.wranglerConfig === 'string' ? options.wranglerConfig.trim() : '';
|
|
37
|
+
if (fromCli.length > 0) {
|
|
38
|
+
const full = join(cwd, fromCli);
|
|
39
|
+
if (existsSync(full))
|
|
40
|
+
return fromCli;
|
|
41
|
+
throw ErrorFactory.createCliError(`Wrangler config not found: ${fromCli}`);
|
|
42
|
+
}
|
|
43
|
+
const fallback = resolveDefaultWranglerConfig(cwd);
|
|
44
|
+
if (typeof fallback === 'string' && fallback.length > 0)
|
|
45
|
+
return fallback;
|
|
46
|
+
throw ErrorFactory.createCliError('Wrangler config not found. Expected wrangler.containers-proxy.jsonc (or wrangler.jsonc/toml).');
|
|
47
|
+
};
|
|
48
|
+
const isContainersProxyConfig = (config) => {
|
|
49
|
+
const base = config.split(/[/\\]/).pop() ?? config;
|
|
50
|
+
return (base === 'wrangler.containers-proxy.jsonc' ||
|
|
51
|
+
base === 'wrangler.containers-proxy.json' ||
|
|
52
|
+
base === 'wrangler.containers-proxy.toml' ||
|
|
53
|
+
base.startsWith('wrangler.containers-proxy.'));
|
|
54
|
+
};
|
|
55
|
+
const withDevVarsForConfig = async (cwd, config, envName, fn) => {
|
|
56
|
+
const nonce = generateUuid();
|
|
57
|
+
const moved = [];
|
|
58
|
+
const swappedIn = [];
|
|
59
|
+
const disable = (name) => {
|
|
60
|
+
const from = join(cwd, name);
|
|
61
|
+
if (!existsSync(from))
|
|
62
|
+
return;
|
|
63
|
+
const to = join(cwd, `${name}.disabled-by-zin-${nonce}`);
|
|
64
|
+
renameSync(from, to);
|
|
65
|
+
moved.push({ from, to });
|
|
66
|
+
};
|
|
67
|
+
const swapIn = (source, target) => {
|
|
68
|
+
const from = join(cwd, source);
|
|
69
|
+
if (!existsSync(from))
|
|
70
|
+
return;
|
|
71
|
+
const to = join(cwd, target);
|
|
72
|
+
if (existsSync(to))
|
|
73
|
+
return;
|
|
74
|
+
renameSync(from, to);
|
|
75
|
+
swappedIn.push({ from, to });
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
if (isContainersProxyConfig(config)) {
|
|
79
|
+
// For containers-proxy configs, we want `.dev.vars*` to exist but only for
|
|
80
|
+
// this run. Users keep the files renamed as `.dev.vars*.containers-proxy`.
|
|
81
|
+
swapIn('.dev.vars.containers-proxy', '.dev.vars');
|
|
82
|
+
if (envName !== '') {
|
|
83
|
+
swapIn(`.dev.vars.${envName}.containers-proxy`, `.dev.vars.${envName}`);
|
|
84
|
+
}
|
|
85
|
+
return await fn();
|
|
86
|
+
}
|
|
87
|
+
// For all other configs, disable `.dev.vars*` so Wrangler relies on `.env*`.
|
|
88
|
+
disable('.dev.vars');
|
|
89
|
+
disable('.dev.vars.local');
|
|
90
|
+
disable('.dev.vars.staging');
|
|
91
|
+
disable('.dev.vars.staging.local');
|
|
92
|
+
if (envName !== '') {
|
|
93
|
+
disable(`.dev.vars.${envName}`);
|
|
94
|
+
disable(`.dev.vars.${envName}.local`);
|
|
95
|
+
}
|
|
96
|
+
return await fn();
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
const restoreSwaps = swappedIn.slice().reverse();
|
|
100
|
+
for (const item of restoreSwaps) {
|
|
101
|
+
try {
|
|
102
|
+
if (existsSync(item.to) && !existsSync(item.from))
|
|
103
|
+
renameSync(item.to, item.from);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// noop
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const restoreMoved = moved.slice().reverse();
|
|
110
|
+
for (const item of restoreMoved) {
|
|
111
|
+
try {
|
|
112
|
+
if (existsSync(item.to))
|
|
113
|
+
renameSync(item.to, item.from);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// noop
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const executeDocker = async (options) => {
|
|
122
|
+
const cwd = process.cwd();
|
|
123
|
+
const config = resolveWranglerConfig(cwd, options);
|
|
124
|
+
const env = typeof options.env === 'string' ? options.env.trim() : '';
|
|
125
|
+
const port = resolvePort(options.port);
|
|
126
|
+
const args = ['dev', '--config', config];
|
|
127
|
+
if (typeof port === 'string' && port.length > 0)
|
|
128
|
+
args.push('--port', port);
|
|
129
|
+
if (env.length > 0)
|
|
130
|
+
args.push('--env', env);
|
|
131
|
+
Logger.info('Starting Wrangler dev (Containers/Docker-backed)...');
|
|
132
|
+
const exitCode = await withDevVarsForConfig(cwd, config, env, async () => {
|
|
133
|
+
return SpawnUtil.spawnAndWait({ command: 'wrangler', args, env: process.env });
|
|
134
|
+
});
|
|
135
|
+
process.exit(exitCode);
|
|
136
|
+
};
|
|
137
|
+
export const DockerCommand = Object.freeze({
|
|
138
|
+
create() {
|
|
139
|
+
return BaseCommand.create({
|
|
140
|
+
name: 'docker',
|
|
141
|
+
aliases: ['dkr', 'dk'],
|
|
142
|
+
description: 'Run Wrangler dev using a Docker-backed Cloudflare Containers config',
|
|
143
|
+
addOptions: (command) => {
|
|
144
|
+
// `zin docker push` (subcommand) for Docker Hub publishing.
|
|
145
|
+
// Keep `zin docker` itself as the Wrangler dev command.
|
|
146
|
+
const pushCommand = DockerPushCommand.create().getCommand();
|
|
147
|
+
pushCommand.name('push');
|
|
148
|
+
command.addCommand(pushCommand);
|
|
149
|
+
command.option('-c, --wrangler-config <path>', 'Wrangler config file (defaults if present)');
|
|
150
|
+
command.option('-e, --env <name>', 'Wrangler environment name');
|
|
151
|
+
command.option('-p, --port <number>', 'Port for wrangler dev');
|
|
152
|
+
},
|
|
153
|
+
execute: async (options) => executeDocker(options),
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DockerPushCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/DockerPushCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA6FrE,eAAO,MAAM,iBAAiB;cAClB,YAAY;EA0BtB,CAAC"}
|