@highstate/backend 0.9.18 → 0.9.19
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-5WVU2AK4.js +1535 -0
- package/dist/chunk-5WVU2AK4.js.map +1 -0
- package/dist/{chunk-OU5OQBLB.js → chunk-I7BWSAN6.js} +3 -28
- package/dist/{chunk-OU5OQBLB.js.map → chunk-I7BWSAN6.js.map} +1 -1
- package/dist/chunk-VB4YL327.js +139 -0
- package/dist/chunk-VB4YL327.js.map +1 -0
- package/dist/database/local/prisma.config.js +26 -0
- package/dist/database/local/prisma.config.js.map +1 -0
- package/dist/highstate.manifest.json +2 -1
- package/dist/index.js +7587 -7291
- package/dist/index.js.map +1 -1
- package/dist/library/package-resolution-worker.js +1 -1
- package/dist/library/package-resolution-worker.js.map +1 -1
- package/dist/library/worker/main.js +35 -29
- package/dist/library/worker/main.js.map +1 -1
- package/dist/shared/index.js +2 -2
- package/package.json +18 -9
- package/prisma/backend/_schema/layout.prisma +7 -0
- package/prisma/backend/_schema/library.prisma +17 -0
- package/prisma/backend/_schema/project.prisma +101 -0
- package/prisma/backend/_schema/pulumi.prisma +17 -0
- package/prisma/backend/postgresql/main.prisma +17 -0
- package/prisma/backend/sqlite/main.prisma +17 -0
- package/prisma/backend/sqlite/migrations/20250817070609_initiial/migration.sql +34 -0
- package/prisma/backend/sqlite/migrations/20250817104948_add_fields/migration.sql +59 -0
- package/prisma/backend/sqlite/migrations/20250818082732_add_models/migration.sql +41 -0
- package/prisma/backend/sqlite/migrations/20250818083106_a/migration.sql +19 -0
- package/prisma/backend/sqlite/migrations/20250818101945_hi/migration.sql +1 -0
- package/prisma/backend/sqlite/migrations/20250819082315_a/migration.sql +5 -0
- package/prisma/backend/sqlite/migrations/migration_lock.toml +3 -0
- package/prisma/project/api-key.prisma +27 -0
- package/prisma/project/artifact.prisma +52 -0
- package/prisma/project/custom-status.prisma +46 -0
- package/prisma/project/evaluation.prisma +35 -0
- package/prisma/project/instance.prisma +160 -0
- package/prisma/project/layout.prisma +23 -0
- package/prisma/project/lock.prisma +18 -0
- package/prisma/project/main.prisma +17 -0
- package/prisma/project/migrations/20250816081310_initial/migration.sql +300 -0
- package/prisma/project/migrations/20250816082523_test/migration.sql +72 -0
- package/prisma/project/migrations/20250818065643_update/migration.sql +42 -0
- package/prisma/project/migrations/20250818070758_a/migration.sql +8 -0
- package/prisma/project/migrations/20250818070913_a/migration.sql +8 -0
- package/prisma/project/migrations/20250818082720_add_motels/migration.sql +11 -0
- package/prisma/project/migrations/20250818112523_hello/migration.sql +35 -0
- package/prisma/project/migrations/20250819082305_a/migration.sql +14 -0
- package/prisma/project/migrations/20250819165004_add_missing_fields/migration.sql +216 -0
- package/prisma/project/migrations/20250819171309_a/migration.sql +22 -0
- package/prisma/project/migrations/20250820113949_a/migration.sql +66 -0
- package/prisma/project/migrations/20250820144256_b/migration.sql +31 -0
- package/prisma/project/migrations/20250820145547_a/migration.sql +24 -0
- package/prisma/project/migrations/20250820182517_b/migration.sql +2 -0
- package/prisma/project/migrations/20250821172324_a/migration.sql +2 -0
- package/prisma/project/migrations/20250822081339_a/migration.sql +219 -0
- package/prisma/project/migrations/20250822083742_b/migration.sql +1 -0
- package/prisma/project/migrations/20250822105134_boom/migration.sql +1 -0
- package/prisma/project/migrations/20250822141028_b/migration.sql +1 -0
- package/prisma/project/migrations/20250822142342_b/migration.sql +16 -0
- package/prisma/project/migrations/20250824072720_a/migration.sql +1 -0
- package/prisma/project/migrations/20250824093656_b/migration.sql +21 -0
- package/prisma/project/migrations/20250825082518_a/migration.sql +1 -0
- package/prisma/project/migrations/20250825085343_b/migration.sql +1 -0
- package/prisma/project/migrations/20250825091312_a/migration.sql +1 -0
- package/prisma/project/migrations/20250903095431_hi/migration.sql +44 -0
- package/prisma/project/migrations/20250903174255_a/migration.sql +24 -0
- package/prisma/project/migrations/20250908095205_hi/migration.sql +18 -0
- package/prisma/project/migrations/20250909155857_hi/migration.sql +15 -0
- package/prisma/project/migrations/migration_lock.toml +3 -0
- package/prisma/project/model.prisma +37 -0
- package/prisma/project/operation.prisma +148 -0
- package/prisma/project/page.prisma +41 -0
- package/prisma/project/secret.prisma +42 -0
- package/prisma/project/service-account.prisma +36 -0
- package/prisma/project/terminal.prisma +90 -0
- package/prisma/project/trigger.prisma +31 -0
- package/prisma/project/unlock-method.prisma +32 -0
- package/prisma/project/worker.prisma +138 -0
- package/src/artifact/abstractions.ts +13 -13
- package/src/artifact/encryption.ts +30 -54
- package/src/artifact/factory.ts +6 -9
- package/src/artifact/local.ts +33 -46
- package/src/business/api-key.ts +24 -36
- package/src/business/artifact.test.ts +978 -0
- package/src/business/artifact.ts +136 -216
- package/src/business/evaluation.ts +328 -0
- package/src/business/index.ts +5 -2
- package/src/business/instance-lock.test.ts +1060 -0
- package/src/business/instance-lock.ts +387 -78
- package/src/business/instance-state.test.ts +735 -0
- package/src/business/instance-state.ts +582 -337
- package/src/business/operation.test.ts +439 -0
- package/src/business/operation.ts +174 -208
- package/src/business/project-model.ts +258 -0
- package/src/business/project-unlock.ts +168 -126
- package/src/business/project.ts +287 -179
- package/src/business/secret.test.ts +465 -130
- package/src/business/secret.ts +186 -217
- package/src/business/settings.test.ts +695 -0
- package/src/business/settings.ts +855 -0
- package/src/business/terminal-session.ts +90 -0
- package/src/business/unit-extra.test.ts +539 -0
- package/src/business/unit-extra.ts +160 -0
- package/src/business/worker.test.ts +356 -579
- package/src/business/worker.ts +238 -339
- package/src/common/codebase.ts +65 -0
- package/src/common/index.ts +3 -5
- package/src/common/logger.ts +5 -0
- package/src/common/utils.ts +4 -3
- package/src/config.ts +10 -11
- package/src/database/_generated/backend/postgresql/client.ts +72 -0
- package/src/database/_generated/backend/postgresql/commonInputTypes.ts +350 -0
- package/src/database/_generated/backend/postgresql/enums.ts +13 -0
- package/src/database/_generated/backend/postgresql/internal/class.ts +320 -0
- package/src/database/_generated/backend/postgresql/internal/prismaNamespace.ts +1238 -0
- package/src/database/_generated/backend/postgresql/models/Library.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/Project.ts +2175 -0
- package/src/database/_generated/backend/postgresql/models/ProjectModelStorage.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/ProjectSpace.ts +1602 -0
- package/src/database/_generated/backend/postgresql/models/PulumiBackend.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/UserWorkspaseLayout.ts +1065 -0
- package/src/database/_generated/backend/postgresql/models.ts +16 -0
- package/src/database/_generated/backend/postgresql/pjtg.ts +182 -0
- package/src/database/_generated/backend/sqlite/client.ts +72 -0
- package/src/database/_generated/backend/sqlite/commonInputTypes.ts +331 -0
- package/src/database/_generated/backend/sqlite/enums.ts +13 -0
- package/src/database/_generated/backend/sqlite/internal/class.ts +318 -0
- package/src/database/_generated/backend/sqlite/internal/prismaNamespace.ts +1207 -0
- package/src/database/_generated/backend/sqlite/models/Library.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/Project.ts +2169 -0
- package/src/database/_generated/backend/sqlite/models/ProjectModelStorage.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/ProjectSpace.ts +1599 -0
- package/src/database/_generated/backend/sqlite/models/PulumiBackend.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/UserWorkspaseLayout.ts +1063 -0
- package/src/database/_generated/backend/sqlite/models.ts +16 -0
- package/src/database/_generated/backend/sqlite/pjtg.ts +182 -0
- package/src/database/_generated/project/client.ts +204 -0
- package/src/database/_generated/project/commonInputTypes.ts +827 -0
- package/src/database/_generated/project/enums.ts +104 -0
- package/src/database/_generated/project/internal/class.ts +479 -0
- package/src/database/_generated/project/internal/prismaNamespace.ts +2974 -0
- package/src/database/_generated/project/models/ApiKey.ts +1506 -0
- package/src/database/_generated/project/models/Artifact.ts +2051 -0
- package/src/database/_generated/project/models/HubModel.ts +1125 -0
- package/src/database/_generated/project/models/InstanceCustomStatus.ts +1713 -0
- package/src/database/_generated/project/models/InstanceEvaluationState.ts +1312 -0
- package/src/database/_generated/project/models/InstanceLock.ts +1268 -0
- package/src/database/_generated/project/models/InstanceModel.ts +1125 -0
- package/src/database/_generated/project/models/InstanceOperationState.ts +1707 -0
- package/src/database/_generated/project/models/InstanceState.ts +4613 -0
- package/src/database/_generated/project/models/Operation.ts +1647 -0
- package/src/database/_generated/project/models/OperationLog.ts +1455 -0
- package/src/database/_generated/project/models/Page.ts +1838 -0
- package/src/database/_generated/project/models/Secret.ts +1692 -0
- package/src/database/_generated/project/models/ServiceAccount.ts +2165 -0
- package/src/database/_generated/project/models/Terminal.ts +2038 -0
- package/src/database/_generated/project/models/TerminalSession.ts +1454 -0
- package/src/database/_generated/project/models/TerminalSessionLog.ts +1280 -0
- package/src/database/_generated/project/models/Trigger.ts +1430 -0
- package/src/database/_generated/project/models/UnlockMethod.ts +1220 -0
- package/src/database/_generated/project/models/UserCompositeViewport.ts +1280 -0
- package/src/database/_generated/project/models/UserProjectViewport.ts +1059 -0
- package/src/database/_generated/project/models/Worker.ts +1459 -0
- package/src/database/_generated/project/models/WorkerUnitRegistration.ts +1524 -0
- package/src/database/_generated/project/models/WorkerVersion.ts +1974 -0
- package/src/database/_generated/project/models/WorkerVersionLog.ts +1318 -0
- package/src/database/_generated/project/models.ts +35 -0
- package/src/database/_generated/project/pjtg.ts +182 -0
- package/src/database/abstractions.ts +19 -0
- package/src/database/factory.ts +37 -0
- package/src/database/index.ts +6 -0
- package/src/database/local/backend.ts +134 -0
- package/src/database/local/index.ts +3 -0
- package/src/database/local/meta.ts +46 -0
- package/src/database/local/prisma.config.ts +25 -0
- package/src/database/local/project.ts +39 -0
- package/src/database/manager.ts +181 -0
- package/src/database/migrate.ts +35 -0
- package/src/database/prisma.ts +56 -0
- package/src/database/well-known.ts +38 -0
- package/src/index.ts +4 -4
- package/src/library/abstractions.ts +3 -5
- package/src/library/factory.ts +1 -1
- package/src/library/local.ts +81 -26
- package/src/library/package-resolution-worker.ts +1 -1
- package/src/library/worker/evaluator.ts +40 -23
- package/src/library/worker/loader.lite.ts +1 -1
- package/src/library/worker/main.ts +3 -10
- package/src/library/worker/protocol.ts +0 -1
- package/src/lock/index.ts +0 -1
- package/src/lock/manager.ts +0 -10
- package/src/orchestrator/manager.ts +190 -104
- package/src/orchestrator/operation-context.ts +357 -0
- package/src/orchestrator/operation-plan.destroy.test.md +357 -0
- package/src/orchestrator/operation-plan.destroy.test.ts +775 -0
- package/src/orchestrator/operation-plan.fixtures.ts +213 -0
- package/src/orchestrator/operation-plan.md +198 -0
- package/src/orchestrator/operation-plan.refresh.test.md +199 -0
- package/src/orchestrator/operation-plan.refresh.test.ts +367 -0
- package/src/orchestrator/operation-plan.ts +709 -0
- package/src/orchestrator/operation-plan.update.test.md +485 -0
- package/src/orchestrator/operation-plan.update.test.ts +1066 -0
- package/src/orchestrator/operation-workset.ts +233 -578
- package/src/orchestrator/operation.ts +435 -948
- package/src/orchestrator/plan-test-builder.ts +267 -0
- package/src/project-model/abstractions.ts +118 -0
- package/src/project-model/backends/codebase.ts +365 -0
- package/src/project-model/backends/database.ts +440 -0
- package/src/project-model/errors.ts +81 -0
- package/src/project-model/factory.ts +24 -0
- package/src/project-model/index.ts +4 -0
- package/src/project-model/utils.test.ts +544 -0
- package/src/project-model/utils.ts +242 -0
- package/src/pubsub/abstractions.ts +10 -1
- package/src/pubsub/factory.ts +4 -4
- package/src/pubsub/index.ts +1 -0
- package/src/pubsub/manager.ts +29 -13
- package/src/pubsub/memory.ts +31 -0
- package/src/runner/abstractions.ts +33 -41
- package/src/runner/artifact-env.ts +19 -8
- package/src/runner/factory.ts +6 -6
- package/src/runner/force-abort.ts +3 -6
- package/src/runner/local.ts +64 -67
- package/src/runner/pulumi.ts +23 -63
- package/src/services.ts +181 -123
- package/src/shared/models/backend/index.ts +3 -1
- package/src/shared/models/backend/library.ts +9 -1
- package/src/shared/models/backend/project.ts +43 -42
- package/src/shared/models/backend/pulumi.ts +14 -0
- package/src/shared/models/backend/unlock-method.ts +1 -1
- package/src/shared/models/backend/well-known.ts +58 -0
- package/src/shared/models/base.ts +40 -26
- package/src/shared/models/errors.ts +82 -1
- package/src/shared/models/index.ts +3 -2
- package/src/shared/models/prisma.ts +36 -0
- package/src/shared/models/project/api-key.ts +37 -59
- package/src/shared/models/project/artifact.ts +16 -76
- package/src/shared/models/project/custom-status.ts +12 -0
- package/src/shared/models/project/index.ts +8 -7
- package/src/shared/models/project/lock.ts +10 -78
- package/src/shared/models/project/model.ts +19 -1
- package/src/shared/models/project/operation.ts +222 -99
- package/src/shared/models/project/page.ts +37 -48
- package/src/shared/models/project/secret.ts +29 -89
- package/src/shared/models/project/service-account.ts +12 -17
- package/src/shared/models/project/state.ts +100 -407
- package/src/shared/models/project/terminal.ts +75 -88
- package/src/shared/models/project/trigger.ts +13 -49
- package/src/shared/models/project/unlock-method.ts +20 -26
- package/src/shared/models/project/worker.ts +89 -90
- package/src/shared/resolvers/graph-resolver.ts +21 -0
- package/src/shared/resolvers/index.ts +1 -1
- package/src/shared/resolvers/input-hash.ts +24 -14
- package/src/shared/resolvers/input.ts +1 -1
- package/src/shared/resolvers/registry.ts +5 -4
- package/src/shared/resolvers/state.ts +12 -1
- package/src/shared/resolvers/validation.ts +7 -3
- package/src/shared/utils/index.ts +1 -2
- package/src/shared/utils/promise-tracker.ts +30 -3
- package/src/terminal/abstractions.ts +1 -1
- package/src/terminal/docker.ts +3 -3
- package/src/terminal/manager.ts +102 -118
- package/src/test-utils/database.ts +119 -0
- package/src/test-utils/index.ts +2 -0
- package/src/test-utils/services.ts +134 -0
- package/src/unlock/abstractions.ts +5 -23
- package/src/unlock/memory.ts +9 -14
- package/src/worker/abstractions.ts +7 -4
- package/src/worker/docker.ts +14 -19
- package/src/worker/manager.ts +366 -97
- package/dist/chunk-NAAIDR4U.js +0 -8499
- package/dist/chunk-NAAIDR4U.js.map +0 -1
- package/dist/chunk-Y7DXREVO.js +0 -1745
- package/dist/chunk-Y7DXREVO.js.map +0 -1
- package/dist/magic-string.es-5ABAC4JN.js +0 -1292
- package/dist/magic-string.es-5ABAC4JN.js.map +0 -1
- package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +0 -356
- package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +0 -274
- package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +0 -223
- package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +0 -147
- package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +0 -280
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +0 -360
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +0 -215
- package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +0 -427
- package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +0 -217
- package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +0 -132
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +0 -454
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +0 -426
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +0 -372
- package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +0 -383
- package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +0 -245
- package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +0 -174
- package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +0 -432
- package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +0 -220
- package/src/business/backend-unlock.ts +0 -10
- package/src/common/clock.ts +0 -18
- package/src/common/performance.ts +0 -44
- package/src/common/random.ts +0 -68
- package/src/common/test/index.ts +0 -2
- package/src/common/test/render.ts +0 -98
- package/src/common/test/tracer.ts +0 -359
- package/src/hotstate/abstractions.ts +0 -48
- package/src/hotstate/factory.ts +0 -17
- package/src/hotstate/index.ts +0 -3
- package/src/hotstate/manager.ts +0 -192
- package/src/hotstate/memory.ts +0 -100
- package/src/hotstate/validation.ts +0 -100
- package/src/lock/test.ts +0 -108
- package/src/project/abstractions.ts +0 -78
- package/src/project/evaluation.ts +0 -248
- package/src/project/factory.ts +0 -11
- package/src/project/index.ts +0 -3
- package/src/project/local.ts +0 -417
- package/src/pubsub/local.ts +0 -36
- package/src/pubsub/validation.ts +0 -33
- package/src/shared/utils/args.ts +0 -25
- package/src/state/abstractions.ts +0 -289
- package/src/state/encryption.ts +0 -98
- package/src/state/factory.ts +0 -20
- package/src/state/index.ts +0 -7
- package/src/state/local/backend.ts +0 -106
- package/src/state/local/collection.ts +0 -361
- package/src/state/local/index.ts +0 -2
- package/src/state/manager.ts +0 -890
- package/src/state/memory/backend.ts +0 -70
- package/src/state/memory/collection.ts +0 -270
- package/src/state/memory/index.ts +0 -2
- package/src/state/repository/index.ts +0 -2
- package/src/state/repository/repository.index.ts +0 -193
- package/src/state/repository/repository.ts +0 -507
- package/src/state/test.ts +0 -457
- /package/src/{state → database/local}/keyring.ts +0 -0
|
@@ -0,0 +1,1535 @@
|
|
|
1
|
+
import { z, commonObjectMetaSchema, genericNameSchema, timestampsSchema, objectMetaSchema, serviceAccountMetaSchema, instanceIdSchema, instanceModelSchema, hubModelSchema, pageBlockSchema, globalCommonObjectMetaSchema, terminalSpecSchema, isUnitModel, parseArgumentValue } from '@highstate/contract';
|
|
2
|
+
import { z as z$1 } from 'zod';
|
|
3
|
+
import { mapValues, constant, unique, fromEntries } from 'remeda';
|
|
4
|
+
import { crc32 } from '@aws-crypto/crc32';
|
|
5
|
+
import { encode } from '@msgpack/msgpack';
|
|
6
|
+
import { Ajv } from 'ajv';
|
|
7
|
+
import styles from 'ansi-styles';
|
|
8
|
+
|
|
9
|
+
// src/shared/models/backend/library.ts
|
|
10
|
+
var librarySpecSchema = z.discriminatedUnion("type", [
|
|
11
|
+
z.object({
|
|
12
|
+
type: z.literal("host")
|
|
13
|
+
})
|
|
14
|
+
]);
|
|
15
|
+
function diffLibraries(oldLibrary, newLibrary) {
|
|
16
|
+
const updates = [];
|
|
17
|
+
for (const [componentType, newComponent] of Object.entries(newLibrary.components)) {
|
|
18
|
+
const existingComponent = oldLibrary.components[componentType];
|
|
19
|
+
if (existingComponent?.definitionHash !== newComponent.definitionHash) {
|
|
20
|
+
updates.push({ type: "component-updated", component: newComponent });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
for (const componentType of Object.keys(oldLibrary.components)) {
|
|
24
|
+
if (!newLibrary.components[componentType]) {
|
|
25
|
+
updates.push({ type: "component-removed", componentType });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const [entityType, newEntity] of Object.entries(newLibrary.entities)) {
|
|
29
|
+
const existingEntity = oldLibrary.entities[entityType];
|
|
30
|
+
if (existingEntity?.definitionHash !== newEntity.definitionHash) {
|
|
31
|
+
updates.push({ type: "entity-updated", entity: newEntity });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (const entityType of Object.keys(oldLibrary.entities)) {
|
|
35
|
+
if (!newLibrary.entities[entityType]) {
|
|
36
|
+
updates.push({ type: "entity-removed", entityType });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return updates;
|
|
40
|
+
}
|
|
41
|
+
function applyLibraryUpdate(components, entities, update) {
|
|
42
|
+
switch (update.type) {
|
|
43
|
+
case "component-updated":
|
|
44
|
+
components[update.component.type] = update.component;
|
|
45
|
+
break;
|
|
46
|
+
case "entity-updated":
|
|
47
|
+
entities[update.entity.type] = update.entity;
|
|
48
|
+
break;
|
|
49
|
+
case "component-removed":
|
|
50
|
+
delete components[update.componentType];
|
|
51
|
+
break;
|
|
52
|
+
case "entity-removed":
|
|
53
|
+
delete entities[update.entityType];
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/shared/models/backend/well-known.ts
|
|
59
|
+
var globalProjectSpace = {
|
|
60
|
+
id: "q8xbilhwpsn65zjlv5kz44qh",
|
|
61
|
+
meta: {
|
|
62
|
+
title: "Global Project Space",
|
|
63
|
+
description: "The default project space for all projects.",
|
|
64
|
+
icon: "mdi-earth",
|
|
65
|
+
iconColor: "#4CAF50"
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var codebaseLibrary = {
|
|
69
|
+
id: "n0rfvpl9o77iqf29ff4kk5gf",
|
|
70
|
+
meta: {
|
|
71
|
+
title: "Codebase Library",
|
|
72
|
+
description: "The library which loads components and entities from packages (local or NPM-installed) in the codebase.",
|
|
73
|
+
icon: "mdi-package-variant",
|
|
74
|
+
iconColor: "#2196F3"
|
|
75
|
+
},
|
|
76
|
+
spec: { type: "host" }
|
|
77
|
+
};
|
|
78
|
+
var hostPulumiBackend = {
|
|
79
|
+
id: "pmn9y901jeiz2ydh93045l39",
|
|
80
|
+
meta: {
|
|
81
|
+
title: "Host Pulumi Backend",
|
|
82
|
+
description: "The Pulumi backend which will always use the Pulumi CLI configured on the host."
|
|
83
|
+
},
|
|
84
|
+
spec: { type: "host" }
|
|
85
|
+
};
|
|
86
|
+
var codebaseProjectModelStorage = {
|
|
87
|
+
id: "qppfcerovu3h22o0x8rlpc3g",
|
|
88
|
+
meta: {
|
|
89
|
+
title: "Codebase Model Storage",
|
|
90
|
+
description: "The storage which stores project model in the codebase.",
|
|
91
|
+
icon: "mdi-code-json"
|
|
92
|
+
},
|
|
93
|
+
spec: { type: "codebase" }
|
|
94
|
+
};
|
|
95
|
+
var databaseProjectModelStorage = {
|
|
96
|
+
id: "rmi0hmo1tjjsyfry9l178fus",
|
|
97
|
+
meta: {
|
|
98
|
+
title: "Database Model Storage",
|
|
99
|
+
description: "The storage which stores project model in the database alongside the project state.",
|
|
100
|
+
icon: "mdi-database"
|
|
101
|
+
},
|
|
102
|
+
spec: { type: "database" }
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// src/shared/models/backend/project.ts
|
|
106
|
+
var projectModelStorageSpecSchema = z.discriminatedUnion("type", [
|
|
107
|
+
z.object({
|
|
108
|
+
/**
|
|
109
|
+
* The project model is stored in the codebase where Highstate is running.
|
|
110
|
+
*/
|
|
111
|
+
type: z.literal("codebase")
|
|
112
|
+
}),
|
|
113
|
+
z.object({
|
|
114
|
+
/**
|
|
115
|
+
* The project model is stored in the project database alongside the project data.
|
|
116
|
+
*/
|
|
117
|
+
type: z.literal("database")
|
|
118
|
+
})
|
|
119
|
+
]);
|
|
120
|
+
var projectInputSchema = z.object({
|
|
121
|
+
name: genericNameSchema,
|
|
122
|
+
spaceId: z.cuid2().default(globalProjectSpace.id),
|
|
123
|
+
modelStorageId: z.cuid2().default(codebaseProjectModelStorage.id),
|
|
124
|
+
libraryId: z.cuid2().default(codebaseLibrary.id),
|
|
125
|
+
pulumiBackendId: z.cuid2().default(hostPulumiBackend.id),
|
|
126
|
+
meta: commonObjectMetaSchema
|
|
127
|
+
});
|
|
128
|
+
var projectOutputSchema = z.object({
|
|
129
|
+
id: z.string(),
|
|
130
|
+
name: genericNameSchema,
|
|
131
|
+
meta: commonObjectMetaSchema,
|
|
132
|
+
spaceId: z.cuid2(),
|
|
133
|
+
modelStorageId: z.cuid2(),
|
|
134
|
+
libraryId: z.cuid2(),
|
|
135
|
+
pulumiBackendId: z.cuid2(),
|
|
136
|
+
...timestampsSchema.shape
|
|
137
|
+
});
|
|
138
|
+
var projectUnlockSuiteSchema = z.object({
|
|
139
|
+
/**
|
|
140
|
+
* The list of encrypted AGE identities that can be used to decrypt the master key of the project.
|
|
141
|
+
*
|
|
142
|
+
* The frontend should try to decrypt at least one of these identities
|
|
143
|
+
* using the password or passkey.
|
|
144
|
+
*/
|
|
145
|
+
encryptedIdentities: z.array(z.string()),
|
|
146
|
+
/**
|
|
147
|
+
* Whether one of the identities is a passkey and user should be asked to use it.
|
|
148
|
+
*/
|
|
149
|
+
hasPasskey: z.boolean()
|
|
150
|
+
});
|
|
151
|
+
var projectUnlockStateSchema = z.discriminatedUnion("type", [
|
|
152
|
+
z.object({
|
|
153
|
+
type: z.literal("locked"),
|
|
154
|
+
unlockSuite: projectUnlockSuiteSchema.optional()
|
|
155
|
+
}),
|
|
156
|
+
z.object({
|
|
157
|
+
type: z.literal("unlocked")
|
|
158
|
+
})
|
|
159
|
+
]);
|
|
160
|
+
var pulumiBackendSpecSchema = z.discriminatedUnion("type", [
|
|
161
|
+
z.object({
|
|
162
|
+
/**
|
|
163
|
+
* Use the Pulumi backend configured on the host where Highstate backend is running.
|
|
164
|
+
*
|
|
165
|
+
* The backend is expected to be configured with the `pulumi login` command by the user.
|
|
166
|
+
*/
|
|
167
|
+
type: z.literal("host")
|
|
168
|
+
})
|
|
169
|
+
]);
|
|
170
|
+
var backendUnlockMethodSchema = z$1.object({
|
|
171
|
+
id: z$1.string(),
|
|
172
|
+
meta: objectMetaSchema,
|
|
173
|
+
/**
|
|
174
|
+
* The AGE recipient of the unlock method to use to encrypt the master key for this unlock method.
|
|
175
|
+
*/
|
|
176
|
+
recipient: z$1.string()
|
|
177
|
+
});
|
|
178
|
+
function hasObjectMeta(value) {
|
|
179
|
+
return typeof value === "object" && value !== null && "meta" in value;
|
|
180
|
+
}
|
|
181
|
+
var sortBySchema = z$1.object({
|
|
182
|
+
key: z$1.string(),
|
|
183
|
+
order: z$1.enum(["asc", "desc"])
|
|
184
|
+
});
|
|
185
|
+
var collectionQuerySchema = z$1.object({
|
|
186
|
+
/**
|
|
187
|
+
* The search string to filter documents by display name, description, or other text fields.
|
|
188
|
+
*/
|
|
189
|
+
search: z$1.string().optional(),
|
|
190
|
+
/**
|
|
191
|
+
* The sorting configuration for the results.
|
|
192
|
+
*
|
|
193
|
+
* Can be a single sort field or an array of sort fields.
|
|
194
|
+
* Each sort field contains the key and order.
|
|
195
|
+
*/
|
|
196
|
+
sortBy: z$1.array(sortBySchema).optional(),
|
|
197
|
+
/**
|
|
198
|
+
* The number of items to skip.
|
|
199
|
+
*
|
|
200
|
+
* Defaults to 0 if not specified.
|
|
201
|
+
*/
|
|
202
|
+
skip: z$1.number().int().nonnegative().default(0).optional(),
|
|
203
|
+
/**
|
|
204
|
+
* The count of documents to return.
|
|
205
|
+
*
|
|
206
|
+
* Defaults to 20 if not specified.
|
|
207
|
+
* Maximum value is 100.
|
|
208
|
+
*/
|
|
209
|
+
count: z$1.number().int().positive().max(100).default(20).optional()
|
|
210
|
+
});
|
|
211
|
+
function collectionQueryResult(schema) {
|
|
212
|
+
return z$1.object({
|
|
213
|
+
items: z$1.array(schema),
|
|
214
|
+
total: z$1.number().int().nonnegative()
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function forSchema(schema) {
|
|
218
|
+
return mapValues(schema.shape, constant(true));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// src/shared/models/errors.ts
|
|
222
|
+
var BackendError = class extends Error {
|
|
223
|
+
constructor(message, cause) {
|
|
224
|
+
super(message, { cause });
|
|
225
|
+
this.name = "BackendError";
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
var AccessError = class extends BackendError {
|
|
229
|
+
constructor(message) {
|
|
230
|
+
super(message);
|
|
231
|
+
this.name = "AccessError";
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var ProjectLockedError = class extends AccessError {
|
|
235
|
+
constructor(projectId) {
|
|
236
|
+
super(`The project with ID "${projectId}" is locked, decryption is not possible.`);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
var ProjectNotFoundError = class extends BackendError {
|
|
240
|
+
constructor(projectId) {
|
|
241
|
+
super(`Project with ID "${projectId}" not found.`);
|
|
242
|
+
this.name = "ProjectNotFoundError";
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
var CannotDeleteLastUnlockMethodError = class extends BackendError {
|
|
246
|
+
constructor(projectId) {
|
|
247
|
+
super(`Refused to delete the last unlock method for project "${projectId}".`);
|
|
248
|
+
this.name = "CannotDeleteLastUnlockMethodError";
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
var InstanceNotFoundError = class extends BackendError {
|
|
252
|
+
constructor(projectId, instanceId) {
|
|
253
|
+
super(`Instance with ID "${instanceId}" not found in project "${projectId}".`);
|
|
254
|
+
this.name = "InstanceNotFoundError";
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var InvalidInstanceKindError = class extends BackendError {
|
|
258
|
+
constructor(projectId, instanceId, expectedKind, actualKind) {
|
|
259
|
+
super(
|
|
260
|
+
`Instance "${instanceId}" in project "${projectId}" has kind "${actualKind}", but expected "${expectedKind}".`
|
|
261
|
+
);
|
|
262
|
+
this.name = "InvalidInstanceKindError";
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
var OperationNotFoundError = class extends BackendError {
|
|
266
|
+
constructor(projectId, operationId) {
|
|
267
|
+
super(`Operation with ID "${operationId}" not found in project "${projectId}".`);
|
|
268
|
+
this.name = "OperationNotFoundError";
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
var InstanceLockLostError = class extends BackendError {
|
|
272
|
+
constructor(projectId, instanceIds, token) {
|
|
273
|
+
super(
|
|
274
|
+
`Instance lock lost for instances [${instanceIds.join(", ")}] in project "${projectId}" with token "${token}".`
|
|
275
|
+
);
|
|
276
|
+
this.name = "InstanceLockLostError";
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
var InstanceStateNotFoundError = class extends BackendError {
|
|
280
|
+
constructor(projectId, instanceId) {
|
|
281
|
+
super(`State for instance with ID "${instanceId}" not found in project "${projectId}".`);
|
|
282
|
+
this.name = "InstanceStateNotFoundError";
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
var InstanceLockedError = class extends BackendError {
|
|
286
|
+
constructor(projectId, instanceId) {
|
|
287
|
+
super(`Instance with ID "${instanceId}" in project "${projectId}" is locked.`);
|
|
288
|
+
this.name = "InstanceLockedError";
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
var WorkerVersionNotFoundError = class extends BackendError {
|
|
292
|
+
constructor(projectId, workerVersionId) {
|
|
293
|
+
super(`Worker version with ID "${workerVersionId}" not found in project "${projectId}".`);
|
|
294
|
+
this.name = "WorkerVersionNotFoundError";
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
var apiKeyMetaSchema = objectMetaSchema.pick({
|
|
298
|
+
title: true,
|
|
299
|
+
description: true
|
|
300
|
+
}).required({ title: true });
|
|
301
|
+
var apiKeyOutputSchema = z.object({
|
|
302
|
+
id: z.cuid2(),
|
|
303
|
+
meta: commonObjectMetaSchema,
|
|
304
|
+
serviceAccountId: z.cuid2(),
|
|
305
|
+
serviceAccountMeta: serviceAccountMetaSchema.nullable(),
|
|
306
|
+
createdAt: z.date()
|
|
307
|
+
});
|
|
308
|
+
var apiKeyQuerySchema = collectionQuerySchema.extend({
|
|
309
|
+
serviceAccountId: z.string().optional()
|
|
310
|
+
});
|
|
311
|
+
function toApiKeyOutput(apiKey, serviceAccount) {
|
|
312
|
+
return {
|
|
313
|
+
...apiKey,
|
|
314
|
+
serviceAccountMeta: serviceAccount?.meta ?? null
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
var artifactOutputSchema = z$1.object({
|
|
318
|
+
id: z$1.cuid2(),
|
|
319
|
+
hash: z$1.string(),
|
|
320
|
+
size: z$1.number(),
|
|
321
|
+
meta: commonObjectMetaSchema,
|
|
322
|
+
createdAt: z$1.date(),
|
|
323
|
+
updatedAt: z$1.date()
|
|
324
|
+
});
|
|
325
|
+
var artifactQuerySchema = collectionQuerySchema.extend({
|
|
326
|
+
stateId: z$1.string().optional(),
|
|
327
|
+
serviceAccountId: z$1.string().optional(),
|
|
328
|
+
terminalId: z$1.string().optional(),
|
|
329
|
+
pageId: z$1.string().optional()
|
|
330
|
+
});
|
|
331
|
+
var instanceCustomStatusInputSchema = z$1.object({
|
|
332
|
+
name: z$1.string(),
|
|
333
|
+
meta: commonObjectMetaSchema,
|
|
334
|
+
value: z$1.string(),
|
|
335
|
+
message: z$1.string().optional(),
|
|
336
|
+
order: z$1.number().min(0).max(100).optional()
|
|
337
|
+
});
|
|
338
|
+
var instanceLockOutputSchema = z$1.object({
|
|
339
|
+
stateId: z$1.cuid2(),
|
|
340
|
+
meta: commonObjectMetaSchema,
|
|
341
|
+
acquiredAt: z$1.date()
|
|
342
|
+
});
|
|
343
|
+
var instanceLockEventSchema = z$1.discriminatedUnion("type", [
|
|
344
|
+
z$1.object({
|
|
345
|
+
type: z$1.literal("locked"),
|
|
346
|
+
locks: instanceLockOutputSchema.array()
|
|
347
|
+
}),
|
|
348
|
+
z$1.object({
|
|
349
|
+
type: z$1.literal("unlocked"),
|
|
350
|
+
stateIds: z$1.array(z$1.string())
|
|
351
|
+
})
|
|
352
|
+
]);
|
|
353
|
+
var projectModelEventSchema = z$1.object({
|
|
354
|
+
updatedInstances: instanceModelSchema.array().optional(),
|
|
355
|
+
updatedHubs: hubModelSchema.array().optional(),
|
|
356
|
+
updatedVirtualInstances: instanceModelSchema.array().optional(),
|
|
357
|
+
updatedGhostInstances: instanceModelSchema.array().optional(),
|
|
358
|
+
deletedInstanceIds: instanceIdSchema.array().optional(),
|
|
359
|
+
deletedHubIds: z$1.string().array().optional(),
|
|
360
|
+
deletedVirtualInstanceIds: instanceIdSchema.array().optional(),
|
|
361
|
+
deletedGhostInstanceIds: instanceIdSchema.array().optional()
|
|
362
|
+
});
|
|
363
|
+
var operationPhaseTypeSchema = z.enum(["destroy", "update", "refresh"]);
|
|
364
|
+
var operationPhaseInstanceSchema = z.object({
|
|
365
|
+
/**
|
|
366
|
+
* The ID of the instance.
|
|
367
|
+
*/
|
|
368
|
+
id: instanceIdSchema,
|
|
369
|
+
/**
|
|
370
|
+
* The parent ID of the instance, either from the model or the state.
|
|
371
|
+
*/
|
|
372
|
+
parentId: z.string().optional(),
|
|
373
|
+
/**
|
|
374
|
+
* Human-readable explanation of the decision.
|
|
375
|
+
* */
|
|
376
|
+
message: z.string()
|
|
377
|
+
});
|
|
378
|
+
var operationPhaseSchema = z.object({
|
|
379
|
+
/**
|
|
380
|
+
* Type of phase being executed.
|
|
381
|
+
*/
|
|
382
|
+
type: operationPhaseTypeSchema,
|
|
383
|
+
/**
|
|
384
|
+
* List of instances to be processed in this phase.
|
|
385
|
+
*/
|
|
386
|
+
instances: z.array(operationPhaseInstanceSchema)
|
|
387
|
+
});
|
|
388
|
+
var operationOptionsSchema = z.object({
|
|
389
|
+
/**
|
|
390
|
+
* Force update all dependencies regardless of their current state.
|
|
391
|
+
*
|
|
392
|
+
* **Operation Behavior Impact:**
|
|
393
|
+
* - bypasses hash-based change detection for dependency chains;
|
|
394
|
+
* - includes **ALL** dependencies (up-to-date, out-of-date, and error states);
|
|
395
|
+
* - traverses the entire dependency graph from requested instances.
|
|
396
|
+
*
|
|
397
|
+
* **Usage with other options:**
|
|
398
|
+
* - combined with `forceUpdateChildren`: updates entire dependency tree **AND** all composite children;
|
|
399
|
+
* - independent of `allowPartialCompositeInstanceCreation`: affects dependency traversal, not composite logic.
|
|
400
|
+
*/
|
|
401
|
+
forceUpdateDependencies: z.boolean().default(false),
|
|
402
|
+
/**
|
|
403
|
+
* Force update all children of composite instances regardless of their state.
|
|
404
|
+
*
|
|
405
|
+
* **Operation Behavior Impact:**
|
|
406
|
+
* - overrides selective child inclusion logic for composites;
|
|
407
|
+
* - includes **ALL** children of affected composites (up-to-date, out-of-date, and error states);
|
|
408
|
+
* - applied after dependency traversal and parent inclusion.
|
|
409
|
+
*
|
|
410
|
+
* **Usage with other options:**
|
|
411
|
+
* - combined with `forceUpdateDependencies`: creates comprehensive force-update behavior;
|
|
412
|
+
* - overrides `allowPartialCompositeInstanceCreation`: when enabled, **ALL** children are included regardless of existence.
|
|
413
|
+
*/
|
|
414
|
+
forceUpdateChildren: z.boolean().default(false),
|
|
415
|
+
/**
|
|
416
|
+
* Include dependent instances when destroying instances.
|
|
417
|
+
*
|
|
418
|
+
* **Operation Behavior Impact:**
|
|
419
|
+
* - extends destroy operations to include instances that depend on the target;
|
|
420
|
+
* - traverses the dependency graph in reverse (dependents, not dependencies);
|
|
421
|
+
* - prevents orphaned instances that would fail without their dependencies.
|
|
422
|
+
*
|
|
423
|
+
* **Usage with other options:**
|
|
424
|
+
* - works with `invokeDestroyTriggers`: ensures triggers run for all dependents;
|
|
425
|
+
* - independent of update-related options.
|
|
426
|
+
*/
|
|
427
|
+
destroyDependentInstances: z.boolean().default(true),
|
|
428
|
+
/**
|
|
429
|
+
* Execute destroy triggers when destroying instances.
|
|
430
|
+
*
|
|
431
|
+
* **Operation Behavior Impact:**
|
|
432
|
+
* - affects how individual units are destroyed (triggers vs direct deletion);
|
|
433
|
+
* - does not change which instances are selected for destruction;
|
|
434
|
+
* - controls trigger execution during the destruction phase.
|
|
435
|
+
*
|
|
436
|
+
* **Usage with other options:**
|
|
437
|
+
* - used with `destroyDependentInstances`: ensures triggers run for cascade deletions;
|
|
438
|
+
* - independent of update-related options.
|
|
439
|
+
*/
|
|
440
|
+
invokeDestroyTriggers: z.boolean().default(true),
|
|
441
|
+
/**
|
|
442
|
+
* Delete Pulumi resources that are no longer referenced in the state.
|
|
443
|
+
*
|
|
444
|
+
* **Operation Behavior Impact:**
|
|
445
|
+
* - does not affect which instances are selected for operations;
|
|
446
|
+
* - deletes orphaned Pulumi resources within individual instances.
|
|
447
|
+
*
|
|
448
|
+
* **Usage with other options:**
|
|
449
|
+
* - independent of instance selection options;
|
|
450
|
+
* - complements destroy-related options for thorough cleanup.
|
|
451
|
+
*/
|
|
452
|
+
deleteUnreachableResources: z.boolean().default(false),
|
|
453
|
+
/**
|
|
454
|
+
* Force deletion of instance state even if the destroy operation fails.
|
|
455
|
+
*
|
|
456
|
+
* **Operation Behavior Impact:**
|
|
457
|
+
* - forces state deletion even when destroy operations fail;
|
|
458
|
+
* - does not affect which instances are selected for operations;
|
|
459
|
+
* - bypasses normal destroy procedures as emergency fallback.
|
|
460
|
+
*
|
|
461
|
+
* **Usage with other options:**
|
|
462
|
+
* - used with destroy-related options when normal cleanup fails;
|
|
463
|
+
* - should be used cautiously as it can create state inconsistencies.
|
|
464
|
+
*/
|
|
465
|
+
forceDeleteState: z.boolean().default(false),
|
|
466
|
+
/**
|
|
467
|
+
* Allow partial update of composite instances without requiring all outdated children.
|
|
468
|
+
*
|
|
469
|
+
* **Operation Behavior Impact:**
|
|
470
|
+
* - controls whether composite operations must include all outdated children or only necessary ones;
|
|
471
|
+
* - when `false` (default): all outdated children of substantive composites are included in operations;
|
|
472
|
+
* - when `true`: only necessary children are included, allowing partial composite operations;
|
|
473
|
+
* - applied during composite child traversal phase for substantive composites only.
|
|
474
|
+
*
|
|
475
|
+
* **Usage with other options:**
|
|
476
|
+
* - overridden by `forceUpdateChildren`: when force is enabled, **ALL** children are included regardless;
|
|
477
|
+
* - independent of `forceUpdateDependencies`: affects composite logic, not dependency traversal.
|
|
478
|
+
*/
|
|
479
|
+
allowPartialCompositeInstanceUpdate: z.boolean().default(false),
|
|
480
|
+
/**
|
|
481
|
+
* Allow partial destruction of composite instances during cascade operations.
|
|
482
|
+
*
|
|
483
|
+
* **Operation Behavior Impact:**
|
|
484
|
+
* - controls whether cascade destruction must include all children or only necessary ones;
|
|
485
|
+
* - when `false` (default): cascade destruction includes **ALL** children of affected composites;
|
|
486
|
+
* - when `true`: cascade destruction includes only directly dependent children;
|
|
487
|
+
* - does not affect explicit composite destruction (always destroys all children);
|
|
488
|
+
* - does not affect parent propagation when destroying sibling composites.
|
|
489
|
+
*
|
|
490
|
+
* **Usage with other options:**
|
|
491
|
+
* - works with `destroyDependentInstances`: controls completeness of cascade destruction;
|
|
492
|
+
* - independent of update-related options.
|
|
493
|
+
*/
|
|
494
|
+
allowPartialCompositeInstanceDestruction: z.boolean().default(false),
|
|
495
|
+
/**
|
|
496
|
+
* Also refresh the state of instances during the operation.
|
|
497
|
+
*
|
|
498
|
+
* **Operation Behavior Impact:**
|
|
499
|
+
* - does not change which instances are selected for operations;
|
|
500
|
+
* - synchronizes state with actual infrastructure during the operation.
|
|
501
|
+
*
|
|
502
|
+
* **Usage with other options:**
|
|
503
|
+
* - additive with dependency resolution options: refreshes all selected instances;
|
|
504
|
+
* - works with both all operation types.
|
|
505
|
+
*/
|
|
506
|
+
refresh: z.boolean().default(false)
|
|
507
|
+
}).partial();
|
|
508
|
+
var operationTypeSchema = z.enum([
|
|
509
|
+
"update",
|
|
510
|
+
"preview",
|
|
511
|
+
"destroy",
|
|
512
|
+
"recreate",
|
|
513
|
+
"refresh"
|
|
514
|
+
]);
|
|
515
|
+
var operationStatusSchema = z.enum([
|
|
516
|
+
"pending",
|
|
517
|
+
"running",
|
|
518
|
+
"failing",
|
|
519
|
+
"completed",
|
|
520
|
+
"failed",
|
|
521
|
+
"cancelled"
|
|
522
|
+
]);
|
|
523
|
+
var operationMetaSchema = objectMetaSchema.pick({
|
|
524
|
+
title: true,
|
|
525
|
+
description: true
|
|
526
|
+
});
|
|
527
|
+
var operationInputSchema = z.object({
|
|
528
|
+
projectId: z.string(),
|
|
529
|
+
type: operationTypeSchema,
|
|
530
|
+
instanceIds: z.array(instanceIdSchema).min(1),
|
|
531
|
+
options: operationOptionsSchema.partial().optional(),
|
|
532
|
+
meta: operationMetaSchema.optional(),
|
|
533
|
+
plan: operationPhaseSchema.array().optional()
|
|
534
|
+
});
|
|
535
|
+
var operationEventSchema = z.discriminatedUnion("type", [
|
|
536
|
+
z.object({
|
|
537
|
+
type: z.literal("updated"),
|
|
538
|
+
operation: z.custom()
|
|
539
|
+
}),
|
|
540
|
+
z.object({
|
|
541
|
+
type: z.literal("deleted"),
|
|
542
|
+
operationId: z.string()
|
|
543
|
+
})
|
|
544
|
+
]);
|
|
545
|
+
var operationOutputSchema = z.object({
|
|
546
|
+
id: z.cuid2(),
|
|
547
|
+
type: operationTypeSchema,
|
|
548
|
+
status: operationStatusSchema,
|
|
549
|
+
meta: operationMetaSchema,
|
|
550
|
+
startedAt: z.date(),
|
|
551
|
+
updatedAt: z.date(),
|
|
552
|
+
finishedAt: z.date().nullable()
|
|
553
|
+
});
|
|
554
|
+
var finalOperationStatuses = ["completed", "failed", "cancelled"];
|
|
555
|
+
function isFinalOperationStatus(status) {
|
|
556
|
+
return finalOperationStatuses.includes(status);
|
|
557
|
+
}
|
|
558
|
+
function isTransientOperationStatus(status) {
|
|
559
|
+
return !!status && !finalOperationStatuses.includes(status);
|
|
560
|
+
}
|
|
561
|
+
var pageOutputSchema = z$1.object({
|
|
562
|
+
id: z$1.cuid2(),
|
|
563
|
+
meta: commonObjectMetaSchema,
|
|
564
|
+
name: z$1.string().nullable(),
|
|
565
|
+
stateId: z$1.cuid2().nullable(),
|
|
566
|
+
serviceAccountId: z$1.cuid2().nullable(),
|
|
567
|
+
serviceAccountMeta: serviceAccountMetaSchema.nullable(),
|
|
568
|
+
createdAt: z$1.date(),
|
|
569
|
+
updatedAt: z$1.date()
|
|
570
|
+
});
|
|
571
|
+
var pageQuerySchema = collectionQuerySchema.extend({
|
|
572
|
+
serviceAccountId: z$1.string().optional(),
|
|
573
|
+
stateId: z$1.string().optional(),
|
|
574
|
+
artifactId: z$1.string().optional()
|
|
575
|
+
});
|
|
576
|
+
var pageDetailsOutputSchema = z$1.object({
|
|
577
|
+
...pageOutputSchema.shape,
|
|
578
|
+
content: z$1.array(pageBlockSchema)
|
|
579
|
+
});
|
|
580
|
+
function toPageOutput(page, serviceAccount) {
|
|
581
|
+
return {
|
|
582
|
+
...page,
|
|
583
|
+
serviceAccountMeta: serviceAccount?.meta ?? null
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
var secretOutputSchema = z.object({
|
|
587
|
+
id: z.cuid2(),
|
|
588
|
+
meta: globalCommonObjectMetaSchema,
|
|
589
|
+
name: z.string().nullable(),
|
|
590
|
+
systemName: z.string().nullable(),
|
|
591
|
+
stateId: z.cuid2().nullable(),
|
|
592
|
+
serviceAccountId: z.cuid2().nullable(),
|
|
593
|
+
serviceAccountMeta: serviceAccountMetaSchema.nullable(),
|
|
594
|
+
createdAt: z.date(),
|
|
595
|
+
updatedAt: z.date()
|
|
596
|
+
});
|
|
597
|
+
var secretQuerySchema = collectionQuerySchema.extend({
|
|
598
|
+
serviceAccountId: z.string().optional(),
|
|
599
|
+
stateId: z.string().optional()
|
|
600
|
+
});
|
|
601
|
+
function toSecretOutput(secret, serviceAccount) {
|
|
602
|
+
return {
|
|
603
|
+
...secret,
|
|
604
|
+
serviceAccountMeta: serviceAccount?.meta ?? null
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
var SystemSecretNames = /* @__PURE__ */ ((SystemSecretNames2) => {
|
|
608
|
+
SystemSecretNames2["PulumiPassword"] = "pulumi-password";
|
|
609
|
+
return SystemSecretNames2;
|
|
610
|
+
})(SystemSecretNames || {});
|
|
611
|
+
var serviceAccountOutputSchema = z.object({
|
|
612
|
+
id: z.cuid2(),
|
|
613
|
+
meta: serviceAccountMetaSchema,
|
|
614
|
+
createdAt: z.date(),
|
|
615
|
+
updatedAt: z.date()
|
|
616
|
+
});
|
|
617
|
+
var serviceAccountQuerySchema = collectionQuerySchema.extend({
|
|
618
|
+
artifactId: z.string().optional()
|
|
619
|
+
});
|
|
620
|
+
var instanceStateEventSchema = z$1.discriminatedUnion("type", [
|
|
621
|
+
z$1.object({
|
|
622
|
+
type: z$1.literal("updated"),
|
|
623
|
+
state: z$1.custom()
|
|
624
|
+
}),
|
|
625
|
+
z$1.object({
|
|
626
|
+
type: z$1.literal("patched"),
|
|
627
|
+
stateId: z$1.string(),
|
|
628
|
+
patch: z$1.custom()
|
|
629
|
+
}),
|
|
630
|
+
z$1.object({
|
|
631
|
+
type: z$1.literal("deleted"),
|
|
632
|
+
stateId: z$1.string()
|
|
633
|
+
})
|
|
634
|
+
]);
|
|
635
|
+
function isVirtualGhostInstance(state) {
|
|
636
|
+
if (state.source !== "virtual") return false;
|
|
637
|
+
if (state.status === "undeployed") return false;
|
|
638
|
+
return !state.evaluationState;
|
|
639
|
+
}
|
|
640
|
+
function isInstanceDeployed(state) {
|
|
641
|
+
return !!state && state.status !== "undeployed";
|
|
642
|
+
}
|
|
643
|
+
var finalInstanceOperationStatuses = [
|
|
644
|
+
"destroyed",
|
|
645
|
+
"updated",
|
|
646
|
+
"cancelled",
|
|
647
|
+
"destroyed",
|
|
648
|
+
"failed",
|
|
649
|
+
"skipped"
|
|
650
|
+
];
|
|
651
|
+
function isTransientInstanceOperationStatus(status) {
|
|
652
|
+
return !!status && !finalInstanceOperationStatuses.includes(status);
|
|
653
|
+
}
|
|
654
|
+
var workerUnitRegistrationEventSchema = z$1.discriminatedUnion("type", [
|
|
655
|
+
z$1.object({
|
|
656
|
+
type: z$1.literal("registered"),
|
|
657
|
+
instanceId: z$1.string(),
|
|
658
|
+
params: z$1.record(z$1.string(), z$1.unknown())
|
|
659
|
+
}),
|
|
660
|
+
z$1.object({
|
|
661
|
+
type: z$1.literal("deregistered"),
|
|
662
|
+
instanceId: z$1.string()
|
|
663
|
+
})
|
|
664
|
+
]);
|
|
665
|
+
var terminalStatusSchema = z$1.enum([
|
|
666
|
+
"active",
|
|
667
|
+
"unavailable"
|
|
668
|
+
]);
|
|
669
|
+
var terminalSessionOutputSchema = z$1.object({
|
|
670
|
+
id: z$1.cuid2(),
|
|
671
|
+
terminalId: z$1.cuid2(),
|
|
672
|
+
meta: commonObjectMetaSchema,
|
|
673
|
+
startedAt: z$1.date(),
|
|
674
|
+
finishedAt: z$1.date().nullable()
|
|
675
|
+
});
|
|
676
|
+
var terminalOutputSchema = z$1.object({
|
|
677
|
+
id: z$1.cuid2(),
|
|
678
|
+
name: z$1.string().nullable(),
|
|
679
|
+
meta: commonObjectMetaSchema,
|
|
680
|
+
status: terminalStatusSchema,
|
|
681
|
+
stateId: z$1.string().nullable(),
|
|
682
|
+
serviceAccountId: z$1.string().nullable(),
|
|
683
|
+
serviceAccountMeta: serviceAccountMetaSchema.nullable(),
|
|
684
|
+
createdAt: z$1.date(),
|
|
685
|
+
updatedAt: z$1.date()
|
|
686
|
+
});
|
|
687
|
+
var terminalQuerySchema = collectionQuerySchema.extend({
|
|
688
|
+
serviceAccountId: z$1.string().optional(),
|
|
689
|
+
stateId: z$1.string().optional(),
|
|
690
|
+
artifactId: z$1.string().optional()
|
|
691
|
+
});
|
|
692
|
+
function toTerminalOutput(terminal, serviceAccount) {
|
|
693
|
+
return {
|
|
694
|
+
...terminal,
|
|
695
|
+
serviceAccountMeta: serviceAccount?.meta ?? null
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
function toTerminalDetailsOutput(terminal, serviceAccount) {
|
|
699
|
+
return {
|
|
700
|
+
...terminal,
|
|
701
|
+
serviceAccountMeta: serviceAccount?.meta ?? null
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
var terminalDetailsOutputSchema = z$1.object({
|
|
705
|
+
...terminalOutputSchema.shape,
|
|
706
|
+
spec: terminalSpecSchema
|
|
707
|
+
});
|
|
708
|
+
function toTerminalSessionOutput(terminal, session) {
|
|
709
|
+
return {
|
|
710
|
+
id: session.id,
|
|
711
|
+
terminalId: terminal.id,
|
|
712
|
+
meta: terminal.meta,
|
|
713
|
+
startedAt: session.startedAt,
|
|
714
|
+
finishedAt: session.finishedAt
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
var triggerOutputSchema = z$1.object({
|
|
718
|
+
id: z$1.cuid2(),
|
|
719
|
+
meta: commonObjectMetaSchema,
|
|
720
|
+
name: z$1.string(),
|
|
721
|
+
stateId: z$1.cuid2(),
|
|
722
|
+
createdAt: z$1.date(),
|
|
723
|
+
updatedAt: z$1.date()
|
|
724
|
+
});
|
|
725
|
+
var triggerQuerySchema = collectionQuerySchema.extend({
|
|
726
|
+
stateId: z$1.string().optional()
|
|
727
|
+
});
|
|
728
|
+
var unlockMethodType = z.enum(["password", "passkey"]);
|
|
729
|
+
var unlockMethodMetaSchema = objectMetaSchema.pick({
|
|
730
|
+
title: true,
|
|
731
|
+
description: true
|
|
732
|
+
}).required({ title: true });
|
|
733
|
+
var unlockMethodInputSchema = z.object({
|
|
734
|
+
meta: unlockMethodMetaSchema,
|
|
735
|
+
type: unlockMethodType,
|
|
736
|
+
encryptedIdentity: z.string(),
|
|
737
|
+
recipient: z.string()
|
|
738
|
+
});
|
|
739
|
+
var unlockMethodOutputSchema = z.object({
|
|
740
|
+
id: z.cuid2(),
|
|
741
|
+
type: unlockMethodType,
|
|
742
|
+
meta: unlockMethodMetaSchema,
|
|
743
|
+
recipient: z.string(),
|
|
744
|
+
createdAt: z.date(),
|
|
745
|
+
updatedAt: z.date()
|
|
746
|
+
});
|
|
747
|
+
var MAX_WORKER_START_ATTEMPTS = 3;
|
|
748
|
+
var SHA256_PREFIX = "sha256:";
|
|
749
|
+
var SHA256_REGEX = /^[a-f0-9]{64}$/;
|
|
750
|
+
function extractDigestFromImage(image) {
|
|
751
|
+
const atIndex = image.indexOf("@");
|
|
752
|
+
if (atIndex === -1) {
|
|
753
|
+
throw new Error(`Invalid worker image "${image}": missing digest.`);
|
|
754
|
+
}
|
|
755
|
+
const digestPart = image.slice(atIndex + 1);
|
|
756
|
+
if (!digestPart.startsWith(SHA256_PREFIX)) {
|
|
757
|
+
throw new Error(`Invalid worker image "${image}": digest must start with "sha256:".`);
|
|
758
|
+
}
|
|
759
|
+
const digest = digestPart.slice(SHA256_PREFIX.length).toLowerCase();
|
|
760
|
+
if (!SHA256_REGEX.test(digest)) {
|
|
761
|
+
throw new Error(`Invalid worker image "${image}": digest must be 64 hex chars.`);
|
|
762
|
+
}
|
|
763
|
+
return digest;
|
|
764
|
+
}
|
|
765
|
+
function getWorkerIdentity(image) {
|
|
766
|
+
const atIndex = image.indexOf("@");
|
|
767
|
+
const withoutDigest = atIndex === -1 ? image : image.slice(0, atIndex);
|
|
768
|
+
const lastColon = withoutDigest.lastIndexOf(":");
|
|
769
|
+
const lastSlash = withoutDigest.lastIndexOf("/");
|
|
770
|
+
if (lastColon > -1 && lastColon > lastSlash) {
|
|
771
|
+
return withoutDigest.slice(0, lastColon);
|
|
772
|
+
}
|
|
773
|
+
return withoutDigest;
|
|
774
|
+
}
|
|
775
|
+
var workerVersionStatusSchema = z$1.enum([
|
|
776
|
+
"unknown",
|
|
777
|
+
"starting",
|
|
778
|
+
"running",
|
|
779
|
+
"stopping",
|
|
780
|
+
"stopped",
|
|
781
|
+
"error"
|
|
782
|
+
]);
|
|
783
|
+
var workerVersionOutputSchema = z$1.object({
|
|
784
|
+
id: z$1.cuid2(),
|
|
785
|
+
digest: z$1.string(),
|
|
786
|
+
meta: commonObjectMetaSchema,
|
|
787
|
+
status: workerVersionStatusSchema,
|
|
788
|
+
enabled: z$1.boolean(),
|
|
789
|
+
apiKeyId: z$1.string(),
|
|
790
|
+
apiKeyMeta: apiKeyMetaSchema,
|
|
791
|
+
createdAt: z$1.date(),
|
|
792
|
+
updatedAt: z$1.date()
|
|
793
|
+
});
|
|
794
|
+
var workerOutputSchema = z$1.object({
|
|
795
|
+
id: z$1.cuid2(),
|
|
796
|
+
identity: z$1.string(),
|
|
797
|
+
meta: commonObjectMetaSchema,
|
|
798
|
+
serviceAccountId: z$1.string(),
|
|
799
|
+
serviceAccountMeta: serviceAccountMetaSchema,
|
|
800
|
+
createdAt: z$1.date()
|
|
801
|
+
});
|
|
802
|
+
var workerQuerySchema = collectionQuerySchema.extend({
|
|
803
|
+
serviceAccountId: z$1.string().optional()
|
|
804
|
+
});
|
|
805
|
+
function toWorkerOutput(worker, lastVersion, serviceAccount) {
|
|
806
|
+
return {
|
|
807
|
+
...worker,
|
|
808
|
+
meta: lastVersion?.meta ?? { title: "Unknown" },
|
|
809
|
+
serviceAccountMeta: serviceAccount.meta
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function toWorkerVersionOutput(version, apiKey) {
|
|
813
|
+
return {
|
|
814
|
+
...version,
|
|
815
|
+
apiKeyMeta: apiKey.meta
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
var GraphResolver = class {
|
|
819
|
+
constructor(nodes, logger, outputHandler, dependentSetHandler) {
|
|
820
|
+
this.nodes = nodes;
|
|
821
|
+
this.logger = logger;
|
|
822
|
+
this.outputHandler = outputHandler;
|
|
823
|
+
this.dependentSetHandler = dependentSetHandler;
|
|
824
|
+
}
|
|
825
|
+
workset = /* @__PURE__ */ new Set();
|
|
826
|
+
dependencyMap = /* @__PURE__ */ new Map();
|
|
827
|
+
dependentMap = /* @__PURE__ */ new Map();
|
|
828
|
+
outputMap = /* @__PURE__ */ new Map();
|
|
829
|
+
addToWorkset(nodeId) {
|
|
830
|
+
this.workset.add(nodeId);
|
|
831
|
+
}
|
|
832
|
+
addAllNodesToWorkset() {
|
|
833
|
+
for (const nodeId of this.nodes.keys()) {
|
|
834
|
+
this.workset.add(nodeId);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* The map of calculated outputs.
|
|
839
|
+
*/
|
|
840
|
+
get outputs() {
|
|
841
|
+
return this.outputMap;
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* The map of dependencies for each node.
|
|
845
|
+
*
|
|
846
|
+
* The key is the node identifier, and the value is an array of identifiers of the nodes which depend on it.
|
|
847
|
+
*/
|
|
848
|
+
get dependents() {
|
|
849
|
+
return this.dependentMap;
|
|
850
|
+
}
|
|
851
|
+
requireOutput(nodeId) {
|
|
852
|
+
const output = this.outputMap.get(nodeId);
|
|
853
|
+
if (!output) {
|
|
854
|
+
throw new Error(`Output for node ${nodeId} is not available`);
|
|
855
|
+
}
|
|
856
|
+
return output;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Gets the identifiers of the nodes that depend on the given node directly.
|
|
860
|
+
*
|
|
861
|
+
* Returns an empty array if there are no dependents.
|
|
862
|
+
*/
|
|
863
|
+
getDependents(nodeId) {
|
|
864
|
+
const dependents = this.dependentMap.get(nodeId);
|
|
865
|
+
if (!dependents) {
|
|
866
|
+
return [];
|
|
867
|
+
}
|
|
868
|
+
return Array.from(dependents);
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Invalidates the node and all nodes that depend on it.
|
|
872
|
+
*
|
|
873
|
+
* Also adds the node to the work set for processing.
|
|
874
|
+
*/
|
|
875
|
+
invalidate(nodeId) {
|
|
876
|
+
const stack = [nodeId];
|
|
877
|
+
while (stack.length > 0) {
|
|
878
|
+
const nodeId2 = stack.pop();
|
|
879
|
+
if (!this.nodes.has(nodeId2)) {
|
|
880
|
+
continue;
|
|
881
|
+
}
|
|
882
|
+
this.outputMap.delete(nodeId2);
|
|
883
|
+
this.workset.add(nodeId2);
|
|
884
|
+
const dependents = this.dependentMap.get(nodeId2);
|
|
885
|
+
if (!dependents) {
|
|
886
|
+
continue;
|
|
887
|
+
}
|
|
888
|
+
for (const dependentId of dependents) {
|
|
889
|
+
if (this.outputMap.has(dependentId)) {
|
|
890
|
+
stack.push(dependentId);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Invalidates a single node without invalidating its dependents.
|
|
897
|
+
*
|
|
898
|
+
* Also adds the node to the work set for processing.
|
|
899
|
+
*
|
|
900
|
+
* Should be used with caution, as it may lead to inconsistent state if the dependents are not re-processed separately.
|
|
901
|
+
*/
|
|
902
|
+
invalidateSingle(nodeId) {
|
|
903
|
+
if (!this.nodes.has(nodeId)) {
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
this.outputMap.delete(nodeId);
|
|
907
|
+
this.workset.add(nodeId);
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Resolves all not-resolved or invalidated nodes in the graph.
|
|
911
|
+
*
|
|
912
|
+
* The abort signal of the previous operation must be called before calling this method again.
|
|
913
|
+
*/
|
|
914
|
+
async process(signal) {
|
|
915
|
+
while (this.workset.size > 0) {
|
|
916
|
+
const rootNodeId = this.workset.values().next().value;
|
|
917
|
+
const stack = [{ nodeId: rootNodeId, resolved: false, dependencies: [] }];
|
|
918
|
+
while (stack.length > 0) {
|
|
919
|
+
const stackItem = stack[stack.length - 1];
|
|
920
|
+
const { nodeId, resolved } = stackItem;
|
|
921
|
+
const node = this.nodes.get(nodeId);
|
|
922
|
+
if (!node) {
|
|
923
|
+
this.logger.warn({ nodeId }, "node not found in the graph, skipping");
|
|
924
|
+
stack.pop();
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
if (this.outputMap.has(nodeId)) {
|
|
928
|
+
stack.pop();
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
if (!resolved) {
|
|
932
|
+
stackItem.dependencies = unique(this.getNodeDependencies(node));
|
|
933
|
+
let hasUnresolvedDependencies = false;
|
|
934
|
+
for (const depId of stackItem.dependencies) {
|
|
935
|
+
if (!this.nodes.has(depId)) {
|
|
936
|
+
this.logger.warn({ depId, nodeId }, "dependency not found in the graph, skipping");
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
if (!this.outputMap.has(depId)) {
|
|
940
|
+
stack.push({ nodeId: depId, resolved: false, dependencies: [] });
|
|
941
|
+
hasUnresolvedDependencies = true;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (hasUnresolvedDependencies) {
|
|
945
|
+
stackItem.resolved = true;
|
|
946
|
+
continue;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
const output = await this.processNode(node, this.logger);
|
|
950
|
+
if (signal?.aborted) {
|
|
951
|
+
this.logger.warn({ nodeId }, "processing aborted, skipping output");
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
const changedDependentMaps = /* @__PURE__ */ new Set();
|
|
955
|
+
const oldDependencies = this.dependencyMap.get(nodeId) ?? [];
|
|
956
|
+
for (const depId of oldDependencies) {
|
|
957
|
+
const dependantSet = this.dependentMap.get(depId);
|
|
958
|
+
if (dependantSet) {
|
|
959
|
+
dependantSet.delete(nodeId);
|
|
960
|
+
changedDependentMaps.add(depId);
|
|
961
|
+
if (dependantSet.size === 0) {
|
|
962
|
+
this.dependentMap.delete(depId);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
for (const depId of stackItem.dependencies) {
|
|
967
|
+
let dependantSet = this.dependentMap.get(depId);
|
|
968
|
+
if (!dependantSet) {
|
|
969
|
+
dependantSet = /* @__PURE__ */ new Set();
|
|
970
|
+
this.dependentMap.set(depId, dependantSet);
|
|
971
|
+
}
|
|
972
|
+
dependantSet.add(nodeId);
|
|
973
|
+
changedDependentMaps.add(depId);
|
|
974
|
+
}
|
|
975
|
+
if (this.dependentSetHandler) {
|
|
976
|
+
for (const depId of changedDependentMaps) {
|
|
977
|
+
const dependents = this.dependentMap.get(depId);
|
|
978
|
+
this.dependentSetHandler(depId, dependents);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
this.outputMap.set(nodeId, output);
|
|
982
|
+
this.outputHandler?.(nodeId, output);
|
|
983
|
+
this.dependencyMap.set(nodeId, stackItem.dependencies);
|
|
984
|
+
stack.pop();
|
|
985
|
+
}
|
|
986
|
+
this.workset.delete(rootNodeId);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
function getAllDependents(dependentMap, nodeId) {
|
|
991
|
+
const result = /* @__PURE__ */ new Set();
|
|
992
|
+
const stack = [nodeId];
|
|
993
|
+
while (stack.length > 0) {
|
|
994
|
+
const dependents = dependentMap.get(stack.pop());
|
|
995
|
+
if (!dependents) {
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
for (const dependentId of dependents) {
|
|
999
|
+
if (!result.has(dependentId)) {
|
|
1000
|
+
result.add(dependentId);
|
|
1001
|
+
stack.push(dependentId);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
return Array.from(result);
|
|
1006
|
+
}
|
|
1007
|
+
var InputResolver = class extends GraphResolver {
|
|
1008
|
+
getNodeDependencies(node) {
|
|
1009
|
+
const dependencies = [];
|
|
1010
|
+
if (node.kind === "hub") {
|
|
1011
|
+
for (const input of node.hub.inputs ?? []) {
|
|
1012
|
+
dependencies.push(`instance:${input.instanceId}`);
|
|
1013
|
+
}
|
|
1014
|
+
for (const input of node.hub.injectionInputs ?? []) {
|
|
1015
|
+
dependencies.push(`hub:${input.hubId}`);
|
|
1016
|
+
}
|
|
1017
|
+
return dependencies;
|
|
1018
|
+
}
|
|
1019
|
+
for (const inputs of Object.values(node.instance.inputs ?? {})) {
|
|
1020
|
+
for (const input of inputs) {
|
|
1021
|
+
dependencies.push(`instance:${input.instanceId}`);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
for (const inputs of Object.values(node.instance.hubInputs ?? {})) {
|
|
1025
|
+
for (const input of inputs) {
|
|
1026
|
+
dependencies.push(`hub:${input.hubId}`);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
for (const input of node.instance.injectionInputs ?? []) {
|
|
1030
|
+
dependencies.push(`hub:${input.hubId}`);
|
|
1031
|
+
}
|
|
1032
|
+
return dependencies;
|
|
1033
|
+
}
|
|
1034
|
+
processNode(node) {
|
|
1035
|
+
const getHubOutput = (input) => {
|
|
1036
|
+
const output = this.outputs.get(`hub:${input.hubId}`);
|
|
1037
|
+
if (!output) {
|
|
1038
|
+
return { resolvedInputs: [] };
|
|
1039
|
+
}
|
|
1040
|
+
if (output.kind !== "hub") {
|
|
1041
|
+
throw new Error("Expected hub node");
|
|
1042
|
+
}
|
|
1043
|
+
return output;
|
|
1044
|
+
};
|
|
1045
|
+
const getInstanceOutput = (input) => {
|
|
1046
|
+
const output = this.outputs.get(`instance:${input.instanceId}`);
|
|
1047
|
+
if (!output) {
|
|
1048
|
+
return {
|
|
1049
|
+
component: null,
|
|
1050
|
+
resolvedInputs: [],
|
|
1051
|
+
resolvedOutputs: []
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
if (output.kind !== "instance") {
|
|
1055
|
+
throw new Error("Expected instance node");
|
|
1056
|
+
}
|
|
1057
|
+
return {
|
|
1058
|
+
component: output.component,
|
|
1059
|
+
resolvedInputs: output.resolvedInputs[input.output] ?? [],
|
|
1060
|
+
resolvedOutputs: output.resolvedOutputs?.[input.output]
|
|
1061
|
+
};
|
|
1062
|
+
};
|
|
1063
|
+
if (node.kind === "hub") {
|
|
1064
|
+
const hubResult = /* @__PURE__ */ new Map();
|
|
1065
|
+
const addHubResult = (input) => {
|
|
1066
|
+
hubResult.set(`${input.input.instanceId}:${input.input.output}`, input);
|
|
1067
|
+
};
|
|
1068
|
+
for (const input of node.hub.inputs ?? []) {
|
|
1069
|
+
const { component } = getInstanceOutput(input);
|
|
1070
|
+
const componentInput = component?.outputs[input.output];
|
|
1071
|
+
if (!componentInput) {
|
|
1072
|
+
this.logger.warn({ msg: "output not found in the component", input, component });
|
|
1073
|
+
continue;
|
|
1074
|
+
}
|
|
1075
|
+
addHubResult({ input, type: componentInput.type });
|
|
1076
|
+
}
|
|
1077
|
+
for (const injectionInput of node.hub.injectionInputs ?? []) {
|
|
1078
|
+
const { resolvedInputs: resolvedInputs2 } = getHubOutput(injectionInput);
|
|
1079
|
+
for (const input of resolvedInputs2) {
|
|
1080
|
+
addHubResult(input);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
return {
|
|
1084
|
+
kind: "hub",
|
|
1085
|
+
resolvedInputs: Array.from(hubResult.values())
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
if (node.instance.resolvedInputs) {
|
|
1089
|
+
return {
|
|
1090
|
+
kind: "instance",
|
|
1091
|
+
instance: node.instance,
|
|
1092
|
+
component: node.component,
|
|
1093
|
+
resolvedInputs: mapValues(node.instance.resolvedInputs, (inputs, inputName) => {
|
|
1094
|
+
const componentInput = node.component.inputs[inputName];
|
|
1095
|
+
if (!componentInput) {
|
|
1096
|
+
this.logger.warn({
|
|
1097
|
+
msg: "input not found in the component",
|
|
1098
|
+
inputName,
|
|
1099
|
+
component: node.component
|
|
1100
|
+
});
|
|
1101
|
+
return [];
|
|
1102
|
+
}
|
|
1103
|
+
return inputs.map((input) => ({ input, type: componentInput.type }));
|
|
1104
|
+
}),
|
|
1105
|
+
resolvedOutputs: node.instance.resolvedOutputs ?? {},
|
|
1106
|
+
resolvedInjectionInputs: [],
|
|
1107
|
+
matchedInjectionInputs: []
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
const resolvedInputsMap = /* @__PURE__ */ new Map();
|
|
1111
|
+
const addInstanceResult = (inputName, input) => {
|
|
1112
|
+
let inputs = resolvedInputsMap.get(inputName);
|
|
1113
|
+
if (!inputs) {
|
|
1114
|
+
inputs = /* @__PURE__ */ new Map();
|
|
1115
|
+
resolvedInputsMap.set(inputName, inputs);
|
|
1116
|
+
}
|
|
1117
|
+
inputs.set(`${input.input.instanceId}:${input.input.output}`, input);
|
|
1118
|
+
};
|
|
1119
|
+
const addInstanceInput = (inputName, input) => {
|
|
1120
|
+
const componentInput = node.component.inputs[inputName];
|
|
1121
|
+
if (!componentInput) {
|
|
1122
|
+
this.logger.warn({
|
|
1123
|
+
msg: "input not found in the component",
|
|
1124
|
+
input,
|
|
1125
|
+
component: node.component
|
|
1126
|
+
});
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
const { component, resolvedOutputs } = getInstanceOutput(input);
|
|
1130
|
+
if (!component) {
|
|
1131
|
+
this.logger.warn({ instanceId: node.instance.id, input }, "no output found for the input");
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
if (isUnitModel(component)) {
|
|
1135
|
+
addInstanceResult(inputName, { input, type: componentInput.type });
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
if (resolvedOutputs) {
|
|
1139
|
+
for (const output of resolvedOutputs) {
|
|
1140
|
+
addInstanceResult(inputName, { input: output, type: componentInput.type });
|
|
1141
|
+
}
|
|
1142
|
+
} else {
|
|
1143
|
+
addInstanceResult(inputName, { input, type: componentInput.type });
|
|
1144
|
+
}
|
|
1145
|
+
};
|
|
1146
|
+
for (const [inputName, inputs] of Object.entries(node.instance.inputs ?? {})) {
|
|
1147
|
+
for (const input of inputs) {
|
|
1148
|
+
addInstanceInput(inputName, input);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
const injectionInputs = /* @__PURE__ */ new Map();
|
|
1152
|
+
const matchedInjectionInputs = /* @__PURE__ */ new Map();
|
|
1153
|
+
for (const injectionInput of node.instance.injectionInputs ?? []) {
|
|
1154
|
+
const { resolvedInputs: resolvedInputs2 } = getHubOutput(injectionInput);
|
|
1155
|
+
for (const input of resolvedInputs2) {
|
|
1156
|
+
injectionInputs.set(`${input.input.instanceId}:${input.input.output}`, input);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
for (const [inputName, componentInput] of Object.entries(node.component.inputs ?? {})) {
|
|
1160
|
+
const allInputs = new Map(injectionInputs);
|
|
1161
|
+
const hubInputs = node.instance.hubInputs?.[inputName] ?? [];
|
|
1162
|
+
for (const hubInput of hubInputs) {
|
|
1163
|
+
const { resolvedInputs: resolvedInputs2 } = getHubOutput(hubInput);
|
|
1164
|
+
for (const input of resolvedInputs2) {
|
|
1165
|
+
allInputs.set(`${input.input.instanceId}:${input.input.output}`, input);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
for (const input of allInputs.values()) {
|
|
1169
|
+
if (input.type === componentInput.type) {
|
|
1170
|
+
addInstanceInput(inputName, input.input);
|
|
1171
|
+
const key = `${input.input.instanceId}:${input.input.output}`;
|
|
1172
|
+
if (injectionInputs.has(key)) {
|
|
1173
|
+
matchedInjectionInputs.set(key, input);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
const resolvedInputs = fromEntries(
|
|
1179
|
+
Array.from(resolvedInputsMap.entries()).map(([inputName, inputs]) => [
|
|
1180
|
+
inputName,
|
|
1181
|
+
Array.from(inputs.values())
|
|
1182
|
+
])
|
|
1183
|
+
);
|
|
1184
|
+
return {
|
|
1185
|
+
kind: "instance",
|
|
1186
|
+
instance: node.instance,
|
|
1187
|
+
component: node.component,
|
|
1188
|
+
resolvedInputs,
|
|
1189
|
+
resolvedOutputs: node.instance.resolvedOutputs,
|
|
1190
|
+
resolvedInjectionInputs: Array.from(injectionInputs.values()),
|
|
1191
|
+
matchedInjectionInputs: Array.from(matchedInjectionInputs.values())
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
function getResolvedHubInputs(outputMap, hubId) {
|
|
1196
|
+
const output = outputMap.get(`hub:${hubId}`);
|
|
1197
|
+
if (!output) {
|
|
1198
|
+
return [];
|
|
1199
|
+
}
|
|
1200
|
+
if (output.kind !== "hub") {
|
|
1201
|
+
throw new Error("Expected hub node");
|
|
1202
|
+
}
|
|
1203
|
+
return output.resolvedInputs;
|
|
1204
|
+
}
|
|
1205
|
+
function getResolvedInstanceInputs(outputMap, instanceId) {
|
|
1206
|
+
const output = outputMap.get(`instance:${instanceId}`);
|
|
1207
|
+
if (!output) {
|
|
1208
|
+
return {};
|
|
1209
|
+
}
|
|
1210
|
+
if (output.kind !== "instance") {
|
|
1211
|
+
throw new Error("Expected instance node");
|
|
1212
|
+
}
|
|
1213
|
+
return output.resolvedInputs;
|
|
1214
|
+
}
|
|
1215
|
+
function getResolvedInjectionInstanceInputs(outputMap, instanceId) {
|
|
1216
|
+
const output = outputMap.get(`instance:${instanceId}`);
|
|
1217
|
+
if (!output) {
|
|
1218
|
+
return [];
|
|
1219
|
+
}
|
|
1220
|
+
if (output.kind !== "instance") {
|
|
1221
|
+
throw new Error("Expected instance node");
|
|
1222
|
+
}
|
|
1223
|
+
return output.resolvedInjectionInputs;
|
|
1224
|
+
}
|
|
1225
|
+
function getMatchedInjectionInstanceInputs(outputMap, instanceId) {
|
|
1226
|
+
const output = outputMap.get(`instance:${instanceId}`);
|
|
1227
|
+
if (!output) {
|
|
1228
|
+
return [];
|
|
1229
|
+
}
|
|
1230
|
+
if (output.kind !== "instance") {
|
|
1231
|
+
throw new Error("Expected instance node");
|
|
1232
|
+
}
|
|
1233
|
+
return output.matchedInjectionInputs;
|
|
1234
|
+
}
|
|
1235
|
+
function getResolvedInstanceOutputs(outputMap, instanceId) {
|
|
1236
|
+
const output = outputMap.get(`instance:${instanceId}`);
|
|
1237
|
+
if (!output) {
|
|
1238
|
+
return void 0;
|
|
1239
|
+
}
|
|
1240
|
+
if (output.kind !== "instance") {
|
|
1241
|
+
throw new Error("Expected instance node");
|
|
1242
|
+
}
|
|
1243
|
+
return output.resolvedOutputs;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
// src/shared/utils/async-batcher.ts
|
|
1247
|
+
function createAsyncBatcher(fn, { waitMs = 100, maxWaitTimeMs = 1e3 } = {}) {
|
|
1248
|
+
let batch = [];
|
|
1249
|
+
let activeTimeout = null;
|
|
1250
|
+
let maxWaitTimeout = null;
|
|
1251
|
+
let firstCallTimestamp = null;
|
|
1252
|
+
async function processBatch() {
|
|
1253
|
+
if (batch.length === 0) return;
|
|
1254
|
+
const currentBatch = batch;
|
|
1255
|
+
batch = [];
|
|
1256
|
+
await fn(currentBatch);
|
|
1257
|
+
if (maxWaitTimeout) {
|
|
1258
|
+
clearTimeout(maxWaitTimeout);
|
|
1259
|
+
maxWaitTimeout = null;
|
|
1260
|
+
}
|
|
1261
|
+
firstCallTimestamp = null;
|
|
1262
|
+
}
|
|
1263
|
+
function schedule() {
|
|
1264
|
+
if (activeTimeout) clearTimeout(activeTimeout);
|
|
1265
|
+
activeTimeout = setTimeout(() => {
|
|
1266
|
+
activeTimeout = null;
|
|
1267
|
+
void processBatch();
|
|
1268
|
+
}, waitMs);
|
|
1269
|
+
if (!firstCallTimestamp) {
|
|
1270
|
+
firstCallTimestamp = Date.now();
|
|
1271
|
+
maxWaitTimeout = setTimeout(() => {
|
|
1272
|
+
if (activeTimeout) clearTimeout(activeTimeout);
|
|
1273
|
+
activeTimeout = null;
|
|
1274
|
+
void processBatch();
|
|
1275
|
+
}, maxWaitTimeMs);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
return {
|
|
1279
|
+
/**
|
|
1280
|
+
* Add an item to the batch.
|
|
1281
|
+
*/
|
|
1282
|
+
call(item) {
|
|
1283
|
+
batch.push(item);
|
|
1284
|
+
schedule();
|
|
1285
|
+
},
|
|
1286
|
+
/**
|
|
1287
|
+
* Immediately flush the pending batch (if any).
|
|
1288
|
+
*/
|
|
1289
|
+
async flush() {
|
|
1290
|
+
if (activeTimeout) {
|
|
1291
|
+
clearTimeout(activeTimeout);
|
|
1292
|
+
activeTimeout = null;
|
|
1293
|
+
}
|
|
1294
|
+
if (maxWaitTimeout) {
|
|
1295
|
+
clearTimeout(maxWaitTimeout);
|
|
1296
|
+
maxWaitTimeout = null;
|
|
1297
|
+
}
|
|
1298
|
+
await processBatch();
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
// src/shared/utils/hash.ts
|
|
1304
|
+
function int32ToBytes(value) {
|
|
1305
|
+
const buffer = new ArrayBuffer(4);
|
|
1306
|
+
const view = new DataView(buffer);
|
|
1307
|
+
view.setInt32(0, value, true);
|
|
1308
|
+
return new Uint8Array(buffer);
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
// src/shared/utils/promise-tracker.ts
|
|
1312
|
+
var PromiseTracker = class {
|
|
1313
|
+
trackedPromises = /* @__PURE__ */ new Set();
|
|
1314
|
+
/**
|
|
1315
|
+
* Tracks a promise to ensure its rejection is handled inside the tracker's scope.
|
|
1316
|
+
*/
|
|
1317
|
+
track(promise) {
|
|
1318
|
+
const wrapped = promise.finally(() => this.trackedPromises.delete(promise));
|
|
1319
|
+
this.trackedPromises.add(wrapped);
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Waits for all tracked promises to resolve or reject.
|
|
1323
|
+
*/
|
|
1324
|
+
async waitForAll() {
|
|
1325
|
+
if (this.trackedPromises.size === 0) {
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
const toTrack = Array.from(this.trackedPromises);
|
|
1329
|
+
this.trackedPromises.clear();
|
|
1330
|
+
await waitAll(toTrack);
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
async function waitAll(promises) {
|
|
1334
|
+
const results = await Promise.allSettled(promises);
|
|
1335
|
+
const rejected = results.filter((p) => p.status === "rejected");
|
|
1336
|
+
if (!rejected.length) {
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
throw new AggregateError(
|
|
1340
|
+
rejected.map((p) => p.reason),
|
|
1341
|
+
"Some promises were rejected"
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
// src/shared/resolvers/input-hash.ts
|
|
1346
|
+
var InputHashResolver = class extends GraphResolver {
|
|
1347
|
+
getNodeDependencies({ resolvedInputs }) {
|
|
1348
|
+
const dependencies = [];
|
|
1349
|
+
for (const inputs of Object.values(resolvedInputs ?? {})) {
|
|
1350
|
+
for (const input of inputs) {
|
|
1351
|
+
dependencies.push(input.input.instanceId);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
return dependencies;
|
|
1355
|
+
}
|
|
1356
|
+
processNode({
|
|
1357
|
+
instance,
|
|
1358
|
+
component,
|
|
1359
|
+
resolvedInputs,
|
|
1360
|
+
sourceHash,
|
|
1361
|
+
state
|
|
1362
|
+
}) {
|
|
1363
|
+
const inputHashSink = [];
|
|
1364
|
+
inputHashSink.push(int32ToBytes(component.definitionHash));
|
|
1365
|
+
if (state?.inputHashNonce) {
|
|
1366
|
+
inputHashSink.push(int32ToBytes(state.inputHashNonce));
|
|
1367
|
+
}
|
|
1368
|
+
if (instance.args) {
|
|
1369
|
+
inputHashSink.push(encode(instance.args));
|
|
1370
|
+
}
|
|
1371
|
+
if (sourceHash) {
|
|
1372
|
+
inputHashSink.push(int32ToBytes(sourceHash));
|
|
1373
|
+
} else if (isUnitModel(component)) {
|
|
1374
|
+
this.logger.warn(
|
|
1375
|
+
{ instanceId: instance.id },
|
|
1376
|
+
"missing source hash for unit model, this may lead to incorrect input hash"
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
const sortedInputs = Object.entries(resolvedInputs).sort(([a], [b]) => a.localeCompare(b));
|
|
1380
|
+
const dependencyInstanceIds = /* @__PURE__ */ new Set();
|
|
1381
|
+
for (const [inputKey, inputs] of sortedInputs) {
|
|
1382
|
+
if (Object.keys(inputs).length === 0) {
|
|
1383
|
+
continue;
|
|
1384
|
+
}
|
|
1385
|
+
inputHashSink.push(Buffer.from(inputKey));
|
|
1386
|
+
const instanceIds = inputs.map((input) => input.input.instanceId).sort();
|
|
1387
|
+
for (const instanceId of instanceIds) {
|
|
1388
|
+
const dependency = this.outputs.get(instanceId);
|
|
1389
|
+
if (!dependency) {
|
|
1390
|
+
this.logger.warn(
|
|
1391
|
+
{ instanceId, dependentInstanceId: instance.id },
|
|
1392
|
+
"missing dependency when calculating input hash, this may lead to incorrect input hash"
|
|
1393
|
+
);
|
|
1394
|
+
continue;
|
|
1395
|
+
}
|
|
1396
|
+
inputHashSink.push(int32ToBytes(dependency.inputHash));
|
|
1397
|
+
inputHashSink.push(int32ToBytes(dependency.outputHash));
|
|
1398
|
+
dependencyInstanceIds.add(instanceId);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
const dependencyOutputHashSink = [];
|
|
1402
|
+
const sortedDependencyInstanceIds = Array.from(dependencyInstanceIds).sort();
|
|
1403
|
+
for (const dependencyInstanceId of sortedDependencyInstanceIds) {
|
|
1404
|
+
const dependency = this.outputs.get(dependencyInstanceId);
|
|
1405
|
+
if (!dependency) {
|
|
1406
|
+
this.logger.warn(
|
|
1407
|
+
{ instanceId: dependencyInstanceId, dependentInstanceId: instance.id },
|
|
1408
|
+
"missing dependency when calculating dependency output hash, this may lead to incorrect input hash"
|
|
1409
|
+
);
|
|
1410
|
+
continue;
|
|
1411
|
+
}
|
|
1412
|
+
dependencyOutputHashSink.push(int32ToBytes(dependency.outputHash));
|
|
1413
|
+
}
|
|
1414
|
+
return {
|
|
1415
|
+
inputHash: crc32(Buffer.concat(inputHashSink)),
|
|
1416
|
+
dependencyOutputHash: crc32(Buffer.concat(dependencyOutputHashSink)),
|
|
1417
|
+
outputHash: state?.outputHash ?? 0
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
|
|
1422
|
+
// src/shared/resolvers/state.ts
|
|
1423
|
+
var StateResolver = class extends GraphResolver {
|
|
1424
|
+
getNodeDependencies(node) {
|
|
1425
|
+
if (!node.lastOperationState) {
|
|
1426
|
+
return [];
|
|
1427
|
+
}
|
|
1428
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
1429
|
+
for (const inputs of Object.values(node.lastOperationState.resolvedInputs)) {
|
|
1430
|
+
for (const input of inputs) {
|
|
1431
|
+
dependencies.add(input.instanceId);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return Array.from(dependencies);
|
|
1435
|
+
}
|
|
1436
|
+
processNode() {
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
};
|
|
1440
|
+
var ValidationResolver = class extends GraphResolver {
|
|
1441
|
+
getNodeDependencies({ resolvedInputs }) {
|
|
1442
|
+
const dependencies = [];
|
|
1443
|
+
for (const inputs of Object.values(resolvedInputs)) {
|
|
1444
|
+
for (const input of inputs) {
|
|
1445
|
+
dependencies.push(input.input.instanceId);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
return dependencies;
|
|
1449
|
+
}
|
|
1450
|
+
processNode({ instance, component, state, resolvedInputs }) {
|
|
1451
|
+
const ajv = new Ajv({ strict: false });
|
|
1452
|
+
this.logger.debug({ instanceId: instance.id }, "validating instance");
|
|
1453
|
+
const validationErrors = [];
|
|
1454
|
+
for (const [name, argument] of Object.entries(component.args)) {
|
|
1455
|
+
try {
|
|
1456
|
+
const value = parseArgumentValue(instance.args?.[name]);
|
|
1457
|
+
if (!argument.required && value === void 0) {
|
|
1458
|
+
continue;
|
|
1459
|
+
}
|
|
1460
|
+
if (!ajv.validate(argument.schema, value)) {
|
|
1461
|
+
this.logger.debug({ instanceId: instance.id, argumentName: name }, "invalid argument");
|
|
1462
|
+
validationErrors.push(
|
|
1463
|
+
`Invalid argument "${styles.blueBright.open}${name}${styles.reset.close}": ` + ajv.errorsText()
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
this.logger.debug(
|
|
1468
|
+
{ instanceId: instance.id, argumentName: name, error },
|
|
1469
|
+
"failed to validate argument"
|
|
1470
|
+
);
|
|
1471
|
+
validationErrors.push(
|
|
1472
|
+
`Failed to validate argument "${styles.blueBright.open}${name}${styles.reset.close}": ` + (error instanceof Error ? error.message : String(error))
|
|
1473
|
+
);
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
if (isUnitModel(component)) {
|
|
1477
|
+
for (const [secret, secretSchema] of Object.entries(component.secrets)) {
|
|
1478
|
+
if (secretSchema.required && !state?.secretNames?.includes(secret)) {
|
|
1479
|
+
validationErrors.push(
|
|
1480
|
+
`Missing required secret "${styles.blueBright.open}${secret}${styles.reset.close}"`
|
|
1481
|
+
);
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
for (const [key, inputs] of Object.entries(resolvedInputs)) {
|
|
1486
|
+
for (const input of inputs) {
|
|
1487
|
+
const inputInstance = this.outputs.get(input.input.instanceId);
|
|
1488
|
+
if (inputInstance?.status !== "ok") {
|
|
1489
|
+
validationErrors.push(
|
|
1490
|
+
`Invalid input "${styles.blueBright.open}${key}${styles.reset.close}":
|
|
1491
|
+
"${styles.blueBright.open}${input.input.instanceId}${styles.reset.close}" has validation errors`
|
|
1492
|
+
);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
for (const [name, input] of Object.entries(component.inputs)) {
|
|
1497
|
+
if (!input.required) {
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
if (!resolvedInputs[name] || !resolvedInputs[name].length) {
|
|
1501
|
+
validationErrors.push(
|
|
1502
|
+
`Missing required input "${styles.blueBright.open}${name}${styles.reset.close}" of type "${styles.greenBright.open}${input.type}${styles.reset.close}"`
|
|
1503
|
+
);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
if (validationErrors.length === 0) {
|
|
1507
|
+
return { status: "ok" };
|
|
1508
|
+
}
|
|
1509
|
+
const numberPrefixLength = (validationErrors.length + 1).toString().length + 2;
|
|
1510
|
+
const formattedError = validationErrors.map((error, index) => {
|
|
1511
|
+
const lines = error.split("\n");
|
|
1512
|
+
const prefix = `${index + 1}. `;
|
|
1513
|
+
return lines.map((line, lineIndex) => {
|
|
1514
|
+
const linePrefix = lineIndex === 0 ? prefix : " ".repeat(numberPrefixLength);
|
|
1515
|
+
return `${linePrefix}${line}`;
|
|
1516
|
+
}).join("\r\n");
|
|
1517
|
+
}).join("\r\n");
|
|
1518
|
+
return {
|
|
1519
|
+
status: "error",
|
|
1520
|
+
errorText: formattedError
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1525
|
+
// src/shared/resolvers/registry.ts
|
|
1526
|
+
var resolverFactories = {
|
|
1527
|
+
InputResolver,
|
|
1528
|
+
InputHashResolver,
|
|
1529
|
+
ValidationResolver,
|
|
1530
|
+
StateResolver
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
export { AccessError, BackendError, CannotDeleteLastUnlockMethodError, GraphResolver, InputHashResolver, InputResolver, InstanceLockLostError, InstanceLockedError, InstanceNotFoundError, InstanceStateNotFoundError, InvalidInstanceKindError, MAX_WORKER_START_ATTEMPTS, OperationNotFoundError, ProjectLockedError, ProjectNotFoundError, PromiseTracker, SystemSecretNames, ValidationResolver, WorkerVersionNotFoundError, apiKeyMetaSchema, apiKeyOutputSchema, apiKeyQuerySchema, applyLibraryUpdate, artifactOutputSchema, artifactQuerySchema, backendUnlockMethodSchema, codebaseLibrary, codebaseProjectModelStorage, collectionQueryResult, collectionQuerySchema, createAsyncBatcher, databaseProjectModelStorage, diffLibraries, extractDigestFromImage, finalInstanceOperationStatuses, finalOperationStatuses, forSchema, getAllDependents, getMatchedInjectionInstanceInputs, getResolvedHubInputs, getResolvedInjectionInstanceInputs, getResolvedInstanceInputs, getResolvedInstanceOutputs, getWorkerIdentity, globalProjectSpace, hasObjectMeta, hostPulumiBackend, instanceCustomStatusInputSchema, instanceLockEventSchema, instanceLockOutputSchema, instanceStateEventSchema, int32ToBytes, isFinalOperationStatus, isInstanceDeployed, isTransientInstanceOperationStatus, isTransientOperationStatus, isVirtualGhostInstance, librarySpecSchema, operationEventSchema, operationInputSchema, operationMetaSchema, operationOptionsSchema, operationOutputSchema, operationPhaseInstanceSchema, operationPhaseSchema, operationPhaseTypeSchema, operationStatusSchema, operationTypeSchema, pageDetailsOutputSchema, pageOutputSchema, pageQuerySchema, projectInputSchema, projectModelEventSchema, projectModelStorageSpecSchema, projectOutputSchema, projectUnlockStateSchema, projectUnlockSuiteSchema, pulumiBackendSpecSchema, resolverFactories, secretOutputSchema, secretQuerySchema, serviceAccountOutputSchema, serviceAccountQuerySchema, terminalDetailsOutputSchema, terminalOutputSchema, terminalQuerySchema, terminalSessionOutputSchema, terminalStatusSchema, toApiKeyOutput, toPageOutput, toSecretOutput, toTerminalDetailsOutput, toTerminalOutput, toTerminalSessionOutput, toWorkerOutput, toWorkerVersionOutput, triggerOutputSchema, triggerQuerySchema, unlockMethodInputSchema, unlockMethodMetaSchema, unlockMethodOutputSchema, unlockMethodType, waitAll, workerOutputSchema, workerQuerySchema, workerUnitRegistrationEventSchema, workerVersionOutputSchema, workerVersionStatusSchema };
|
|
1534
|
+
//# sourceMappingURL=chunk-5WVU2AK4.js.map
|
|
1535
|
+
//# sourceMappingURL=chunk-5WVU2AK4.js.map
|