@edgible-team/cli 1.2.13 → 1.2.15
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/dist/commands/stack/deploy.d.ts +6 -0
- package/dist/commands/stack/deploy.d.ts.map +1 -0
- package/dist/commands/stack/deploy.js +58 -0
- package/dist/commands/stack/diff.d.ts +7 -0
- package/dist/commands/stack/diff.d.ts.map +1 -0
- package/dist/commands/stack/diff.js +64 -0
- package/dist/commands/stack/status.d.ts +9 -0
- package/dist/commands/stack/status.d.ts.map +1 -0
- package/dist/commands/stack/status.js +53 -0
- package/dist/commands/stack/teardown.d.ts +6 -0
- package/dist/commands/stack/teardown.d.ts.map +1 -0
- package/dist/commands/stack/teardown.js +104 -0
- package/dist/commands/stack/validate.d.ts +7 -0
- package/dist/commands/stack/validate.d.ts.map +1 -0
- package/dist/commands/stack/validate.js +42 -0
- package/dist/commands/stack.d.ts +10 -0
- package/dist/commands/stack.d.ts.map +1 -0
- package/dist/commands/stack.js +112 -0
- package/dist/index.js +2 -0
- package/dist/services/instances.d.ts +23 -0
- package/dist/services/instances.d.ts.map +1 -1
- package/dist/services/instances.js +46 -1
- package/dist/services/stack/DependencyGraphManager.d.ts +69 -0
- package/dist/services/stack/DependencyGraphManager.d.ts.map +1 -0
- package/dist/services/stack/DependencyGraphManager.js +204 -0
- package/dist/services/stack/DeviceResolver.d.ts +63 -0
- package/dist/services/stack/DeviceResolver.d.ts.map +1 -0
- package/dist/services/stack/DeviceResolver.js +147 -0
- package/dist/services/stack/GatewayResolver.d.ts +84 -0
- package/dist/services/stack/GatewayResolver.d.ts.map +1 -0
- package/dist/services/stack/GatewayResolver.js +179 -0
- package/dist/services/stack/StackParser.d.ts +38 -0
- package/dist/services/stack/StackParser.d.ts.map +1 -0
- package/dist/services/stack/StackParser.js +234 -0
- package/dist/services/stack/StackService.d.ts +76 -0
- package/dist/services/stack/StackService.d.ts.map +1 -0
- package/dist/services/stack/StackService.js +476 -0
- package/dist/types/stack.d.ts +191 -0
- package/dist/types/stack.d.ts.map +1 -0
- package/dist/types/stack.js +5 -0
- package/dist/types/validation/schemas.d.ts +17 -17
- package/dist/utils/stack-errors.d.ts +103 -0
- package/dist/utils/stack-errors.d.ts.map +1 -0
- package/dist/utils/stack-errors.js +158 -0
- package/dist/validation/stack-schemas.d.ts +535 -0
- package/dist/validation/stack-schemas.d.ts.map +1 -0
- package/dist/validation/stack-schemas.js +178 -0
- package/package.json +4 -2
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Stack validation schemas using Zod
|
|
4
|
+
* Provides runtime validation for application stacks
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.applicationStackSchema = exports.stackMetadataSchema = exports.stackApplicationSchema = exports.uuidSchema = exports.hostnameSchema = exports.stackDeviceNameSchema = exports.stackPortSchema = exports.applicationNameSchema = exports.stackProtocolSchema = exports.authModeSchema = exports.applicationSubtypeSchema = void 0;
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
/**
|
|
10
|
+
* Application subtypes
|
|
11
|
+
*/
|
|
12
|
+
exports.applicationSubtypeSchema = zod_1.z.enum([
|
|
13
|
+
'existing',
|
|
14
|
+
'docker-compose',
|
|
15
|
+
'managed-process',
|
|
16
|
+
'docker',
|
|
17
|
+
'podman',
|
|
18
|
+
'qemu',
|
|
19
|
+
], {
|
|
20
|
+
errorMap: () => ({ message: 'Invalid application subtype' }),
|
|
21
|
+
});
|
|
22
|
+
/**
|
|
23
|
+
* Auth modes
|
|
24
|
+
*/
|
|
25
|
+
exports.authModeSchema = zod_1.z.enum(['none', 'org', 'api-key'], {
|
|
26
|
+
errorMap: () => ({ message: 'Invalid authentication mode' }),
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Protocol
|
|
30
|
+
*/
|
|
31
|
+
exports.stackProtocolSchema = zod_1.z.enum(['http', 'https', 'tcp', 'udp'], {
|
|
32
|
+
errorMap: () => ({ message: 'Protocol must be one of: http, https, tcp, udp' }),
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Application name (alphanumeric, hyphens, underscores)
|
|
36
|
+
*/
|
|
37
|
+
exports.applicationNameSchema = zod_1.z
|
|
38
|
+
.string()
|
|
39
|
+
.min(1, 'Application name is required')
|
|
40
|
+
.max(100, 'Application name must be at most 100 characters')
|
|
41
|
+
.regex(/^[a-zA-Z0-9-_]+$/, 'Application name can only contain letters, numbers, hyphens, and underscores');
|
|
42
|
+
/**
|
|
43
|
+
* Port number
|
|
44
|
+
*/
|
|
45
|
+
exports.stackPortSchema = zod_1.z
|
|
46
|
+
.number()
|
|
47
|
+
.int('Port must be an integer')
|
|
48
|
+
.min(1, 'Port must be between 1 and 65535')
|
|
49
|
+
.max(65535, 'Port must be between 1 and 65535');
|
|
50
|
+
/**
|
|
51
|
+
* Device name
|
|
52
|
+
*/
|
|
53
|
+
exports.stackDeviceNameSchema = zod_1.z
|
|
54
|
+
.string()
|
|
55
|
+
.min(1, 'Device name is required')
|
|
56
|
+
.max(100, 'Device name must be at most 100 characters');
|
|
57
|
+
/**
|
|
58
|
+
* Hostname validation
|
|
59
|
+
*/
|
|
60
|
+
exports.hostnameSchema = zod_1.z
|
|
61
|
+
.string()
|
|
62
|
+
.min(1, 'Hostname cannot be empty')
|
|
63
|
+
.max(253, 'Hostname must be at most 253 characters')
|
|
64
|
+
.regex(/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/, 'Invalid hostname format');
|
|
65
|
+
/**
|
|
66
|
+
* UUID validation
|
|
67
|
+
*/
|
|
68
|
+
exports.uuidSchema = zod_1.z
|
|
69
|
+
.string()
|
|
70
|
+
.uuid('Invalid UUID format');
|
|
71
|
+
/**
|
|
72
|
+
* Stack application schema
|
|
73
|
+
*/
|
|
74
|
+
exports.stackApplicationSchema = zod_1.z
|
|
75
|
+
.object({
|
|
76
|
+
name: exports.applicationNameSchema,
|
|
77
|
+
description: zod_1.z.string().optional(),
|
|
78
|
+
port: exports.stackPortSchema,
|
|
79
|
+
protocol: exports.stackProtocolSchema,
|
|
80
|
+
subtype: exports.applicationSubtypeSchema,
|
|
81
|
+
deviceName: exports.stackDeviceNameSchema,
|
|
82
|
+
published: zod_1.z.boolean().optional().default(false),
|
|
83
|
+
hostnames: zod_1.z.array(exports.hostnameSchema).optional(),
|
|
84
|
+
dependsOn: zod_1.z.array(exports.applicationNameSchema).optional(),
|
|
85
|
+
authModes: zod_1.z.array(exports.authModeSchema).optional(),
|
|
86
|
+
allowedOrganizations: zod_1.z.array(exports.uuidSchema).optional(),
|
|
87
|
+
// Subtype-specific fields
|
|
88
|
+
composeFile: zod_1.z.string().optional(),
|
|
89
|
+
command: zod_1.z.string().optional(),
|
|
90
|
+
workingDir: zod_1.z.string().optional(),
|
|
91
|
+
environment: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
92
|
+
logFile: zod_1.z.string().optional(),
|
|
93
|
+
})
|
|
94
|
+
.refine((data) => {
|
|
95
|
+
// docker-compose requires composeFile
|
|
96
|
+
if (data.subtype === 'docker-compose' && !data.composeFile) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}, {
|
|
101
|
+
message: 'composeFile is required for docker-compose subtype',
|
|
102
|
+
path: ['composeFile'],
|
|
103
|
+
})
|
|
104
|
+
.refine((data) => {
|
|
105
|
+
// managed-process requires command
|
|
106
|
+
if (data.subtype === 'managed-process' && !data.command) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}, {
|
|
111
|
+
message: 'command is required for managed-process subtype',
|
|
112
|
+
path: ['command'],
|
|
113
|
+
})
|
|
114
|
+
.refine((data) => {
|
|
115
|
+
// Stub subtypes (docker, podman, qemu) are not yet implemented
|
|
116
|
+
if (['docker', 'podman', 'qemu'].includes(data.subtype)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}, {
|
|
121
|
+
message: 'This subtype is not yet implemented. Use: existing, docker-compose, or managed-process',
|
|
122
|
+
path: ['subtype'],
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
125
|
+
* Stack metadata schema
|
|
126
|
+
*/
|
|
127
|
+
exports.stackMetadataSchema = zod_1.z.object({
|
|
128
|
+
name: zod_1.z
|
|
129
|
+
.string()
|
|
130
|
+
.min(1, 'Stack name is required')
|
|
131
|
+
.max(100, 'Stack name must be at most 100 characters')
|
|
132
|
+
.regex(/^[a-zA-Z0-9-_]+$/, 'Stack name can only contain letters, numbers, hyphens, and underscores'),
|
|
133
|
+
description: zod_1.z.string().optional(),
|
|
134
|
+
});
|
|
135
|
+
/**
|
|
136
|
+
* Main application stack schema
|
|
137
|
+
*/
|
|
138
|
+
exports.applicationStackSchema = zod_1.z
|
|
139
|
+
.object({
|
|
140
|
+
apiVersion: zod_1.z.literal('v1', {
|
|
141
|
+
errorMap: () => ({ message: 'Only apiVersion "v1" is currently supported' }),
|
|
142
|
+
}),
|
|
143
|
+
kind: zod_1.z.literal('ApplicationStack', {
|
|
144
|
+
errorMap: () => ({ message: 'kind must be "ApplicationStack"' }),
|
|
145
|
+
}),
|
|
146
|
+
metadata: exports.stackMetadataSchema,
|
|
147
|
+
applications: zod_1.z
|
|
148
|
+
.array(exports.stackApplicationSchema)
|
|
149
|
+
.min(1, 'At least one application is required')
|
|
150
|
+
.max(100, 'Maximum 100 applications per stack'),
|
|
151
|
+
})
|
|
152
|
+
.refine((data) => {
|
|
153
|
+
// Check for duplicate application names
|
|
154
|
+
const names = data.applications.map((app) => app.name);
|
|
155
|
+
const uniqueNames = new Set(names);
|
|
156
|
+
return names.length === uniqueNames.size;
|
|
157
|
+
}, {
|
|
158
|
+
message: 'Duplicate application names found. Each application must have a unique name',
|
|
159
|
+
path: ['applications'],
|
|
160
|
+
})
|
|
161
|
+
.refine((data) => {
|
|
162
|
+
// Validate that all dependencies exist
|
|
163
|
+
const appNames = new Set(data.applications.map((app) => app.name));
|
|
164
|
+
for (const app of data.applications) {
|
|
165
|
+
if (app.dependsOn) {
|
|
166
|
+
for (const dep of app.dependsOn) {
|
|
167
|
+
if (!appNames.has(dep)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}, {
|
|
175
|
+
message: 'One or more applications depend on non-existent applications',
|
|
176
|
+
path: ['applications'],
|
|
177
|
+
});
|
|
178
|
+
//# sourceMappingURL=stack-schemas.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgible-team/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.15",
|
|
4
4
|
"description": "CLI tool for Edgible service",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -62,13 +62,15 @@
|
|
|
62
62
|
"chalk": "^4.1.2",
|
|
63
63
|
"commander": "^11.1.0",
|
|
64
64
|
"find-process": "^2.0.0",
|
|
65
|
+
"graphlib": "^2.1.8",
|
|
65
66
|
"inquirer": "^9.2.12",
|
|
66
|
-
"js-yaml": "^4.1.
|
|
67
|
+
"js-yaml": "^4.1.1",
|
|
67
68
|
"node-fetch": "^3.3.2",
|
|
68
69
|
"ssh2": "^1.15.0",
|
|
69
70
|
"zod": "^3.25.76"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
73
|
+
"@types/graphlib": "^2.1.12",
|
|
72
74
|
"@types/inquirer": "^9.0.7",
|
|
73
75
|
"@types/jest": "^29.5.0",
|
|
74
76
|
"@types/js-yaml": "^4.0.9",
|