@ninedeploy/schemas 0.2.4 → 0.3.0
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/auth.d.ts +19 -14
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +18 -4
- package/dist/auth.js.map +1 -1
- package/dist/common.d.ts +18 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +47 -0
- package/dist/common.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +110 -0
- package/dist/insights.d.ts.map +1 -0
- package/dist/insights.js +64 -0
- package/dist/insights.js.map +1 -0
- package/dist/labels.d.ts +108 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +70 -0
- package/dist/labels.js.map +1 -0
- package/dist/management.d.ts +6 -7
- package/dist/management.d.ts.map +1 -1
- package/dist/management.js +34 -9
- package/dist/management.js.map +1 -1
- package/dist/ninedeployManifest.d.ts +292 -0
- package/dist/ninedeployManifest.d.ts.map +1 -0
- package/dist/ninedeployManifest.js +284 -0
- package/dist/ninedeployManifest.js.map +1 -0
- package/dist/project.d.ts +4 -2
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +2 -2
- package/dist/project.js.map +1 -1
- package/dist/secretScan.d.ts +52 -0
- package/dist/secretScan.d.ts.map +1 -0
- package/dist/secretScan.js +125 -0
- package/dist/secretScan.js.map +1 -0
- package/dist/service.d.ts +118 -4
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +148 -10
- package/dist/service.js.map +1 -1
- package/dist/workspaces.d.ts +49 -0
- package/dist/workspaces.d.ts.map +1 -1
- package/dist/workspaces.js +9 -0
- package/dist/workspaces.js.map +1 -1
- package/package.json +1 -1
package/dist/service.d.ts
CHANGED
|
@@ -10,9 +10,13 @@ export declare const buildPack: z.ZodEnum<{
|
|
|
10
10
|
nixpacks: "nixpacks";
|
|
11
11
|
}>;
|
|
12
12
|
export declare const createService: z.ZodObject<{
|
|
13
|
-
|
|
13
|
+
templateId: z.ZodOptional<z.ZodString>;
|
|
14
|
+
tagProjectIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
15
|
+
tagWorkspaceIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
16
|
+
tagLabelIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
14
17
|
name: z.ZodString;
|
|
15
18
|
slug: z.ZodOptional<z.ZodString>;
|
|
19
|
+
reuseExisting: z.ZodOptional<z.ZodBoolean>;
|
|
16
20
|
type: z.ZodDefault<z.ZodEnum<{
|
|
17
21
|
compose: "compose";
|
|
18
22
|
docker: "docker";
|
|
@@ -58,7 +62,9 @@ export type CreateService = z.infer<typeof createService>;
|
|
|
58
62
|
* still applies `.default()` values for absent keys, which would silently
|
|
59
63
|
* rewrite `type` back to 'docker' and `branch` to 'main' on every PATCH. */
|
|
60
64
|
export declare const updateService: z.ZodObject<{
|
|
61
|
-
|
|
65
|
+
tagProjectIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
66
|
+
tagWorkspaceIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
67
|
+
tagLabelIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
62
68
|
name: z.ZodOptional<z.ZodString>;
|
|
63
69
|
slug: z.ZodOptional<z.ZodString>;
|
|
64
70
|
type: z.ZodOptional<z.ZodEnum<{
|
|
@@ -68,7 +74,7 @@ export declare const updateService: z.ZodObject<{
|
|
|
68
74
|
}>>;
|
|
69
75
|
repoUrl: z.ZodOptional<z.ZodURL>;
|
|
70
76
|
branch: z.ZodOptional<z.ZodString>;
|
|
71
|
-
sourceId: z.ZodOptional<z.ZodNumber
|
|
77
|
+
sourceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
72
78
|
serverId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
73
79
|
image: z.ZodOptional<z.ZodString>;
|
|
74
80
|
volumeMount: z.ZodOptional<z.ZodString>;
|
|
@@ -106,7 +112,24 @@ export type CreateServiceInput = z.input<typeof createService>;
|
|
|
106
112
|
export type UpdateServiceInput = z.input<typeof updateService>;
|
|
107
113
|
export declare const service: z.ZodObject<{
|
|
108
114
|
id: z.ZodNumber;
|
|
109
|
-
|
|
115
|
+
projectIds: z.ZodArray<z.ZodNumber>;
|
|
116
|
+
workspaceIds: z.ZodArray<z.ZodNumber>;
|
|
117
|
+
labelIds: z.ZodArray<z.ZodNumber>;
|
|
118
|
+
projects: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
119
|
+
id: z.ZodNumber;
|
|
120
|
+
name: z.ZodString;
|
|
121
|
+
slug: z.ZodString;
|
|
122
|
+
}, z.core.$strip>>>;
|
|
123
|
+
workspaces: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
124
|
+
id: z.ZodNumber;
|
|
125
|
+
name: z.ZodString;
|
|
126
|
+
slug: z.ZodString;
|
|
127
|
+
}, z.core.$strip>>>;
|
|
128
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
129
|
+
id: z.ZodNumber;
|
|
130
|
+
name: z.ZodString;
|
|
131
|
+
color: z.ZodString;
|
|
132
|
+
}, z.core.$strip>>>;
|
|
110
133
|
serverId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
111
134
|
name: z.ZodString;
|
|
112
135
|
slug: z.ZodString;
|
|
@@ -126,6 +149,7 @@ export declare const service: z.ZodObject<{
|
|
|
126
149
|
repoUrl: z.ZodNullable<z.ZodString>;
|
|
127
150
|
branch: z.ZodString;
|
|
128
151
|
sourceId: z.ZodNullable<z.ZodNumber>;
|
|
152
|
+
sourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
129
153
|
image: z.ZodNullable<z.ZodString>;
|
|
130
154
|
volumeMount: z.ZodNullable<z.ZodString>;
|
|
131
155
|
composeService: z.ZodNullable<z.ZodString>;
|
|
@@ -186,8 +210,10 @@ export declare const source: z.ZodObject<{
|
|
|
186
210
|
type: z.ZodString;
|
|
187
211
|
hasToken: z.ZodBoolean;
|
|
188
212
|
hasDeployKey: z.ZodBoolean;
|
|
213
|
+
registryUsername: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
189
214
|
defaultBranch: z.ZodNullable<z.ZodString>;
|
|
190
215
|
createdAt: z.ZodString;
|
|
216
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
191
217
|
}, z.core.$strip>;
|
|
192
218
|
export type Source = z.infer<typeof source>;
|
|
193
219
|
export declare const triggerDeploy: z.ZodObject<{
|
|
@@ -263,6 +289,7 @@ export declare const webhook: z.ZodObject<{
|
|
|
263
289
|
branch: z.ZodString;
|
|
264
290
|
active: z.ZodBoolean;
|
|
265
291
|
watchPaths: z.ZodString;
|
|
292
|
+
sourceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
266
293
|
url: z.ZodString;
|
|
267
294
|
createdAt: z.ZodString;
|
|
268
295
|
}, z.core.$strip>;
|
|
@@ -273,6 +300,7 @@ export declare const createdWebhook: z.ZodObject<{
|
|
|
273
300
|
branch: z.ZodString;
|
|
274
301
|
active: z.ZodBoolean;
|
|
275
302
|
watchPaths: z.ZodString;
|
|
303
|
+
sourceId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
276
304
|
url: z.ZodString;
|
|
277
305
|
createdAt: z.ZodString;
|
|
278
306
|
secret: z.ZodString;
|
|
@@ -293,6 +321,7 @@ export declare const createDatabase: z.ZodObject<{
|
|
|
293
321
|
}>;
|
|
294
322
|
version: z.ZodOptional<z.ZodString>;
|
|
295
323
|
projectId: z.ZodOptional<z.ZodNumber>;
|
|
324
|
+
reuseExisting: z.ZodOptional<z.ZodBoolean>;
|
|
296
325
|
existingVolume: z.ZodOptional<z.ZodString>;
|
|
297
326
|
extensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
298
327
|
webGuiEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -335,6 +364,7 @@ export type ManagedDatabase = z.infer<typeof managedDatabase>;
|
|
|
335
364
|
export declare const createAttachment: z.ZodObject<{
|
|
336
365
|
databaseId: z.ZodNumber;
|
|
337
366
|
envAlias: z.ZodOptional<z.ZodString>;
|
|
367
|
+
reuseExisting: z.ZodOptional<z.ZodBoolean>;
|
|
338
368
|
}, z.core.$strip>;
|
|
339
369
|
export type CreateAttachmentInput = z.input<typeof createAttachment>;
|
|
340
370
|
export declare const attachment: z.ZodObject<{
|
|
@@ -352,6 +382,7 @@ export declare const upsertEnvVar: z.ZodObject<{
|
|
|
352
382
|
key: z.ZodString;
|
|
353
383
|
value: z.ZodString;
|
|
354
384
|
isSecret: z.ZodOptional<z.ZodBoolean>;
|
|
385
|
+
overwriteExisting: z.ZodOptional<z.ZodBoolean>;
|
|
355
386
|
}, z.core.$strip>;
|
|
356
387
|
export type UpsertEnvVarInput = z.input<typeof upsertEnvVar>;
|
|
357
388
|
export declare const envVar: z.ZodObject<{
|
|
@@ -361,6 +392,36 @@ export declare const envVar: z.ZodObject<{
|
|
|
361
392
|
isSecret: z.ZodBoolean;
|
|
362
393
|
}, z.core.$strip>;
|
|
363
394
|
export type EnvVar = z.infer<typeof envVar>;
|
|
395
|
+
/** Create a new attachment. Exactly one of `volumeName` or `create.label`
|
|
396
|
+
* must be present — the former attaches an existing managed volume, the
|
|
397
|
+
* latter provisions a new one (system-generated name) and immediately
|
|
398
|
+
* attaches it. */
|
|
399
|
+
export declare const createServiceVolumeAttachment: z.ZodObject<{
|
|
400
|
+
volumeName: z.ZodOptional<z.ZodString>;
|
|
401
|
+
create: z.ZodOptional<z.ZodObject<{
|
|
402
|
+
label: z.ZodString;
|
|
403
|
+
}, z.core.$strip>>;
|
|
404
|
+
containerPath: z.ZodString;
|
|
405
|
+
readOnly: z.ZodOptional<z.ZodBoolean>;
|
|
406
|
+
}, z.core.$strip>;
|
|
407
|
+
export type CreateServiceVolumeAttachmentInput = z.input<typeof createServiceVolumeAttachment>;
|
|
408
|
+
/** PATCH shape — path and readOnly are optional, but at least one must change. */
|
|
409
|
+
export declare const updateServiceVolumeAttachment: z.ZodObject<{
|
|
410
|
+
containerPath: z.ZodOptional<z.ZodString>;
|
|
411
|
+
readOnly: z.ZodOptional<z.ZodBoolean>;
|
|
412
|
+
}, z.core.$strip>;
|
|
413
|
+
export type UpdateServiceVolumeAttachmentInput = z.input<typeof updateServiceVolumeAttachment>;
|
|
414
|
+
/** API representation of a service's volume attachment. */
|
|
415
|
+
export declare const serviceVolumeAttachment: z.ZodObject<{
|
|
416
|
+
id: z.ZodNumber;
|
|
417
|
+
serviceId: z.ZodNumber;
|
|
418
|
+
volumeName: z.ZodString;
|
|
419
|
+
containerPath: z.ZodString;
|
|
420
|
+
readOnly: z.ZodBoolean;
|
|
421
|
+
createdAt: z.ZodString;
|
|
422
|
+
updatedAt: z.ZodString;
|
|
423
|
+
}, z.core.$strip>;
|
|
424
|
+
export type ServiceVolumeAttachment = z.infer<typeof serviceVolumeAttachment>;
|
|
364
425
|
export declare const setLimits: z.ZodObject<{
|
|
365
426
|
cpuShares: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
366
427
|
memLimitMb: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
@@ -476,20 +537,38 @@ export type TopologyGraph = z.infer<typeof topologyGraph>;
|
|
|
476
537
|
export declare const backup: z.ZodObject<{
|
|
477
538
|
id: z.ZodNumber;
|
|
478
539
|
databaseId: z.ZodNullable<z.ZodNumber>;
|
|
540
|
+
volumeName: z.ZodNullable<z.ZodString>;
|
|
541
|
+
scope: z.ZodEnum<{
|
|
542
|
+
db: "db";
|
|
543
|
+
volumes: "volumes";
|
|
544
|
+
}>;
|
|
479
545
|
status: z.ZodString;
|
|
480
546
|
sizeBytes: z.ZodNumber;
|
|
547
|
+
hasRemoteCopy: z.ZodOptional<z.ZodBoolean>;
|
|
481
548
|
createdAt: z.ZodString;
|
|
482
549
|
}, z.core.$strip>;
|
|
483
550
|
export type Backup = z.infer<typeof backup>;
|
|
484
551
|
export declare const backupWithDb: z.ZodObject<{
|
|
485
552
|
id: z.ZodNumber;
|
|
486
553
|
databaseId: z.ZodNullable<z.ZodNumber>;
|
|
554
|
+
volumeName: z.ZodNullable<z.ZodString>;
|
|
555
|
+
scope: z.ZodEnum<{
|
|
556
|
+
db: "db";
|
|
557
|
+
volumes: "volumes";
|
|
558
|
+
}>;
|
|
487
559
|
status: z.ZodString;
|
|
488
560
|
sizeBytes: z.ZodNumber;
|
|
561
|
+
hasRemoteCopy: z.ZodOptional<z.ZodBoolean>;
|
|
489
562
|
createdAt: z.ZodString;
|
|
490
563
|
databaseName: z.ZodNullable<z.ZodString>;
|
|
491
564
|
}, z.core.$strip>;
|
|
492
565
|
export type BackupWithDb = z.infer<typeof backupWithDb>;
|
|
566
|
+
/** Create a new volume backup. The `volumeName` is the route param; the
|
|
567
|
+
* body only carries the `label` for human-friendly file naming. */
|
|
568
|
+
export declare const createVolumeBackup: z.ZodObject<{
|
|
569
|
+
label: z.ZodOptional<z.ZodString>;
|
|
570
|
+
}, z.core.$strip>;
|
|
571
|
+
export type CreateVolumeBackupInput = z.input<typeof createVolumeBackup>;
|
|
493
572
|
export declare const templateSummary: z.ZodObject<{
|
|
494
573
|
id: z.ZodString;
|
|
495
574
|
name: z.ZodString;
|
|
@@ -497,6 +576,8 @@ export declare const templateSummary: z.ZodObject<{
|
|
|
497
576
|
category: z.ZodString;
|
|
498
577
|
emoji: z.ZodString;
|
|
499
578
|
featured: z.ZodOptional<z.ZodBoolean>;
|
|
579
|
+
runtimeVerified: z.ZodOptional<z.ZodBoolean>;
|
|
580
|
+
verifiedAt: z.ZodOptional<z.ZodISODate>;
|
|
500
581
|
}, z.core.$strip>;
|
|
501
582
|
export type TemplateSummary = z.infer<typeof templateSummary>;
|
|
502
583
|
export declare const template: z.ZodObject<{
|
|
@@ -517,6 +598,8 @@ export declare const template: z.ZodObject<{
|
|
|
517
598
|
website: z.ZodOptional<z.ZodString>;
|
|
518
599
|
docs: z.ZodOptional<z.ZodString>;
|
|
519
600
|
featured: z.ZodOptional<z.ZodBoolean>;
|
|
601
|
+
runtimeVerified: z.ZodOptional<z.ZodBoolean>;
|
|
602
|
+
verifiedAt: z.ZodOptional<z.ZodISODate>;
|
|
520
603
|
requires: z.ZodOptional<z.ZodString>;
|
|
521
604
|
dbEngine: z.ZodOptional<z.ZodEnum<{
|
|
522
605
|
clickhouse: "clickhouse";
|
|
@@ -529,10 +612,41 @@ export declare const template: z.ZodObject<{
|
|
|
529
612
|
redis: "redis";
|
|
530
613
|
valkey: "valkey";
|
|
531
614
|
}>>;
|
|
615
|
+
databaseEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
616
|
+
database: "database";
|
|
617
|
+
host: "host";
|
|
618
|
+
hostPort: "hostPort";
|
|
619
|
+
password: "password";
|
|
620
|
+
port: "port";
|
|
621
|
+
url: "url";
|
|
622
|
+
username: "username";
|
|
623
|
+
}>>>;
|
|
532
624
|
cmd: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
533
625
|
dockerSocket: z.ZodOptional<z.ZodBoolean>;
|
|
534
626
|
}, z.core.$strip>;
|
|
535
627
|
export type Template = z.infer<typeof template>;
|
|
628
|
+
/**
|
|
629
|
+
* One canonical Hub installation request. Image, internal port, volume,
|
|
630
|
+
* command, Docker socket and database mapping are intentionally absent: they
|
|
631
|
+
* are privileged registry-owned fields resolved by the server.
|
|
632
|
+
*/
|
|
633
|
+
export declare const deployTemplate: z.ZodObject<{
|
|
634
|
+
name: z.ZodOptional<z.ZodString>;
|
|
635
|
+
projectId: z.ZodOptional<z.ZodNumber>;
|
|
636
|
+
serverId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
637
|
+
publishedPort: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
638
|
+
healthPath: z.ZodOptional<z.ZodString>;
|
|
639
|
+
cpuShares: z.ZodOptional<z.ZodNumber>;
|
|
640
|
+
memLimitMb: z.ZodOptional<z.ZodNumber>;
|
|
641
|
+
env: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
642
|
+
key: z.ZodString;
|
|
643
|
+
value: z.ZodString;
|
|
644
|
+
isSecret: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
645
|
+
}, z.core.$strip>>>;
|
|
646
|
+
reuseExisting: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
647
|
+
}, z.core.$strip>;
|
|
648
|
+
export type DeployTemplateInput = z.input<typeof deployTemplate>;
|
|
649
|
+
export type DeployTemplate = z.infer<typeof deployTemplate>;
|
|
536
650
|
export declare const domainEntry: z.ZodObject<{
|
|
537
651
|
id: z.ZodNumber;
|
|
538
652
|
hostname: z.ZodString;
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,WAAW;;;;EAAuC,CAAC;AAChE,eAAO,MAAM,SAAS;;;;EAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/dist/service.js
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { envVarName, gitBranch, gitRepoUrl, httpPath, slug } from './common.js';
|
|
2
|
+
import { containerPath, dockerVolumeName, envVarName, gitBranch, gitRepoUrl, httpPath, repoBaseDir, repoRelativePath, slug } from './common.js';
|
|
3
3
|
export const serviceType = z.enum(['pm2', 'docker', 'compose']);
|
|
4
4
|
export const buildPack = z.enum(['auto', 'nixpacks', 'dockerfile']);
|
|
5
|
+
/** Optional project/workspace/label tag IDs for new service creation. */
|
|
6
|
+
const tagIds = z.array(z.number().int().positive()).optional();
|
|
5
7
|
export const createService = z.object({
|
|
6
|
-
|
|
8
|
+
/** Bundled/remote Hub template ID. The server resolves privileged template
|
|
9
|
+
* settings (cmd, Docker socket and database env mapping) from the trusted
|
|
10
|
+
* registry; clients cannot submit those settings directly. */
|
|
11
|
+
templateId: z.string().min(1).max(100).optional(),
|
|
12
|
+
/**
|
|
13
|
+
* Project / workspace / label tagging (N-N). `tagProjectIds` replaces the
|
|
14
|
+
* removed `projectId` field. `tagWorkspaceIds` defaults to all workspaces
|
|
15
|
+
* the caller belongs to when omitted (so a freshly-created service is
|
|
16
|
+
* visible from the operator's workspaces). `tagLabelIds` is optional.
|
|
17
|
+
*/
|
|
18
|
+
tagProjectIds: tagIds,
|
|
19
|
+
tagWorkspaceIds: tagIds,
|
|
20
|
+
tagLabelIds: tagIds,
|
|
7
21
|
name: z.string().min(1).max(100),
|
|
8
22
|
slug: slug.optional(), // derived from name if omitted
|
|
23
|
+
/** Resume an idle, caller-owned service left by an interrupted Hub deploy. */
|
|
24
|
+
reuseExisting: z.boolean().optional(),
|
|
9
25
|
type: serviceType.default('docker'),
|
|
10
26
|
repoUrl: gitRepoUrl.optional(),
|
|
11
27
|
branch: gitBranch.default('main'),
|
|
@@ -28,11 +44,11 @@ export const createService = z.object({
|
|
|
28
44
|
build: z
|
|
29
45
|
.object({
|
|
30
46
|
buildPack: buildPack.default('auto'),
|
|
31
|
-
baseDir:
|
|
47
|
+
baseDir: repoBaseDir.default('/'),
|
|
32
48
|
installCmd: z.string().optional(),
|
|
33
49
|
buildCmd: z.string().optional(),
|
|
34
50
|
startCmd: z.string().optional(),
|
|
35
|
-
dockerfilePath:
|
|
51
|
+
dockerfilePath: repoRelativePath.optional(),
|
|
36
52
|
preDeployCmd: z.string().nullable().optional(),
|
|
37
53
|
postDeployCmd: z.string().nullable().optional(),
|
|
38
54
|
preStopCmd: z.string().nullable().optional(),
|
|
@@ -48,13 +64,19 @@ export const createService = z.object({
|
|
|
48
64
|
* still applies `.default()` values for absent keys, which would silently
|
|
49
65
|
* rewrite `type` back to 'docker' and `branch` to 'main' on every PATCH. */
|
|
50
66
|
export const updateService = z.object({
|
|
51
|
-
|
|
67
|
+
// Tag updates are usually handled by `PUT /v1/services/:id/tags`; these
|
|
68
|
+
// convenience fields let a single PATCH reassign tags together with other
|
|
69
|
+
// service edits without an extra round-trip.
|
|
70
|
+
tagProjectIds: tagIds,
|
|
71
|
+
tagWorkspaceIds: tagIds,
|
|
72
|
+
tagLabelIds: tagIds,
|
|
52
73
|
name: z.string().min(1).max(100).optional(),
|
|
53
74
|
slug: slug.optional(),
|
|
54
75
|
type: serviceType.optional(),
|
|
55
76
|
repoUrl: gitRepoUrl.optional(),
|
|
56
77
|
branch: gitBranch.optional(),
|
|
57
|
-
|
|
78
|
+
/** Attached Git credential (source) for private-repo cloning. null clears it. */
|
|
79
|
+
sourceId: z.number().int().positive().nullable().optional(),
|
|
58
80
|
serverId: z.number().int().positive().nullable().optional(),
|
|
59
81
|
image: z.string().optional(),
|
|
60
82
|
volumeMount: z.string().optional(),
|
|
@@ -71,11 +93,11 @@ export const updateService = z.object({
|
|
|
71
93
|
build: z
|
|
72
94
|
.object({
|
|
73
95
|
buildPack: buildPack.optional(),
|
|
74
|
-
baseDir:
|
|
96
|
+
baseDir: repoBaseDir.optional(),
|
|
75
97
|
installCmd: z.string().optional(),
|
|
76
98
|
buildCmd: z.string().optional(),
|
|
77
99
|
startCmd: z.string().optional(),
|
|
78
|
-
dockerfilePath:
|
|
100
|
+
dockerfilePath: repoRelativePath.optional(),
|
|
79
101
|
preDeployCmd: z.string().nullable().optional(),
|
|
80
102
|
postDeployCmd: z.string().nullable().optional(),
|
|
81
103
|
preStopCmd: z.string().nullable().optional(),
|
|
@@ -86,7 +108,24 @@ export const updateService = z.object({
|
|
|
86
108
|
});
|
|
87
109
|
export const service = z.object({
|
|
88
110
|
id: z.number().int(),
|
|
89
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Project / workspace / label tag lists (N-N). The legacy single
|
|
113
|
+
* `projectId` field is gone; consumers compose the three arrays to decide
|
|
114
|
+
* what shows up in the top-bar filter chips.
|
|
115
|
+
*/
|
|
116
|
+
projectIds: z.array(z.number().int()),
|
|
117
|
+
workspaceIds: z.array(z.number().int()),
|
|
118
|
+
labelIds: z.array(z.number().int()),
|
|
119
|
+
/** Resolved display objects — present on detail responses, may be omitted on list. */
|
|
120
|
+
projects: z
|
|
121
|
+
.array(z.object({ id: z.number().int(), name: z.string(), slug: z.string() }))
|
|
122
|
+
.optional(),
|
|
123
|
+
workspaces: z
|
|
124
|
+
.array(z.object({ id: z.number().int(), name: z.string(), slug: z.string() }))
|
|
125
|
+
.optional(),
|
|
126
|
+
labels: z
|
|
127
|
+
.array(z.object({ id: z.number().int(), name: z.string(), color: z.string() }))
|
|
128
|
+
.optional(),
|
|
90
129
|
serverId: z.number().int().nullable().optional(),
|
|
91
130
|
name: z.string(),
|
|
92
131
|
slug: z.string(),
|
|
@@ -95,6 +134,8 @@ export const service = z.object({
|
|
|
95
134
|
repoUrl: z.string().nullable(),
|
|
96
135
|
branch: z.string(),
|
|
97
136
|
sourceId: z.number().int().nullable(),
|
|
137
|
+
/** Display name of the attached Git credential (source), for the UI. */
|
|
138
|
+
sourceName: z.string().nullable().optional(),
|
|
98
139
|
image: z.string().nullable(),
|
|
99
140
|
volumeMount: z.string().nullable(),
|
|
100
141
|
composeService: z.string().nullable(),
|
|
@@ -147,8 +188,10 @@ export const source = z.object({
|
|
|
147
188
|
type: z.string(),
|
|
148
189
|
hasToken: z.boolean(),
|
|
149
190
|
hasDeployKey: z.boolean(),
|
|
191
|
+
registryUsername: z.string().nullable().optional(),
|
|
150
192
|
defaultBranch: z.string().nullable(),
|
|
151
193
|
createdAt: z.string().datetime(),
|
|
194
|
+
updatedAt: z.string().datetime().optional(),
|
|
152
195
|
});
|
|
153
196
|
export const triggerDeploy = z.object({
|
|
154
197
|
commitSha: z.string().optional(),
|
|
@@ -220,6 +263,7 @@ export const webhook = z.object({
|
|
|
220
263
|
branch: z.string(),
|
|
221
264
|
active: z.boolean(),
|
|
222
265
|
watchPaths: z.string(),
|
|
266
|
+
sourceId: z.number().int().nullable().optional(),
|
|
223
267
|
url: z.string(),
|
|
224
268
|
createdAt: z.string().datetime(),
|
|
225
269
|
});
|
|
@@ -231,6 +275,9 @@ export const createDatabase = z.object({
|
|
|
231
275
|
engine: z.enum(['postgres', 'mysql', 'mariadb', 'redis', 'mongo', 'valkey', 'clickhouse', 'meilisearch', 'rabbitmq']),
|
|
232
276
|
version: z.string().optional(),
|
|
233
277
|
projectId: z.number().int().optional(),
|
|
278
|
+
/** Hub/template provisioning is retryable: resume a matching database owned
|
|
279
|
+
* by the caller instead of colliding with the globally unique slug. */
|
|
280
|
+
reuseExisting: z.boolean().optional(),
|
|
234
281
|
existingVolume: z.string().optional(),
|
|
235
282
|
extensions: z.array(z.string()).optional(),
|
|
236
283
|
webGuiEnabled: z.boolean().optional(),
|
|
@@ -266,6 +313,7 @@ export const managedDatabase = z.object({
|
|
|
266
313
|
export const createAttachment = z.object({
|
|
267
314
|
databaseId: z.number().int().positive(),
|
|
268
315
|
envAlias: envVarName.optional(),
|
|
316
|
+
reuseExisting: z.boolean().optional(),
|
|
269
317
|
});
|
|
270
318
|
export const attachment = z.object({
|
|
271
319
|
id: z.number().int(),
|
|
@@ -278,6 +326,7 @@ export const upsertEnvVar = z.object({
|
|
|
278
326
|
key: envVarName.max(100),
|
|
279
327
|
value: z.string(),
|
|
280
328
|
isSecret: z.boolean().optional(),
|
|
329
|
+
overwriteExisting: z.boolean().optional(),
|
|
281
330
|
});
|
|
282
331
|
export const envVar = z.object({
|
|
283
332
|
id: z.number().int(),
|
|
@@ -285,6 +334,48 @@ export const envVar = z.object({
|
|
|
285
334
|
value: z.string(),
|
|
286
335
|
isSecret: z.boolean(),
|
|
287
336
|
});
|
|
337
|
+
// ── Service volume attachments ────────────────────────────────────────────
|
|
338
|
+
// A service can attach additional named Docker volumes in addition to its
|
|
339
|
+
// `volumeMount` primary. Either an existing managed volume (by name) or a
|
|
340
|
+
// fresh one created on demand. The volume persists across redeploys and
|
|
341
|
+
// container recreations — detaching only removes the link, not the data.
|
|
342
|
+
/** Create a new attachment. Exactly one of `volumeName` or `create.label`
|
|
343
|
+
* must be present — the former attaches an existing managed volume, the
|
|
344
|
+
* latter provisions a new one (system-generated name) and immediately
|
|
345
|
+
* attaches it. */
|
|
346
|
+
export const createServiceVolumeAttachment = z
|
|
347
|
+
.object({
|
|
348
|
+
// Attach an existing managed volume (must start with nd-svc- / nd-db-).
|
|
349
|
+
volumeName: dockerVolumeName.optional(),
|
|
350
|
+
// Provision a new named volume on attach. The label is a short
|
|
351
|
+
// human-friendly suffix (e.g. "uploads"); the server prepends the
|
|
352
|
+
// service-prefix to produce a unique managed name.
|
|
353
|
+
create: z.object({ label: z.string().min(1).max(40).regex(/^[a-z0-9][a-z0-9-]*$/i, 'invalid label') }).optional(),
|
|
354
|
+
containerPath: containerPath,
|
|
355
|
+
readOnly: z.boolean().optional(),
|
|
356
|
+
})
|
|
357
|
+
.refine((v) => Boolean(v.volumeName) !== Boolean(v.create?.label), {
|
|
358
|
+
message: 'Provide exactly one of volumeName or create.label',
|
|
359
|
+
});
|
|
360
|
+
/** PATCH shape — path and readOnly are optional, but at least one must change. */
|
|
361
|
+
export const updateServiceVolumeAttachment = z
|
|
362
|
+
.object({
|
|
363
|
+
containerPath: containerPath.optional(),
|
|
364
|
+
readOnly: z.boolean().optional(),
|
|
365
|
+
})
|
|
366
|
+
.refine((v) => v.containerPath !== undefined || v.readOnly !== undefined, {
|
|
367
|
+
message: 'Provide at least one of containerPath or readOnly',
|
|
368
|
+
});
|
|
369
|
+
/** API representation of a service's volume attachment. */
|
|
370
|
+
export const serviceVolumeAttachment = z.object({
|
|
371
|
+
id: z.number().int(),
|
|
372
|
+
serviceId: z.number().int(),
|
|
373
|
+
volumeName: z.string(),
|
|
374
|
+
containerPath: z.string(),
|
|
375
|
+
readOnly: z.boolean(),
|
|
376
|
+
createdAt: z.string().datetime(),
|
|
377
|
+
updatedAt: z.string().datetime(),
|
|
378
|
+
});
|
|
288
379
|
// ── Resource limits ───────────────────────────────────────────────────────
|
|
289
380
|
export const setLimits = z.object({
|
|
290
381
|
cpuShares: z.number().int().min(0).max(262144).nullable().optional(),
|
|
@@ -346,12 +437,21 @@ export const topologyGraph = z.object({
|
|
|
346
437
|
// ── Backups + storage ──────────────────────────────────────────────────────
|
|
347
438
|
export const backup = z.object({
|
|
348
439
|
id: z.number().int(),
|
|
440
|
+
// Exactly one of (databaseId, volumeName) is set — encoded by `scope`.
|
|
349
441
|
databaseId: z.number().int().nullable(),
|
|
442
|
+
volumeName: z.string().nullable(),
|
|
443
|
+
scope: z.enum(['db', 'volumes']),
|
|
350
444
|
status: z.string(),
|
|
351
445
|
sizeBytes: z.number().int(),
|
|
446
|
+
hasRemoteCopy: z.boolean().optional(),
|
|
352
447
|
createdAt: z.string().datetime(),
|
|
353
448
|
});
|
|
354
449
|
export const backupWithDb = backup.extend({ databaseName: z.string().nullable() });
|
|
450
|
+
/** Create a new volume backup. The `volumeName` is the route param; the
|
|
451
|
+
* body only carries the `label` for human-friendly file naming. */
|
|
452
|
+
export const createVolumeBackup = z.object({
|
|
453
|
+
label: z.string().min(1).max(80).optional(),
|
|
454
|
+
});
|
|
355
455
|
// ── Template hub ───────────────────────────────────────────────────────────
|
|
356
456
|
export const templateSummary = z.object({
|
|
357
457
|
id: z.string(),
|
|
@@ -360,6 +460,8 @@ export const templateSummary = z.object({
|
|
|
360
460
|
category: z.string(),
|
|
361
461
|
emoji: z.string(),
|
|
362
462
|
featured: z.boolean().optional(),
|
|
463
|
+
runtimeVerified: z.boolean().optional(),
|
|
464
|
+
verifiedAt: z.iso.date().optional(),
|
|
363
465
|
});
|
|
364
466
|
export const template = z.object({
|
|
365
467
|
id: z.string(),
|
|
@@ -375,11 +477,18 @@ export const template = z.object({
|
|
|
375
477
|
website: z.string().optional(),
|
|
376
478
|
docs: z.string().optional(),
|
|
377
479
|
featured: z.boolean().optional(),
|
|
480
|
+
/** Set only after the complete template contract has passed an isolated
|
|
481
|
+
* container startup and declared-port smoke test. */
|
|
482
|
+
runtimeVerified: z.boolean().optional(),
|
|
483
|
+
verifiedAt: z.iso.date().optional(),
|
|
378
484
|
/** Human hint about extra setup this template needs (shown in the Hub). */
|
|
379
485
|
requires: z.string().optional(),
|
|
380
486
|
/** When set, the wizard can auto-provision + attach a managed database of
|
|
381
|
-
* this engine
|
|
487
|
+
* this engine. databaseEnv controls the application-specific injection. */
|
|
382
488
|
dbEngine: z.enum(['postgres', 'mysql', 'mariadb', 'redis', 'valkey', 'mongo', 'clickhouse', 'meilisearch', 'rabbitmq']).optional(),
|
|
489
|
+
/** Map application-specific environment keys to managed database connection
|
|
490
|
+
* fields. Without this, attachments expose only their legacy URL alias. */
|
|
491
|
+
databaseEnv: z.record(envVarName, z.enum(['url', 'host', 'hostPort', 'port', 'username', 'password', 'database'])).optional(),
|
|
383
492
|
/** Container command (argv) appended after the image — needed by images
|
|
384
493
|
* whose default entrypoint prints help and exits (e.g. minio). */
|
|
385
494
|
cmd: z.array(z.string()).min(1).optional(),
|
|
@@ -387,6 +496,35 @@ export const template = z.object({
|
|
|
387
496
|
* only settable from the admin-controlled template registry, never via
|
|
388
497
|
* the create-service API). */
|
|
389
498
|
dockerSocket: z.boolean().optional(),
|
|
499
|
+
}).superRefine((value, ctx) => {
|
|
500
|
+
if (value.dbEngine && !value.databaseEnv) {
|
|
501
|
+
ctx.addIssue({
|
|
502
|
+
code: 'custom',
|
|
503
|
+
path: ['databaseEnv'],
|
|
504
|
+
message: 'databaseEnv is required when dbEngine is set',
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
/**
|
|
509
|
+
* One canonical Hub installation request. Image, internal port, volume,
|
|
510
|
+
* command, Docker socket and database mapping are intentionally absent: they
|
|
511
|
+
* are privileged registry-owned fields resolved by the server.
|
|
512
|
+
*/
|
|
513
|
+
export const deployTemplate = z.object({
|
|
514
|
+
name: z.string().trim().min(1).max(100).optional(),
|
|
515
|
+
projectId: z.number().int().positive().optional(),
|
|
516
|
+
serverId: z.number().int().positive().nullable().optional(),
|
|
517
|
+
publishedPort: z.number().int().min(1).max(65535).nullable().optional(),
|
|
518
|
+
healthPath: httpPath.optional(),
|
|
519
|
+
cpuShares: z.number().int().min(0).max(262144).optional(),
|
|
520
|
+
memLimitMb: z.number().int().min(0).optional(),
|
|
521
|
+
env: z.array(z.object({
|
|
522
|
+
key: envVarName,
|
|
523
|
+
value: z.string().max(32_768),
|
|
524
|
+
isSecret: z.boolean().optional().default(false),
|
|
525
|
+
})).max(200).optional(),
|
|
526
|
+
/** Reconcile an interrupted caller-owned install with the same slug. */
|
|
527
|
+
reuseExisting: z.boolean().optional().default(true),
|
|
390
528
|
});
|
|
391
529
|
// ── Domain routing index + volumes ─────────────────────────────────────────
|
|
392
530
|
export const domainEntry = z.object({
|