@figulus/schema 0.4.0-alpha-dev → 0.5.0-alpha-dev-2
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/.openapi-meta/index.ts +12 -0
- package/dist/core/entities/figspec.d.ts +659 -0
- package/dist/core/entities/figspec.d.ts.map +1 -0
- package/dist/core/entities/figspec.js +73 -0
- package/dist/core/entities/figspec.js.map +1 -0
- package/dist/core/entities/figstack.d.ts +139 -0
- package/dist/core/entities/figstack.d.ts.map +1 -0
- package/dist/core/entities/figstack.js +79 -0
- package/dist/core/entities/figstack.js.map +1 -0
- package/dist/core/entities/index.d.ts +3 -0
- package/dist/core/entities/index.d.ts.map +1 -0
- package/dist/core/entities/index.js +3 -0
- package/dist/core/entities/index.js.map +1 -0
- package/dist/core/execute.d.ts +64 -0
- package/dist/core/execute.d.ts.map +1 -0
- package/dist/core/execute.js +45 -0
- package/dist/core/execute.js.map +1 -0
- package/dist/core/generic.d.ts +35 -0
- package/dist/core/generic.d.ts.map +1 -0
- package/dist/core/generic.js +28 -0
- package/dist/core/generic.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/primitives.d.ts +3 -0
- package/dist/core/primitives.d.ts.map +1 -0
- package/dist/core/primitives.js +11 -0
- package/dist/core/primitives.js.map +1 -0
- package/dist/core/volumes.d.ts +160 -0
- package/dist/core/volumes.d.ts.map +1 -0
- package/dist/core/volumes.js +100 -0
- package/dist/core/volumes.js.map +1 -0
- package/dist/engine/deprecated/index.d.ts +2 -0
- package/dist/engine/deprecated/index.d.ts.map +1 -0
- package/dist/engine/deprecated/index.js +2 -0
- package/dist/engine/deprecated/index.js.map +1 -0
- package/dist/engine/deprecated/run-request.d.ts +73 -0
- package/dist/engine/deprecated/run-request.d.ts.map +1 -0
- package/dist/engine/deprecated/run-request.js +47 -0
- package/dist/engine/deprecated/run-request.js.map +1 -0
- package/dist/engine/dry-run.d.ts +15 -0
- package/dist/engine/dry-run.d.ts.map +1 -0
- package/dist/engine/dry-run.js +12 -0
- package/dist/engine/dry-run.js.map +1 -0
- package/dist/engine/health.d.ts +11 -0
- package/dist/engine/health.d.ts.map +1 -0
- package/dist/engine/health.js +9 -0
- package/dist/engine/health.js.map +1 -0
- package/dist/engine/images.d.ts +49 -0
- package/dist/engine/images.d.ts.map +1 -0
- package/dist/engine/images.js +44 -0
- package/dist/engine/images.js.map +1 -0
- package/dist/engine/index.d.ts +9 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +9 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/paths/containers.d.ts +8 -0
- package/dist/engine/paths/containers.d.ts.map +1 -0
- package/dist/engine/paths/containers.js +297 -0
- package/dist/engine/paths/containers.js.map +1 -0
- package/dist/engine/paths/dry-run.d.ts +3 -0
- package/dist/engine/paths/dry-run.d.ts.map +1 -0
- package/dist/engine/paths/dry-run.js +43 -0
- package/dist/engine/paths/dry-run.js.map +1 -0
- package/dist/engine/paths/health.d.ts +3 -0
- package/dist/engine/paths/health.d.ts.map +1 -0
- package/dist/engine/paths/health.js +36 -0
- package/dist/engine/paths/health.js.map +1 -0
- package/dist/engine/paths/images.d.ts +5 -0
- package/dist/engine/paths/images.d.ts.map +1 -0
- package/dist/engine/paths/images.js +144 -0
- package/dist/engine/paths/images.js.map +1 -0
- package/dist/engine/paths/index.d.ts +8 -0
- package/dist/engine/paths/index.d.ts.map +1 -0
- package/dist/engine/paths/index.js +8 -0
- package/dist/engine/paths/index.js.map +1 -0
- package/dist/engine/paths/sessions.d.ts +10 -0
- package/dist/engine/paths/sessions.d.ts.map +1 -0
- package/dist/engine/paths/sessions.js +484 -0
- package/dist/engine/paths/sessions.js.map +1 -0
- package/dist/engine/paths/stacks.d.ts +6 -0
- package/dist/engine/paths/stacks.d.ts.map +1 -0
- package/dist/engine/paths/stacks.js +175 -0
- package/dist/engine/paths/stacks.js.map +1 -0
- package/dist/engine/paths/volumes.d.ts +6 -0
- package/dist/engine/paths/volumes.d.ts.map +1 -0
- package/dist/engine/paths/volumes.js +164 -0
- package/dist/engine/paths/volumes.js.map +1 -0
- package/dist/engine/response.d.ts +8 -0
- package/dist/engine/response.d.ts.map +1 -0
- package/dist/engine/response.js +9 -0
- package/dist/engine/response.js.map +1 -0
- package/dist/engine/sessions.d.ts +343 -0
- package/dist/engine/sessions.d.ts.map +1 -0
- package/dist/engine/sessions.js +118 -0
- package/dist/engine/sessions.js.map +1 -0
- package/dist/engine/volumes.d.ts +52 -0
- package/dist/engine/volumes.d.ts.map +1 -0
- package/dist/engine/volumes.js +39 -0
- package/dist/engine/volumes.js.map +1 -0
- package/dist/index.d.ts +2 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +3 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/json-schema.d.ts +82 -0
- package/dist/registry/json-schema.d.ts.map +1 -0
- package/dist/registry/json-schema.js +149 -0
- package/dist/registry/json-schema.js.map +1 -0
- package/dist/registry/metadata.d.ts +216 -0
- package/dist/registry/metadata.d.ts.map +1 -0
- package/dist/registry/metadata.js +143 -0
- package/dist/registry/metadata.js.map +1 -0
- package/package.json +12 -4
- package/scripts/fix-openapi-3.1.ts +183 -0
- package/scripts/generate-openapi-data.ts +51 -0
- package/scripts/generate-openapi-meta.ts +540 -0
- package/src/core/entities/figspec.ts +94 -0
- package/src/core/entities/figstack.ts +101 -0
- package/src/core/entities/index.ts +2 -0
- package/src/core/execute.ts +66 -0
- package/src/core/generic.ts +38 -0
- package/src/core/index.ts +5 -0
- package/src/core/primitives.ts +12 -0
- package/src/core/volumes.ts +124 -0
- package/src/engine/deprecated/index.ts +1 -0
- package/src/engine/deprecated/run-request.ts +53 -0
- package/src/engine/dry-run.ts +14 -0
- package/src/engine/health.ts +11 -0
- package/src/engine/images.ts +58 -0
- package/src/engine/index.ts +8 -0
- package/src/engine/paths/containers.ts +304 -0
- package/src/engine/paths/dry-run.ts +44 -0
- package/src/engine/paths/health.ts +37 -0
- package/src/engine/paths/images.ts +148 -0
- package/src/engine/paths/index.ts +7 -0
- package/src/engine/paths/sessions.ts +493 -0
- package/src/engine/paths/stacks.ts +179 -0
- package/src/engine/paths/volumes.ts +168 -0
- package/src/engine/response.ts +11 -0
- package/src/engine/sessions.ts +146 -0
- package/src/engine/volumes.ts +53 -0
- package/src/index.ts +3 -8
- package/src/registry/index.ts +2 -0
- package/src/registry/json-schema.ts +178 -0
- package/src/registry/metadata.ts +181 -0
- package/tests/figspec.test.ts +1 -1
- package/tests/schemas.test.ts +31 -31
- package/dist/figspec.d.ts +0 -4394
- package/dist/figspec.d.ts.map +0 -1
- package/dist/figspec.js +0 -214
- package/dist/figspec.js.map +0 -1
- package/dist/figstack.d.ts +0 -419
- package/dist/figstack.d.ts.map +0 -1
- package/dist/figstack.js +0 -72
- package/dist/figstack.js.map +0 -1
- package/dist/health.d.ts +0 -16
- package/dist/health.d.ts.map +0 -1
- package/dist/health.js +0 -7
- package/dist/health.js.map +0 -1
- package/dist/image.d.ts +0 -115
- package/dist/image.d.ts.map +0 -1
- package/dist/image.js +0 -42
- package/dist/image.js.map +0 -1
- package/dist/run-request.d.ts +0 -244
- package/dist/run-request.d.ts.map +0 -1
- package/dist/run-request.js +0 -43
- package/dist/run-request.js.map +0 -1
- package/dist/session.d.ts +0 -447
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -78
- package/dist/session.js.map +0 -1
- package/dist/shared.d.ts +0 -90
- package/dist/shared.d.ts.map +0 -1
- package/dist/shared.js +0 -41
- package/dist/shared.js.map +0 -1
- package/dist/volume.d.ts +0 -140
- package/dist/volume.d.ts.map +0 -1
- package/dist/volume.js +0 -37
- package/dist/volume.js.map +0 -1
- package/src/figspec.ts +0 -279
- package/src/figstack.ts +0 -92
- package/src/health.ts +0 -8
- package/src/image.ts +0 -55
- package/src/run-request.ts +0 -55
- package/src/session.ts +0 -101
- package/src/shared.ts +0 -56
- package/src/volume.ts +0 -50
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
import { OpenAPIObjectConfig } from "@asteasolutions/zod-to-openapi/dist/v3.0/openapi-generator";
|
|
2
|
+
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import z from "zod";
|
|
6
|
+
import { OpenAPIMappedSchemaIterable } from "../.openapi-meta";
|
|
7
|
+
|
|
8
|
+
const fileSchema = z.enum([
|
|
9
|
+
"core-entities-figspec",
|
|
10
|
+
"core-entities-figstack",
|
|
11
|
+
"core-execute",
|
|
12
|
+
"core-generic",
|
|
13
|
+
"core-primitives",
|
|
14
|
+
"core-volumes",
|
|
15
|
+
"engine-dry-run",
|
|
16
|
+
"engine-deprecated-run-request",
|
|
17
|
+
"engine-health",
|
|
18
|
+
"engine-images",
|
|
19
|
+
"engine-response",
|
|
20
|
+
"engine-sessions",
|
|
21
|
+
"engine-volumes",
|
|
22
|
+
"engine-paths-health",
|
|
23
|
+
"engine-paths-containers",
|
|
24
|
+
"engine-paths-images",
|
|
25
|
+
"engine-paths-volumes",
|
|
26
|
+
"engine-paths-dry-run",
|
|
27
|
+
"engine-paths-sessions",
|
|
28
|
+
"engine-paths-stacks",
|
|
29
|
+
"registry-json-schema",
|
|
30
|
+
"registry-metadata",
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
type File = z.infer<typeof fileSchema>;
|
|
34
|
+
|
|
35
|
+
const openApiFileSchema = z.enum(["core", "registry"]);
|
|
36
|
+
type OpenAPIFileId = z.infer<typeof openApiFileSchema>;
|
|
37
|
+
|
|
38
|
+
const fileNames: {
|
|
39
|
+
[file in File]: {
|
|
40
|
+
camelCase: string,
|
|
41
|
+
pascalCase: string,
|
|
42
|
+
kebabCase: string,
|
|
43
|
+
type: "schema" | "path",
|
|
44
|
+
dir: string,
|
|
45
|
+
filename: string,
|
|
46
|
+
openApiFileId: OpenAPIFileId,
|
|
47
|
+
}
|
|
48
|
+
} = {
|
|
49
|
+
"core-entities-figspec": {
|
|
50
|
+
camelCase: "coreEntitiesFigSpec",
|
|
51
|
+
pascalCase: "CoreEntitiesFigSpec",
|
|
52
|
+
kebabCase: "core-entities-figspec",
|
|
53
|
+
type: "schema",
|
|
54
|
+
dir: "core/entities",
|
|
55
|
+
filename: "figspec",
|
|
56
|
+
openApiFileId: "core",
|
|
57
|
+
},
|
|
58
|
+
"core-entities-figstack": {
|
|
59
|
+
camelCase: "coreEntitiesFigStack",
|
|
60
|
+
pascalCase: "CoreEntitiesFigStack",
|
|
61
|
+
kebabCase: "core-entities-figstack",
|
|
62
|
+
type: "schema",
|
|
63
|
+
dir: "core/entities",
|
|
64
|
+
filename: "figstack",
|
|
65
|
+
openApiFileId: "core",
|
|
66
|
+
},
|
|
67
|
+
"core-execute": {
|
|
68
|
+
camelCase: "coreExecute",
|
|
69
|
+
pascalCase: "CoreExecute",
|
|
70
|
+
kebabCase: "core-execute",
|
|
71
|
+
type: "schema",
|
|
72
|
+
dir: "core",
|
|
73
|
+
filename: "execute",
|
|
74
|
+
openApiFileId: "core",
|
|
75
|
+
},
|
|
76
|
+
"core-generic": {
|
|
77
|
+
camelCase: "coreGeneric",
|
|
78
|
+
pascalCase: "CoreGeneric",
|
|
79
|
+
kebabCase: "core-generic",
|
|
80
|
+
type: "schema",
|
|
81
|
+
dir: "core",
|
|
82
|
+
filename: "generic",
|
|
83
|
+
openApiFileId: "core",
|
|
84
|
+
},
|
|
85
|
+
"core-primitives": {
|
|
86
|
+
camelCase: "corePrimitives",
|
|
87
|
+
pascalCase: "CorePrimitives",
|
|
88
|
+
kebabCase: "core-primitives",
|
|
89
|
+
type: "schema",
|
|
90
|
+
dir: "core",
|
|
91
|
+
filename: "primitives",
|
|
92
|
+
openApiFileId: "core",
|
|
93
|
+
},
|
|
94
|
+
"core-volumes": {
|
|
95
|
+
camelCase: "coreVolumes",
|
|
96
|
+
pascalCase: "CoreVolumes",
|
|
97
|
+
kebabCase: "core-volumes",
|
|
98
|
+
type: "schema",
|
|
99
|
+
dir: "core",
|
|
100
|
+
filename: "volumes",
|
|
101
|
+
openApiFileId: "core",
|
|
102
|
+
},
|
|
103
|
+
"engine-deprecated-run-request": {
|
|
104
|
+
camelCase: "engineDeprecatedRunRequest",
|
|
105
|
+
pascalCase: "EngineDeprecatedRunRequest",
|
|
106
|
+
kebabCase: "engine-deprecated-run-request",
|
|
107
|
+
type: "schema",
|
|
108
|
+
dir: "engine/deprecated",
|
|
109
|
+
filename: "run-request",
|
|
110
|
+
openApiFileId: "core",
|
|
111
|
+
},
|
|
112
|
+
"engine-dry-run": {
|
|
113
|
+
camelCase: "engineDryRun",
|
|
114
|
+
pascalCase: "EngineDryDry",
|
|
115
|
+
kebabCase: "engine-dry-run",
|
|
116
|
+
type: "schema",
|
|
117
|
+
dir: "engine",
|
|
118
|
+
filename: "dry-run",
|
|
119
|
+
openApiFileId: "core",
|
|
120
|
+
},
|
|
121
|
+
"engine-health": {
|
|
122
|
+
camelCase: "engineHealth",
|
|
123
|
+
pascalCase: "EngineHealth",
|
|
124
|
+
kebabCase: "engine-health",
|
|
125
|
+
type: "schema",
|
|
126
|
+
dir: "engine",
|
|
127
|
+
filename: "health",
|
|
128
|
+
openApiFileId: "core",
|
|
129
|
+
},
|
|
130
|
+
"engine-images": {
|
|
131
|
+
camelCase: "engineImages",
|
|
132
|
+
pascalCase: "EngineImages",
|
|
133
|
+
kebabCase: "engine-images",
|
|
134
|
+
type: "schema",
|
|
135
|
+
dir: "engine",
|
|
136
|
+
filename: "images",
|
|
137
|
+
openApiFileId: "core",
|
|
138
|
+
},
|
|
139
|
+
"engine-response": {
|
|
140
|
+
camelCase: "engineResponse",
|
|
141
|
+
pascalCase: "EngineResponse",
|
|
142
|
+
kebabCase: "engine-response",
|
|
143
|
+
type: "schema",
|
|
144
|
+
dir: "engine",
|
|
145
|
+
filename: "response",
|
|
146
|
+
openApiFileId: "core",
|
|
147
|
+
},
|
|
148
|
+
"engine-sessions": {
|
|
149
|
+
camelCase: "engineSessions",
|
|
150
|
+
pascalCase: "EngineSessions",
|
|
151
|
+
kebabCase: "engine-sessions",
|
|
152
|
+
type: "schema",
|
|
153
|
+
dir: "engine",
|
|
154
|
+
filename: "sessions",
|
|
155
|
+
openApiFileId: "core",
|
|
156
|
+
},
|
|
157
|
+
"engine-volumes": {
|
|
158
|
+
camelCase: "engineVolumes",
|
|
159
|
+
pascalCase: "EngineVolumes",
|
|
160
|
+
kebabCase: "engine-volumes",
|
|
161
|
+
type: "schema",
|
|
162
|
+
dir: "engine",
|
|
163
|
+
filename: "volumes",
|
|
164
|
+
openApiFileId: "core",
|
|
165
|
+
},
|
|
166
|
+
"engine-paths-health": {
|
|
167
|
+
camelCase: "pathsHealth",
|
|
168
|
+
pascalCase: "PathsHealth",
|
|
169
|
+
kebabCase: "paths-health",
|
|
170
|
+
type: "path",
|
|
171
|
+
dir: "engine/paths",
|
|
172
|
+
filename: "health",
|
|
173
|
+
openApiFileId: "core",
|
|
174
|
+
},
|
|
175
|
+
"engine-paths-containers": {
|
|
176
|
+
camelCase: "pathsContainers",
|
|
177
|
+
pascalCase: "PathsContainers",
|
|
178
|
+
kebabCase: "paths-containers",
|
|
179
|
+
type: "path",
|
|
180
|
+
dir: "engine/paths",
|
|
181
|
+
filename: "containers",
|
|
182
|
+
openApiFileId: "core",
|
|
183
|
+
},
|
|
184
|
+
"engine-paths-images": {
|
|
185
|
+
camelCase: "pathsImages",
|
|
186
|
+
pascalCase: "PathsImages",
|
|
187
|
+
kebabCase: "paths-images",
|
|
188
|
+
type: "path",
|
|
189
|
+
dir: "engine/paths",
|
|
190
|
+
filename: "images",
|
|
191
|
+
openApiFileId: "core",
|
|
192
|
+
},
|
|
193
|
+
"engine-paths-volumes": {
|
|
194
|
+
camelCase: "pathsVolumes",
|
|
195
|
+
pascalCase: "PathsVolumes",
|
|
196
|
+
kebabCase: "paths-volumes",
|
|
197
|
+
type: "path",
|
|
198
|
+
dir: "engine/paths",
|
|
199
|
+
filename: "volumes",
|
|
200
|
+
openApiFileId: "core",
|
|
201
|
+
},
|
|
202
|
+
"engine-paths-dry-run": {
|
|
203
|
+
camelCase: "pathsDryRun",
|
|
204
|
+
pascalCase: "PathsDryRun",
|
|
205
|
+
kebabCase: "paths-dry-run",
|
|
206
|
+
type: "path",
|
|
207
|
+
dir: "engine/paths",
|
|
208
|
+
filename: "dry-run",
|
|
209
|
+
openApiFileId: "core",
|
|
210
|
+
},
|
|
211
|
+
"engine-paths-sessions": {
|
|
212
|
+
camelCase: "pathsSessions",
|
|
213
|
+
pascalCase: "PathsSessions",
|
|
214
|
+
kebabCase: "paths-sessions",
|
|
215
|
+
type: "path",
|
|
216
|
+
dir: "engine/paths",
|
|
217
|
+
filename: "sessions",
|
|
218
|
+
openApiFileId: "core",
|
|
219
|
+
},
|
|
220
|
+
"engine-paths-stacks": {
|
|
221
|
+
camelCase: "pathsStacks",
|
|
222
|
+
pascalCase: "PathsStacks",
|
|
223
|
+
kebabCase: "paths-stacks",
|
|
224
|
+
type: "path",
|
|
225
|
+
dir: "engine/paths",
|
|
226
|
+
filename: "stacks",
|
|
227
|
+
openApiFileId: "core",
|
|
228
|
+
},
|
|
229
|
+
"registry-json-schema": {
|
|
230
|
+
camelCase: "registryJsonSchema",
|
|
231
|
+
pascalCase: "RegistryJsonSchema",
|
|
232
|
+
kebabCase: "registry-json-schema",
|
|
233
|
+
type: "schema",
|
|
234
|
+
dir: "registry",
|
|
235
|
+
filename: "json-schema",
|
|
236
|
+
openApiFileId: "registry",
|
|
237
|
+
},
|
|
238
|
+
"registry-metadata": {
|
|
239
|
+
camelCase: "registryMetadata",
|
|
240
|
+
pascalCase: "RegistryMetadata",
|
|
241
|
+
kebabCase: "registry-metadata",
|
|
242
|
+
type: "schema",
|
|
243
|
+
dir: "registry",
|
|
244
|
+
filename: "metadata",
|
|
245
|
+
openApiFileId: "registry",
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
function getVersion() {
|
|
250
|
+
const packageJsonPath = path.resolve(
|
|
251
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
252
|
+
"..", "..", "..",
|
|
253
|
+
"package.json"
|
|
254
|
+
);
|
|
255
|
+
const packageJsonData = readFileSync(packageJsonPath);
|
|
256
|
+
const parsed = z.object({ version: z.string() }).parse(
|
|
257
|
+
JSON.parse(packageJsonData.toString())
|
|
258
|
+
);
|
|
259
|
+
return parsed.version;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const openApiFiles: {
|
|
263
|
+
[Id in OpenAPIFileId]: {
|
|
264
|
+
fileName: string,
|
|
265
|
+
document: OpenAPIObjectConfig,
|
|
266
|
+
}
|
|
267
|
+
} = {
|
|
268
|
+
core: {
|
|
269
|
+
fileName: "openapi-new",
|
|
270
|
+
document: {
|
|
271
|
+
openapi: "3.1.0",
|
|
272
|
+
info: {
|
|
273
|
+
title: "Figulus Schema",
|
|
274
|
+
version: getVersion(),
|
|
275
|
+
description:
|
|
276
|
+
"Schemas and types for the Figulus ecosystem",
|
|
277
|
+
contact: {
|
|
278
|
+
name: "Figulus Project",
|
|
279
|
+
url: "https://github.com/figulusproject/figulus",
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
servers: [
|
|
283
|
+
{
|
|
284
|
+
url: "http://localhost",
|
|
285
|
+
description: "Local Unix socket (connect via /run/figulus/figulus.sock)",
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
tags: [
|
|
289
|
+
{
|
|
290
|
+
name: "health",
|
|
291
|
+
description: "Engine and Docker health checks",
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: "containers",
|
|
295
|
+
description: "Container job execution and lifecycle management",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "images",
|
|
299
|
+
description: "Docker image build and garbage collection",
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
name: "volumes",
|
|
303
|
+
description: "Docker volume management",
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: "sessions",
|
|
307
|
+
description: "Persistent session container management",
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "stacks",
|
|
311
|
+
description: "FigStack multi-container orchestration",
|
|
312
|
+
},
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
registry: {
|
|
317
|
+
fileName: "openapi-registry",
|
|
318
|
+
document: {
|
|
319
|
+
openapi: "3.1.0",
|
|
320
|
+
info: {
|
|
321
|
+
title: "Figulus Registry Schema",
|
|
322
|
+
version: getVersion(),
|
|
323
|
+
description:
|
|
324
|
+
"Schemas and types for the Figulus Registry",
|
|
325
|
+
contact: {
|
|
326
|
+
name: "Figulus Project",
|
|
327
|
+
url: "https://github.com/figulusproject/figulus",
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
servers: [
|
|
331
|
+
{
|
|
332
|
+
url: "https://github.com/figulusproject/registry",
|
|
333
|
+
description: "Official GitHub repository for the registry",
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function getName(file: File, casing: "camel"|"pascal"|"kebab") {
|
|
341
|
+
return fileNames[file][`${casing}Case`];
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function getType(file: File) {
|
|
345
|
+
return fileNames[file].type;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function getDir(file: File) {
|
|
349
|
+
return fileNames[file].dir || "";
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function getFilename(file: File) {
|
|
353
|
+
return fileNames[file].filename || getName(file, "kebab");
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function getOpenAPIFileId(file: File) {
|
|
357
|
+
return fileNames[file].openApiFileId;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const generatedDirPath = ".openapi-meta/generated/";
|
|
361
|
+
|
|
362
|
+
type IterableBase = OpenAPIMappedSchemaIterable<string>;
|
|
363
|
+
|
|
364
|
+
function getFileLines(file: File) {
|
|
365
|
+
const dir = getDir(file);
|
|
366
|
+
const dirPath = dir ? `${dir}/` : "";
|
|
367
|
+
const content = readFileSync(path.resolve(`./src/${dirPath}${getFilename(file)}.ts`));
|
|
368
|
+
return content.toString().split("\n");
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function getFileSrc(file: File): IterableBase {
|
|
372
|
+
const lines = getFileLines(file);
|
|
373
|
+
const output: IterableBase = [];
|
|
374
|
+
|
|
375
|
+
if (getType(file) === "schema") {
|
|
376
|
+
let currentConst: string = "";
|
|
377
|
+
|
|
378
|
+
for (const l of lines) {
|
|
379
|
+
const isConst = l.includes("export const");
|
|
380
|
+
const isOpenAPIRef = /\.openapi\("[^"]+"\)/.test(l);
|
|
381
|
+
if (!isConst && !isOpenAPIRef) continue;
|
|
382
|
+
|
|
383
|
+
const matchAndSlice = (matchPhraseStart: string, matchPhraseEnd: string) => {
|
|
384
|
+
const start = l.slice(l.indexOf(matchPhraseStart) + matchPhraseStart.length);
|
|
385
|
+
const end = start.slice(0, start.indexOf(matchPhraseEnd) + matchPhraseEnd.length - 1);
|
|
386
|
+
return end;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (isConst) {
|
|
390
|
+
const start = l.slice(l.indexOf("export const ") + "export const ".length);
|
|
391
|
+
const match = start.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)/);
|
|
392
|
+
currentConst = match ? match[1] : "";
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
output.push({ key: matchAndSlice(`openapi("`, `"`), obj: currentConst });
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
const matchPhraseStart = "export const";
|
|
400
|
+
const matchPhraseEnd = ": RouteConfig";
|
|
401
|
+
|
|
402
|
+
const constNames = lines.filter((l) => l.startsWith(matchPhraseStart)).map((l) => {
|
|
403
|
+
const start = l.slice(l.indexOf(matchPhraseStart) + matchPhraseStart.length + 1);
|
|
404
|
+
const end = start.slice(0, start.indexOf(matchPhraseEnd));
|
|
405
|
+
return end;
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
constNames.forEach((name) => {
|
|
409
|
+
output.push({ key: name, obj: name });
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return output;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function generateKeySchema(file: File, refs: IterableBase) {
|
|
417
|
+
const prefix = `export const ${getName(file, "camel")}OpenAPIKeySchema = z.enum([\n`;
|
|
418
|
+
const suffix = `\n]);`;
|
|
419
|
+
return prefix + refs.map((r) => ` "${r.key}",`).join("\n") + suffix;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function generateKeyType(file: File) {
|
|
423
|
+
return `type ${getName(file, "pascal")}OpenAPIKey = z.infer<typeof ${getName(file, "camel")}OpenAPIKeySchema>;`
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function generateMappings(file: File, refs: IterableBase) {
|
|
427
|
+
const isSchema = getType(file) === "schema";
|
|
428
|
+
const valueType = isSchema ? "OpenAPIMappedSchemaValue" : "RouteConfig";
|
|
429
|
+
const prefix = `const ${getName(file, "camel")}OpenAPIMappings: { [key in ${getName(file, "pascal")}OpenAPIKey]: ${valueType} } = {\n`;
|
|
430
|
+
const suffix = `\n};`;
|
|
431
|
+
return prefix + refs.map((r) => ` ${r.key}: ${r.obj},`).join("\n") + suffix;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function generateIterable(file: File) {
|
|
435
|
+
const isSchema = getType(file) === "schema";
|
|
436
|
+
const valueType = isSchema ? "OpenAPIMappedSchemaValue" : "RouteConfig";
|
|
437
|
+
return `export const ${getName(file, "camel")}OpenAPIIterable: OpenAPIMappedSchemaIterable<${valueType}> = ${getName(file, "camel")}OpenAPIKeySchema.options.map((key) => ({\n key,\n obj: ${getName(file, "camel")}OpenAPIMappings[key],\n}));`
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function generateFile(file: File) {
|
|
441
|
+
const refs = getFileSrc(file);
|
|
442
|
+
const isSchema = getType(file) === "schema";
|
|
443
|
+
const dir = getDir(file);
|
|
444
|
+
const dirPath = dir ? `${dir}/` : "";
|
|
445
|
+
|
|
446
|
+
// Calculate relative path depth: for files in subdirs, we need extra ../
|
|
447
|
+
// File at .openapi-meta/generated/paths/health.ts needs ../../../src
|
|
448
|
+
// File at .openapi-meta/generated/health.ts needs ../../src
|
|
449
|
+
const depth = dir ? (dir.split("/").length + 2) : 2;
|
|
450
|
+
const relativePrefix = "../".repeat(depth);
|
|
451
|
+
|
|
452
|
+
const imports = [
|
|
453
|
+
`import z from "zod";`,
|
|
454
|
+
`import { OpenAPIMappedSchemaIterable, OpenAPIMappedSchemaValue } from "${"../".repeat(depth - 1)}index.js";`,
|
|
455
|
+
isSchema ? `` : `import { RouteConfig } from "@asteasolutions/zod-to-openapi";`,
|
|
456
|
+
`import { ${refs.map((v) => v.obj).join(", ")} } from "${relativePrefix}src/${dirPath}${getFilename(file)}.js";`,
|
|
457
|
+
].filter(Boolean).join("\n");
|
|
458
|
+
|
|
459
|
+
const keySchema = generateKeySchema(file, refs);
|
|
460
|
+
const keyType = generateKeyType(file);
|
|
461
|
+
const mappings = generateMappings(file, refs);
|
|
462
|
+
const iterable = generateIterable(file);
|
|
463
|
+
|
|
464
|
+
return imports + "\n\n" + keySchema + "\n" + keyType + "\n\n" + mappings + "\n\n" + iterable + "\n";
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function generateIndex(files: File[]) {
|
|
468
|
+
const imports = [
|
|
469
|
+
`import { OpenAPIMappedSchemaIterable, OpenAPIMappedSchemaValue } from "..";\nimport { RouteConfig } from "@asteasolutions/zod-to-openapi";`,
|
|
470
|
+
...files.map((f) => {
|
|
471
|
+
const dir = getDir(f);
|
|
472
|
+
const dirPath = dir ? `${dir}/` : "";
|
|
473
|
+
return `import { ${getName(f, "camel")}OpenAPIIterable } from "./${dirPath}${getFilename(f)}.js";`;
|
|
474
|
+
}),
|
|
475
|
+
"\n"
|
|
476
|
+
].join("\n");
|
|
477
|
+
|
|
478
|
+
const schemaFiles = files.filter((f) => getType(f) === "schema");
|
|
479
|
+
const schemaIterables = () => {
|
|
480
|
+
const prefix = `export const openApiSchemaIterables: OpenAPIMappedSchemaIterable<OpenAPIMappedSchemaValue> = [\n`;
|
|
481
|
+
const suffix = `\n];`;
|
|
482
|
+
return prefix + schemaFiles.map((f) => ` ...${getName(f, "camel")}OpenAPIIterable,`).join("\n") + suffix;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const pathFiles = files.filter((f) => getType(f) === "path");
|
|
486
|
+
const pathIterables = () => {
|
|
487
|
+
const prefix = `export const openApiPathIterables: OpenAPIMappedSchemaIterable<RouteConfig> = [\n`;
|
|
488
|
+
const suffix = `\n];`;
|
|
489
|
+
return prefix + pathFiles.map((f) => ` ...${getName(f, "camel")}OpenAPIIterable,`).join("\n") + suffix;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return imports + schemaIterables() + "\n\n" + pathIterables() + "\n";
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function writeFile(file: File, content: string) {
|
|
496
|
+
const dir = getDir(file);
|
|
497
|
+
const dirPath = dir ? `${dir}/` : "";
|
|
498
|
+
const fullPath = generatedDirPath + dirPath + getFilename(file) + ".ts";
|
|
499
|
+
|
|
500
|
+
if (dir) {
|
|
501
|
+
mkdirSync(path.resolve(generatedDirPath + dir), { recursive: true });
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
writeFileSync(path.resolve(fullPath), content);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function generateFiles(openApiFileId: OpenAPIFileId) {
|
|
508
|
+
rmSync(generatedDirPath, { recursive: true, force: true, });
|
|
509
|
+
mkdirSync(generatedDirPath, { recursive: true });
|
|
510
|
+
|
|
511
|
+
const files = fileSchema.options;
|
|
512
|
+
const filtered = files.filter((f) => getOpenAPIFileId(f) === openApiFileId);
|
|
513
|
+
|
|
514
|
+
for (const file of filtered) {
|
|
515
|
+
const content = generateFile(file);
|
|
516
|
+
writeFile(file, content);
|
|
517
|
+
}
|
|
518
|
+
writeFileSync(path.resolve(generatedDirPath + "index.ts"), generateIndex(filtered));
|
|
519
|
+
writeFileSync(path.resolve(generatedDirPath + "data.json"), JSON.stringify(openApiFiles[openApiFileId], null, 2));
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function parseArgs() {
|
|
523
|
+
const args = process.argv;
|
|
524
|
+
if(args.length < 3)
|
|
525
|
+
throw new Error("openApiFileId argument is missing!");
|
|
526
|
+
|
|
527
|
+
const arg = args[2].toLowerCase();
|
|
528
|
+
if(!arg.startsWith("--openapifileid="))
|
|
529
|
+
throw new Error(`Invalid argument provided! Expected '--openApiFileId=', received '${arg}'.`);
|
|
530
|
+
|
|
531
|
+
const openApiFileId = openApiFileSchema.parse(
|
|
532
|
+
arg.replace("--openapifileid=", "")
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
return { openApiFileId };
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const { openApiFileId } = parseArgs();
|
|
539
|
+
|
|
540
|
+
generateFiles(openApiFileId);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { buildExecuteStepSchema, executeMainCmdSchema, executeShutdownCmdSchema, executeStartupCmdSchema, scheduledCmdSchema } from '../execute.js';
|
|
4
|
+
import { installGroupSchema, portMappingSchema } from '../generic.js';
|
|
5
|
+
import { buildVolumeMountSchema, runVolumeMountSchema } from '../volumes.js';
|
|
6
|
+
|
|
7
|
+
extendZodWithOpenApi(z);
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Execute model
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
export const figSpecExecuteSchema = z.object({
|
|
14
|
+
startup: z.array(executeStartupCmdSchema).optional().describe("Commands that run before main (sync commands block main start)"),
|
|
15
|
+
main: executeMainCmdSchema,
|
|
16
|
+
shutdown: z.array(executeShutdownCmdSchema).optional().describe("Commands that run before the container stops"),
|
|
17
|
+
scheduled: z.array(scheduledCmdSchema).optional(),
|
|
18
|
+
}).openapi("FigSpecExecute");
|
|
19
|
+
export type FigSpecExecute = z.infer<typeof figSpecExecuteSchema>;
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Build spec
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
export const figSpecBuildBaseSchema = z.object({
|
|
26
|
+
schemaVersion: z.string().optional(),
|
|
27
|
+
specName: z.string().optional(),
|
|
28
|
+
packagesToInstall: z.array(installGroupSchema).optional(),
|
|
29
|
+
platform: z.string().optional().describe("Target platform, e.g. \"linux/amd64\" or \"linux/arm64\"").openapi({ example: "linux/amd64" }),
|
|
30
|
+
env: z.record(z.string(), z.string()).optional().describe("Build-time environment variables"),
|
|
31
|
+
volumes: z.array(buildVolumeMountSchema).optional(),
|
|
32
|
+
execute: z.array(buildExecuteStepSchema).optional().describe("Ordered list of RUN instructions; each step is a separate cacheable layer"),
|
|
33
|
+
workDir: z.string().optional().describe("Working directory inside the image"),
|
|
34
|
+
user: z.string().optional().describe("User to run build commands as (e.g. \"root\")"),
|
|
35
|
+
}).openapi("FigSpecBuildBase");
|
|
36
|
+
|
|
37
|
+
export const figSpecBuildStandaloneSchema = figSpecBuildBaseSchema.extend({
|
|
38
|
+
baseImage: z.string(),
|
|
39
|
+
}).openapi("FigSpecBuildStandalone");
|
|
40
|
+
export type FigSpecBuildStandalone = z.infer<typeof figSpecBuildStandaloneSchema>;
|
|
41
|
+
|
|
42
|
+
export const figSpecBuildWithBaseSpecSchema = figSpecBuildBaseSchema.extend({
|
|
43
|
+
baseSpec: z.string(),
|
|
44
|
+
baseImage: z.string().optional(),
|
|
45
|
+
}).openapi("FigSpecBuildWithBaseSpec");
|
|
46
|
+
export type FigSpecBuildWithBaseSpec = z.infer<typeof figSpecBuildWithBaseSpecSchema>;
|
|
47
|
+
|
|
48
|
+
export const figSpecBuildSchema = z.union([
|
|
49
|
+
figSpecBuildStandaloneSchema,
|
|
50
|
+
figSpecBuildWithBaseSpecSchema,
|
|
51
|
+
]);
|
|
52
|
+
export type FigSpecBuild = z.infer<typeof figSpecBuildSchema>;
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Run spec
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
export const figSpecRunSchema = z.object({
|
|
59
|
+
schemaVersion: z.string().optional(),
|
|
60
|
+
specName: z.string().optional(),
|
|
61
|
+
execute: figSpecExecuteSchema,
|
|
62
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
63
|
+
secrets: z.record(z.string(), z.string()).optional().describe("Secret references: env_name → \"vault:path#field\""),
|
|
64
|
+
volumes: z.array(runVolumeMountSchema).optional(),
|
|
65
|
+
workDir: z.string().optional(),
|
|
66
|
+
user: z.string().optional(),
|
|
67
|
+
ports: z.array(portMappingSchema).optional(),
|
|
68
|
+
}).openapi("FigSpecRun");
|
|
69
|
+
export type FigSpecRun = z.infer<typeof figSpecRunSchema>;
|
|
70
|
+
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Top-level Figspec document
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
export const figSpecBuildInputSchema = z.union([
|
|
76
|
+
figSpecBuildSchema,
|
|
77
|
+
z.string(),
|
|
78
|
+
z.array(z.string()),
|
|
79
|
+
]).openapi("FigSpecBuildInput");
|
|
80
|
+
export type FigSpecBuildInput = z.infer<typeof figSpecBuildInputSchema>;
|
|
81
|
+
|
|
82
|
+
export const figSpecRunInputSchema = z.union([
|
|
83
|
+
figSpecRunSchema,
|
|
84
|
+
z.string(),
|
|
85
|
+
]).openapi("FigSpecRunInput");
|
|
86
|
+
export type FigSpecRunInput = z.infer<typeof figSpecRunInputSchema>;
|
|
87
|
+
|
|
88
|
+
export const figSpecSchema = z.object({
|
|
89
|
+
schemaVersion: z.string(),
|
|
90
|
+
specName: z.string().optional(),
|
|
91
|
+
build: figSpecBuildInputSchema,
|
|
92
|
+
run: figSpecRunInputSchema.optional(),
|
|
93
|
+
}).openapi("FigSpec");
|
|
94
|
+
export type FigSpec = z.infer<typeof figSpecSchema>;
|