@highstate/backend 0.9.15 → 0.9.16
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/chunk-RCB4AFGD.js +159 -0
- package/dist/chunk-RCB4AFGD.js.map +1 -0
- package/dist/chunk-WHALQHEZ.js +2017 -0
- package/dist/chunk-WHALQHEZ.js.map +1 -0
- package/dist/highstate.manifest.json +3 -3
- package/dist/index.js +6158 -2178
- package/dist/index.js.map +1 -1
- package/dist/library/worker/main.js +47 -155
- package/dist/library/worker/main.js.map +1 -1
- package/dist/shared/index.js +159 -41
- package/package.json +25 -7
- package/src/artifact/abstractions.ts +46 -0
- package/src/artifact/encryption.ts +69 -0
- package/src/artifact/factory.ts +36 -0
- package/src/artifact/index.ts +3 -0
- package/src/artifact/local.ts +142 -0
- package/src/business/api-key.ts +65 -0
- package/src/business/artifact.ts +288 -0
- package/src/business/backend-unlock.ts +10 -0
- package/src/business/index.ts +9 -0
- package/src/business/instance-lock.ts +124 -0
- package/src/business/instance-state.ts +292 -0
- package/src/business/operation.ts +251 -0
- package/src/business/project-unlock.ts +242 -0
- package/src/business/secret.ts +187 -0
- package/src/business/worker.ts +161 -0
- package/src/common/index.ts +2 -1
- package/src/common/performance.ts +44 -0
- package/src/common/tree.ts +33 -0
- package/src/common/utils.ts +40 -1
- package/src/config.ts +14 -10
- package/src/hotstate/abstractions.ts +48 -0
- package/src/hotstate/factory.ts +17 -0
- package/src/{secret → hotstate}/index.ts +1 -0
- package/src/hotstate/manager.ts +192 -0
- package/src/hotstate/memory.ts +100 -0
- package/src/hotstate/validation.ts +101 -0
- package/src/index.ts +2 -1
- package/src/library/abstractions.ts +10 -23
- package/src/library/factory.ts +2 -2
- package/src/library/local.ts +89 -102
- package/src/library/worker/evaluator.ts +9 -42
- package/src/library/worker/loader.lite.ts +41 -0
- package/src/library/worker/main.ts +14 -65
- package/src/library/worker/protocol.ts +8 -24
- package/src/lock/abstractions.ts +6 -0
- package/src/lock/factory.ts +15 -0
- package/src/{workspace → lock}/index.ts +1 -0
- package/src/lock/manager.ts +82 -0
- package/src/lock/memory.ts +19 -0
- package/src/orchestrator/manager.ts +129 -82
- package/src/orchestrator/operation-workset.ts +168 -77
- package/src/orchestrator/operation.ts +967 -284
- package/src/project/abstractions.ts +20 -7
- package/src/project/factory.ts +1 -1
- package/src/project/index.ts +0 -1
- package/src/project/local.ts +73 -17
- package/src/project/manager.ts +272 -131
- package/src/pubsub/abstractions.ts +13 -0
- package/src/pubsub/factory.ts +19 -0
- package/src/pubsub/index.ts +3 -0
- package/src/pubsub/local.ts +36 -0
- package/src/pubsub/manager.ts +100 -0
- package/src/pubsub/validation.ts +33 -0
- package/src/runner/abstractions.ts +135 -68
- package/src/runner/artifact-env.ts +160 -0
- package/src/runner/factory.ts +20 -5
- package/src/runner/force-abort.ts +117 -0
- package/src/runner/local.ts +281 -371
- package/src/{common → runner}/pulumi.ts +86 -37
- package/src/services.ts +193 -35
- package/src/shared/index.ts +3 -11
- package/src/shared/models/backend/index.ts +3 -0
- package/src/shared/models/backend/project.ts +63 -0
- package/src/shared/models/backend/unlock-method.ts +20 -0
- package/src/shared/models/base.ts +151 -0
- package/src/shared/models/errors.ts +5 -0
- package/src/shared/models/index.ts +4 -0
- package/src/shared/models/project/api-key.ts +62 -0
- package/src/shared/models/project/artifact.ts +113 -0
- package/src/shared/models/project/component.ts +45 -0
- package/src/shared/models/project/index.ts +14 -0
- package/src/shared/{project.ts → models/project/instance.ts} +12 -0
- package/src/shared/models/project/lock.ts +91 -0
- package/src/shared/{operation.ts → models/project/operation.ts} +28 -7
- package/src/shared/models/project/page.ts +57 -0
- package/src/shared/models/project/secret.ts +112 -0
- package/src/shared/models/project/service-account.ts +22 -0
- package/src/shared/models/project/state.ts +432 -0
- package/src/shared/models/project/terminal.ts +99 -0
- package/src/shared/models/project/trigger.ts +56 -0
- package/src/shared/models/project/unlock-method.ts +31 -0
- package/src/shared/models/project/worker.ts +105 -0
- package/src/shared/resolvers/graph-resolver.ts +28 -0
- package/src/shared/resolvers/index.ts +5 -0
- package/src/shared/resolvers/input-hash.ts +53 -15
- package/src/shared/resolvers/input.ts +1 -9
- package/src/shared/resolvers/registry.ts +3 -2
- package/src/shared/resolvers/state.ts +2 -2
- package/src/shared/resolvers/validation.ts +61 -20
- package/src/shared/{async-batcher.ts → utils/async-batcher.ts} +13 -1
- package/src/shared/utils/hash.ts +6 -0
- package/src/shared/utils/index.ts +3 -0
- package/src/shared/utils/promise-tracker.ts +23 -0
- package/src/state/abstractions.ts +330 -101
- package/src/state/encryption.ts +59 -0
- package/src/state/factory.ts +3 -5
- package/src/state/index.ts +3 -0
- package/src/state/keyring.ts +22 -0
- package/src/state/local/backend.ts +299 -0
- package/src/state/local/collection.ts +342 -0
- package/src/state/local/index.ts +2 -0
- package/src/state/manager.ts +804 -18
- package/src/state/repository/index.ts +2 -0
- package/src/state/repository/repository.index.ts +193 -0
- package/src/state/repository/repository.ts +458 -0
- package/src/terminal/{shared.ts → abstractions.ts} +3 -3
- package/src/terminal/docker.ts +18 -14
- package/src/terminal/factory.ts +3 -3
- package/src/terminal/index.ts +1 -1
- package/src/terminal/manager.ts +131 -79
- package/src/terminal/run.sh.ts +21 -11
- package/src/worker/abstractions.ts +42 -0
- package/src/worker/docker.ts +83 -0
- package/src/worker/factory.ts +20 -0
- package/src/worker/index.ts +3 -0
- package/src/worker/manager.ts +139 -0
- package/dist/chunk-KTGKNSKM.js +0 -979
- package/dist/chunk-KTGKNSKM.js.map +0 -1
- package/dist/chunk-WXDYCRTT.js +0 -234
- package/dist/chunk-WXDYCRTT.js.map +0 -1
- package/src/library/worker/loader.ts +0 -114
- package/src/preferences/shared.ts +0 -1
- package/src/project/lock.ts +0 -39
- package/src/secret/abstractions.ts +0 -59
- package/src/secret/factory.ts +0 -22
- package/src/secret/local.ts +0 -152
- package/src/shared/state.ts +0 -247
- package/src/shared/terminal.ts +0 -14
- package/src/state/local.ts +0 -612
- package/src/workspace/abstractions.ts +0 -41
- package/src/workspace/factory.ts +0 -14
- package/src/workspace/local.ts +0 -54
- /package/src/shared/{library.ts → models/backend/library.ts} +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
|
|
3
|
+
export const userObjectMetaSchema = z.object({
|
|
4
|
+
/**
|
|
5
|
+
* Human-readable name of the object.
|
|
6
|
+
*
|
|
7
|
+
* Used in UI components for better user experience.
|
|
8
|
+
*/
|
|
9
|
+
title: z.string().optional(),
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The title used globally for the object.
|
|
13
|
+
*
|
|
14
|
+
* For example, the title of an instance secret is "Password" which is okay
|
|
15
|
+
* to display in the instance secret list, but when the secret is displayed in a
|
|
16
|
+
* global secret list the name should be more descriptive, like "Proxmox Password".
|
|
17
|
+
*/
|
|
18
|
+
globalTitle: z.string().optional(),
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Description of the object.
|
|
22
|
+
*
|
|
23
|
+
* Provides additional context for users and developers.
|
|
24
|
+
*/
|
|
25
|
+
description: z.string().optional(),
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The color of the object.
|
|
29
|
+
*
|
|
30
|
+
* Used in UI components to visually distinguish objects.
|
|
31
|
+
*/
|
|
32
|
+
color: z.string().optional(),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Primary icon identifier.
|
|
36
|
+
*
|
|
37
|
+
* Should reference a iconify icon name, like "mdi:server" or "gg:remote".
|
|
38
|
+
*/
|
|
39
|
+
icon: z.string().optional(),
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The color of the primary icon.
|
|
43
|
+
*/
|
|
44
|
+
iconColor: z.string().optional(),
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The secondary icon identifier.
|
|
48
|
+
*
|
|
49
|
+
* Used to provide additional context or actions related to the object.
|
|
50
|
+
*
|
|
51
|
+
* Should reference a iconify icon name, like "mdi:edit" or "mdi:delete".
|
|
52
|
+
*/
|
|
53
|
+
secondaryIcon: z.string().optional(),
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The color of the secondary icon.
|
|
57
|
+
*/
|
|
58
|
+
secondaryIconColor: z.string().optional(),
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
export const objectMetaSchema = userObjectMetaSchema.extend({
|
|
62
|
+
/**
|
|
63
|
+
* Creation timestamp in milliseconds.
|
|
64
|
+
*
|
|
65
|
+
* Managed automatically by the system.
|
|
66
|
+
*/
|
|
67
|
+
createdAt: z.number().optional(),
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Last update timestamp in milliseconds.
|
|
71
|
+
*
|
|
72
|
+
* Managed automatically by the system.
|
|
73
|
+
*/
|
|
74
|
+
updatedAt: z.number().optional(),
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The optional version of the document to support optimistic concurrency control.
|
|
78
|
+
*
|
|
79
|
+
* Managed automatically by the system.
|
|
80
|
+
*/
|
|
81
|
+
version: z.number().optional(),
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
export type UserObjectMeta = z.infer<typeof userObjectMetaSchema>
|
|
85
|
+
export type ObjectMeta = z.infer<typeof objectMetaSchema>
|
|
86
|
+
|
|
87
|
+
export function hasObjectMeta(value: unknown): value is { meta: ObjectMeta } {
|
|
88
|
+
return typeof value === "object" && value !== null && "meta" in value
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const collectionQuerySchema = z.object({
|
|
92
|
+
/**
|
|
93
|
+
* The search string to filter documents by display name, description, or other text fields.
|
|
94
|
+
*
|
|
95
|
+
* Not implemented yet.
|
|
96
|
+
*/
|
|
97
|
+
search: z.string().optional(),
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The skip count for pagination.
|
|
101
|
+
*
|
|
102
|
+
* Cannot be used with `cursor`.
|
|
103
|
+
*/
|
|
104
|
+
skip: z.number().int().nonnegative().optional(),
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The sorting order for the results.
|
|
108
|
+
*
|
|
109
|
+
* By default, "asc" is used.
|
|
110
|
+
*/
|
|
111
|
+
sort: z.enum(["asc", "desc"]).default("asc"),
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The ID of the document to start the query from.
|
|
115
|
+
*
|
|
116
|
+
* If "asc" sorting is used, this will return results after this ID.
|
|
117
|
+
* Otherwise, it will return results before this ID.
|
|
118
|
+
*
|
|
119
|
+
* Cannot be used with `skip`.
|
|
120
|
+
*/
|
|
121
|
+
cursor: z.string().optional(),
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The count of documents to return.
|
|
125
|
+
*
|
|
126
|
+
* Defaults to 20 if not specified.
|
|
127
|
+
* Maximum value is 100.
|
|
128
|
+
*/
|
|
129
|
+
count: z.number().int().nonnegative().max(100).optional(),
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
export type CollectionQuery = z.infer<typeof collectionQuerySchema>
|
|
133
|
+
|
|
134
|
+
export type CollectionQueryResult<T> = {
|
|
135
|
+
/**
|
|
136
|
+
* The list of objects matching the query.
|
|
137
|
+
*/
|
|
138
|
+
items: T[]
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The total number of documents matching the query.
|
|
142
|
+
*/
|
|
143
|
+
total: number
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The cursor for the next page of results.
|
|
147
|
+
*
|
|
148
|
+
* If undefined, there are no more results.
|
|
149
|
+
*/
|
|
150
|
+
nextCursor?: string
|
|
151
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import { objectMetaSchema } from "../base"
|
|
3
|
+
|
|
4
|
+
export const instanceActionSchema = z.enum(["read", "write"])
|
|
5
|
+
export const serviceAccountActionSchema = z.enum(["full"])
|
|
6
|
+
|
|
7
|
+
export const projectAccessScope = z.discriminatedUnion("type", [
|
|
8
|
+
z.object({
|
|
9
|
+
type: z.literal("instance"),
|
|
10
|
+
actions: instanceActionSchema.array(),
|
|
11
|
+
instanceIds: z.string().array(),
|
|
12
|
+
}),
|
|
13
|
+
z.object({
|
|
14
|
+
type: z.literal("service-account"),
|
|
15
|
+
actions: serviceAccountActionSchema.array(),
|
|
16
|
+
serviceAccountIds: z.string().array(),
|
|
17
|
+
}),
|
|
18
|
+
])
|
|
19
|
+
|
|
20
|
+
export const projectApiKeySchema = z.object({
|
|
21
|
+
id: z.string().ulid(),
|
|
22
|
+
meta: objectMetaSchema,
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The 256-bit random token used to authenticate API requests.
|
|
26
|
+
*/
|
|
27
|
+
token: z.string(),
|
|
28
|
+
|
|
29
|
+
scopes: z.array(projectAccessScope),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
export type InstanceAction = z.infer<typeof instanceActionSchema>
|
|
33
|
+
export type ProjectAccessScope = z.infer<typeof projectAccessScope>
|
|
34
|
+
export type ProjectApiKey = z.infer<typeof projectApiKeySchema>
|
|
35
|
+
|
|
36
|
+
function hasAll<T>(array: T[], values: T[]): boolean {
|
|
37
|
+
return values.every(value => array.includes(value))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function validateInstanceAccess(
|
|
41
|
+
apiKey: ProjectApiKey,
|
|
42
|
+
actions: InstanceAction[],
|
|
43
|
+
instanceIds: string[],
|
|
44
|
+
): boolean {
|
|
45
|
+
return apiKey.scopes
|
|
46
|
+
.filter(scope => scope.type === "instance")
|
|
47
|
+
.some(scope => hasAll(scope.actions, actions) && hasAll(scope.instanceIds, instanceIds))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type ActionDescriptionMap<TType extends ProjectAccessScope["type"] = ProjectAccessScope["type"]> = {
|
|
51
|
+
[K in TType]: Record<(ProjectAccessScope & { type: K })["actions"][number], string>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const projectAccessActionDescriptions: ActionDescriptionMap = {
|
|
55
|
+
"service-account": {
|
|
56
|
+
full: "Full access to the service account and all resources owned by it and granted to it.",
|
|
57
|
+
},
|
|
58
|
+
instance: {
|
|
59
|
+
read: "Read access to the instance, including its state all resources owned by it.",
|
|
60
|
+
write: "Write access to the instance, including its state and all resources owned by it.",
|
|
61
|
+
},
|
|
62
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import {
|
|
3
|
+
HighstateSignature,
|
|
4
|
+
type File,
|
|
5
|
+
type FileContent,
|
|
6
|
+
type FileMeta,
|
|
7
|
+
type UnitArtifact,
|
|
8
|
+
} from "@highstate/contract"
|
|
9
|
+
import { objectMetaSchema, userObjectMetaSchema } from "../base"
|
|
10
|
+
|
|
11
|
+
export const artifactUsageSchema = z.discriminatedUnion("type", [
|
|
12
|
+
z.object({
|
|
13
|
+
type: z.literal("instance"),
|
|
14
|
+
instanceId: z.string(),
|
|
15
|
+
}),
|
|
16
|
+
z.object({
|
|
17
|
+
type: z.literal("terminal"),
|
|
18
|
+
terminalId: z.string(),
|
|
19
|
+
}),
|
|
20
|
+
z.object({
|
|
21
|
+
type: z.literal("service-account"),
|
|
22
|
+
serviceAccountId: z.string(),
|
|
23
|
+
}),
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
export type ArtifactUsage = z.infer<typeof artifactUsageSchema>
|
|
27
|
+
|
|
28
|
+
export function compareArtifactUsage(a: ArtifactUsage, b: ArtifactUsage): boolean {
|
|
29
|
+
if (a.type === "instance" && b.type === "instance") {
|
|
30
|
+
return a.instanceId === b.instanceId
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (a.type === "terminal" && b.type === "terminal") {
|
|
34
|
+
return a.terminalId === b.terminalId
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (a.type === "service-account" && b.type === "service-account") {
|
|
38
|
+
return a.serviceAccountId === b.serviceAccountId
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* File metadata schema.
|
|
46
|
+
*/
|
|
47
|
+
export const fileMetaSchema = z.object({
|
|
48
|
+
name: z.string(),
|
|
49
|
+
size: z.number().optional(),
|
|
50
|
+
isBinary: z.boolean().optional(),
|
|
51
|
+
mode: z.number().optional(),
|
|
52
|
+
}) satisfies z.ZodType<FileMeta>
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Complete artifact schema for database storage.
|
|
56
|
+
* Contains all artifact information.
|
|
57
|
+
*/
|
|
58
|
+
export const artifactSchema = z.object({
|
|
59
|
+
/**
|
|
60
|
+
* The UUIDv7 of the artifact generated when the artifact with unique content is first stored.
|
|
61
|
+
*/
|
|
62
|
+
id: z.string().uuid(),
|
|
63
|
+
|
|
64
|
+
meta: objectMetaSchema,
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The SHA-256 hash of the artifact content before encryption.
|
|
68
|
+
*/
|
|
69
|
+
hash: z.string(),
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The list of usages of this artifact.
|
|
73
|
+
*
|
|
74
|
+
* When became empty, the artifact is garbage collected.
|
|
75
|
+
*/
|
|
76
|
+
usages: artifactUsageSchema.array(),
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The size of the unencrypted artifact archive in bytes.
|
|
80
|
+
*/
|
|
81
|
+
size: z.number(),
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The size of each chunk of the artifact which independently encrypted.
|
|
85
|
+
*/
|
|
86
|
+
chunkSize: z.number(),
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
export type Artifact = z.infer<typeof artifactSchema>
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Artifact schema for unit API.
|
|
93
|
+
*/
|
|
94
|
+
export const unitArtifactSchema = z.object({
|
|
95
|
+
hash: z.string(),
|
|
96
|
+
meta: userObjectMetaSchema.optional(),
|
|
97
|
+
}) satisfies z.ZodType<UnitArtifact>
|
|
98
|
+
|
|
99
|
+
export const fileContentSchema = z.union([
|
|
100
|
+
z.object({
|
|
101
|
+
type: z.literal("embedded"),
|
|
102
|
+
value: z.string(),
|
|
103
|
+
}),
|
|
104
|
+
z.object({
|
|
105
|
+
type: z.literal("artifact"),
|
|
106
|
+
[HighstateSignature.Artifact]: unitArtifactSchema,
|
|
107
|
+
}),
|
|
108
|
+
]) satisfies z.ZodType<FileContent>
|
|
109
|
+
|
|
110
|
+
export const fileSchema = z.object({
|
|
111
|
+
meta: fileMetaSchema,
|
|
112
|
+
content: fileContentSchema,
|
|
113
|
+
}) satisfies z.ZodType<File>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
|
|
3
|
+
export const metaSchema = z.object({
|
|
4
|
+
displayName: z.string().optional(),
|
|
5
|
+
description: z.string().optional(),
|
|
6
|
+
color: z.string().optional(),
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
export const entitySchema = z.object({
|
|
10
|
+
type: z.string(),
|
|
11
|
+
schema: z.any(), // TSchema from TypeBox
|
|
12
|
+
meta: metaSchema,
|
|
13
|
+
definitionHash: z.string(),
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const componentMetaSchema = metaSchema.extend({
|
|
17
|
+
primaryIcon: z.string().optional(),
|
|
18
|
+
primaryIconColor: z.string().optional(),
|
|
19
|
+
secondaryIcon: z.string().optional(),
|
|
20
|
+
secondaryIconColor: z.string().optional(),
|
|
21
|
+
category: z.string().optional(),
|
|
22
|
+
defaultNamePrefix: z.string().optional(),
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
export const componentArgumentSchema = z.object({
|
|
26
|
+
schema: z.any(), // ArgumentValueSchema from TypeBox
|
|
27
|
+
required: z.boolean(),
|
|
28
|
+
meta: componentMetaSchema,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
export const componentInputSchema = z.object({
|
|
32
|
+
type: z.string(),
|
|
33
|
+
required: z.boolean(),
|
|
34
|
+
multiple: z.boolean(),
|
|
35
|
+
meta: componentMetaSchema,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
export const componentModelSchema = z.object({
|
|
39
|
+
type: z.string(),
|
|
40
|
+
args: z.record(componentArgumentSchema),
|
|
41
|
+
inputs: z.record(componentInputSchema),
|
|
42
|
+
outputs: z.record(componentInputSchema),
|
|
43
|
+
meta: componentMetaSchema,
|
|
44
|
+
definitionHash: z.string(),
|
|
45
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./instance"
|
|
2
|
+
export * from "./state"
|
|
3
|
+
export * from "./operation"
|
|
4
|
+
export * from "./terminal"
|
|
5
|
+
export * from "./page"
|
|
6
|
+
export * from "./artifact"
|
|
7
|
+
export * from "./trigger"
|
|
8
|
+
export * from "./unlock-method"
|
|
9
|
+
export * from "./secret"
|
|
10
|
+
export * from "./lock"
|
|
11
|
+
export * from "./component"
|
|
12
|
+
export * from "./service-account"
|
|
13
|
+
export * from "./worker"
|
|
14
|
+
export * from "./api-key"
|
|
@@ -38,11 +38,23 @@ export const instanceModelSchema = z.object({
|
|
|
38
38
|
export const compositeInstanceSchema = z.object({
|
|
39
39
|
instance: instanceModelSchema,
|
|
40
40
|
children: z.array(instanceModelSchema),
|
|
41
|
+
childCompositeInstanceIds: z.array(z.string()).optional(),
|
|
41
42
|
inputHash: z.string().optional(),
|
|
42
43
|
})
|
|
43
44
|
|
|
44
45
|
export type CompositeInstance = z.infer<typeof compositeInstanceSchema>
|
|
45
46
|
|
|
47
|
+
export const compositeInstanceEventSchema = z.discriminatedUnion("type", [
|
|
48
|
+
z.object({
|
|
49
|
+
type: z.literal("updated"),
|
|
50
|
+
instance: compositeInstanceSchema,
|
|
51
|
+
}),
|
|
52
|
+
z.object({
|
|
53
|
+
type: z.literal("deleted"),
|
|
54
|
+
instanceId: z.string(),
|
|
55
|
+
}),
|
|
56
|
+
])
|
|
57
|
+
|
|
46
58
|
export const hubModelPatchSchema = z.object({
|
|
47
59
|
position: positionSchema.optional(),
|
|
48
60
|
inputs: z.array(instanceInputSchema).optional(),
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import { objectMetaSchema } from "../base"
|
|
3
|
+
|
|
4
|
+
export const instanceLockSpecSchema = z.union([
|
|
5
|
+
z.object({
|
|
6
|
+
type: z.literal("operation"),
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The operation ID. Will be used to fetch the operation and detect whether it is still running or lost.
|
|
10
|
+
*/
|
|
11
|
+
operationId: z.string(),
|
|
12
|
+
}),
|
|
13
|
+
z.object({
|
|
14
|
+
type: z.literal("evaluation"),
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The internal evaluation ID that is used to detect lost evaluations and restart them.
|
|
18
|
+
*/
|
|
19
|
+
evaluationId: z.string(),
|
|
20
|
+
}),
|
|
21
|
+
z.object({
|
|
22
|
+
type: z.literal("custom"),
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The ID of the party that holds the lock.
|
|
26
|
+
*
|
|
27
|
+
* Each locker must only manage the locks it has created.
|
|
28
|
+
*/
|
|
29
|
+
lockerId: z.string(),
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The ID of the lock provided by the locker.
|
|
33
|
+
*
|
|
34
|
+
* Must be unique across all locks in the locker system.
|
|
35
|
+
*/
|
|
36
|
+
lockId: z.string(),
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The optional payload provided by the locker.
|
|
40
|
+
*
|
|
41
|
+
* Can be used to store additional information about the lock,
|
|
42
|
+
* like the ID of the lock in the locker system,
|
|
43
|
+
* or any other metadata that is relevant to the lock.
|
|
44
|
+
*/
|
|
45
|
+
payload: z.record(z.string()).optional(),
|
|
46
|
+
}),
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
export const instanceLockSchema = z.object({
|
|
50
|
+
id: z.string(),
|
|
51
|
+
meta: objectMetaSchema,
|
|
52
|
+
spec: instanceLockSpecSchema,
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
export type InstanceLock = z.infer<typeof instanceLockSchema>
|
|
56
|
+
export type InstanceLockSpec = z.infer<typeof instanceLockSpecSchema>
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Compares two instance lock specifications for equality.
|
|
60
|
+
*
|
|
61
|
+
* @param a The first instance lock specification to compare.
|
|
62
|
+
* @param b The second instance lock specification to compare.
|
|
63
|
+
*
|
|
64
|
+
* @returns True if both specifications are of the same type and have matching identifiers, false otherwise.
|
|
65
|
+
*/
|
|
66
|
+
export function compareInstanceLockSpecs(a: InstanceLockSpec, b: InstanceLockSpec): boolean {
|
|
67
|
+
if (a.type === "operation" && b.type === "operation") {
|
|
68
|
+
return a.operationId === b.operationId
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (a.type === "evaluation" && b.type === "evaluation") {
|
|
72
|
+
return a.evaluationId === b.evaluationId
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (a.type === "custom" && b.type === "custom") {
|
|
76
|
+
return a.lockerId === b.lockerId && a.lockId === b.lockId
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const instanceLockEventSchema = z.discriminatedUnion("type", [
|
|
83
|
+
z.object({
|
|
84
|
+
type: z.literal("locked"),
|
|
85
|
+
locks: z.array(instanceLockSchema),
|
|
86
|
+
}),
|
|
87
|
+
z.object({
|
|
88
|
+
type: z.literal("unlocked"),
|
|
89
|
+
instanceIds: z.array(z.string()),
|
|
90
|
+
}),
|
|
91
|
+
])
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod"
|
|
2
|
+
import { objectMetaSchema } from "../base"
|
|
2
3
|
|
|
3
4
|
export const operationTypeSchema = z.enum(["update", "preview", "destroy", "recreate", "refresh"])
|
|
4
5
|
|
|
@@ -8,6 +9,7 @@ export const operationStatusSchema = z.enum([
|
|
|
8
9
|
"completed",
|
|
9
10
|
"failed",
|
|
10
11
|
"cancelled",
|
|
12
|
+
"failing",
|
|
11
13
|
])
|
|
12
14
|
|
|
13
15
|
export const operationOptionsSchema = z.object({
|
|
@@ -81,18 +83,20 @@ export const operationOptionsSchema = z.object({
|
|
|
81
83
|
refresh: z.boolean().default(false),
|
|
82
84
|
})
|
|
83
85
|
|
|
84
|
-
export const
|
|
86
|
+
export const operationRequestSchema = z.object({
|
|
85
87
|
projectId: z.string(),
|
|
86
88
|
type: operationTypeSchema,
|
|
87
89
|
instanceIds: z.array(z.string()),
|
|
88
90
|
options: operationOptionsSchema.partial().optional(),
|
|
89
91
|
})
|
|
90
92
|
|
|
91
|
-
export const
|
|
93
|
+
export const operationSchema = z.object({
|
|
92
94
|
id: z.string().uuid(),
|
|
95
|
+
meta: objectMetaSchema,
|
|
93
96
|
status: operationStatusSchema,
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
error: z.string().nullable(),
|
|
99
|
+
|
|
96
100
|
type: operationTypeSchema,
|
|
97
101
|
|
|
98
102
|
requestedInstanceIds: z.array(z.string()),
|
|
@@ -100,19 +104,36 @@ export const projectOperationSchema = z.object({
|
|
|
100
104
|
instanceIdsToUpdate: z.array(z.string()).default(() => []),
|
|
101
105
|
instanceIdsToDestroy: z.array(z.string()).default(() => []),
|
|
102
106
|
|
|
103
|
-
options: operationOptionsSchema
|
|
107
|
+
options: operationOptionsSchema,
|
|
104
108
|
|
|
105
|
-
error: z.string().nullable(),
|
|
106
109
|
startedAt: z.number(),
|
|
107
110
|
completedAt: z.number().nullable(),
|
|
108
111
|
})
|
|
109
112
|
|
|
110
113
|
export type OperationType = z.infer<typeof operationTypeSchema>
|
|
111
114
|
export type OperationStatus = z.infer<typeof operationStatusSchema>
|
|
112
|
-
export type
|
|
113
|
-
export type
|
|
115
|
+
export type Operation = z.infer<typeof operationSchema>
|
|
116
|
+
export type OperationRequest = z.infer<typeof operationRequestSchema>
|
|
114
117
|
export type OperationOptions = z.infer<typeof operationOptionsSchema>
|
|
115
118
|
|
|
116
119
|
export function isFinalOperationStatus(status: OperationStatus): boolean {
|
|
117
120
|
return status === "completed" || status === "failed" || status === "cancelled"
|
|
118
121
|
}
|
|
122
|
+
|
|
123
|
+
export const operationLogEntrySchema = z.tuple([
|
|
124
|
+
z.string().uuid(), // UUIDv7
|
|
125
|
+
z.string(), // The log message
|
|
126
|
+
])
|
|
127
|
+
|
|
128
|
+
export type OperationLogEntry = z.infer<typeof operationLogEntrySchema>
|
|
129
|
+
|
|
130
|
+
export const operationEventSchema = z.discriminatedUnion("type", [
|
|
131
|
+
z.object({
|
|
132
|
+
type: z.literal("updated"),
|
|
133
|
+
operation: operationSchema,
|
|
134
|
+
}),
|
|
135
|
+
z.object({
|
|
136
|
+
type: z.literal("deleted"),
|
|
137
|
+
operationId: z.string(),
|
|
138
|
+
}),
|
|
139
|
+
])
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import { objectMetaSchema, userObjectMetaSchema } from "../base"
|
|
3
|
+
import { fileSchema } from "./artifact"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Page block schema for database storage and unit API.
|
|
7
|
+
*/
|
|
8
|
+
export const pageBlockSchema = z.union([
|
|
9
|
+
z.object({
|
|
10
|
+
type: z.literal("markdown"),
|
|
11
|
+
content: z.string(),
|
|
12
|
+
}),
|
|
13
|
+
z.object({
|
|
14
|
+
type: z.literal("qr"),
|
|
15
|
+
content: z.string(),
|
|
16
|
+
showContent: z.coerce.boolean(),
|
|
17
|
+
language: z.string().optional(),
|
|
18
|
+
}),
|
|
19
|
+
fileSchema.extend({
|
|
20
|
+
type: z.literal("file"),
|
|
21
|
+
}),
|
|
22
|
+
])
|
|
23
|
+
|
|
24
|
+
export type PageBlock = z.infer<typeof pageBlockSchema>
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Page info for frontend display.
|
|
28
|
+
* Contains only basic information visible to the frontend.
|
|
29
|
+
*/
|
|
30
|
+
export const pageSchema = z.object({
|
|
31
|
+
id: z.string(),
|
|
32
|
+
instanceId: z.string().optional(),
|
|
33
|
+
meta: objectMetaSchema,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export type Page = z.infer<typeof pageSchema>
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The content of a page separated from the page info.
|
|
40
|
+
*/
|
|
41
|
+
export const pageContentSchema = z.object({
|
|
42
|
+
id: z.string(),
|
|
43
|
+
content: z.array(pageBlockSchema),
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
export type PageContent = z.infer<typeof pageContentSchema>
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Page schema for unit API.
|
|
50
|
+
* This is what units provide - excludes id, instanceId and some fields from meta since those are set by the system.
|
|
51
|
+
*/
|
|
52
|
+
export const unitPageSchema = pageContentSchema.omit({ id: true }).extend({
|
|
53
|
+
name: z.string(),
|
|
54
|
+
meta: userObjectMetaSchema,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
export type UnitPage = z.infer<typeof unitPageSchema>
|