@highstate/backend 0.9.18 → 0.9.20
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-OU5OQBLB.js → chunk-I7BWSAN6.js} +3 -28
- package/dist/{chunk-OU5OQBLB.js.map → chunk-I7BWSAN6.js.map} +1 -1
- package/dist/chunk-RC6Q3XQQ.js +1547 -0
- package/dist/chunk-RC6Q3XQQ.js.map +1 -0
- 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 +7590 -7289
- 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 +32 -0
- package/prisma/project/artifact.prisma +52 -0
- package/prisma/project/custom-status.prisma +46 -0
- package/prisma/project/evaluation.prisma +45 -0
- package/prisma/project/instance.prisma +157 -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 +49 -0
- package/prisma/project/secret.prisma +54 -0
- package/prisma/project/service-account.prisma +42 -0
- package/prisma/project/terminal.prisma +107 -0
- package/prisma/project/trigger.prisma +37 -0
- package/prisma/project/unlock-method.prisma +46 -0
- package/prisma/project/worker.prisma +169 -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 +469 -130
- package/src/business/secret.ts +177 -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 +440 -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 +40 -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 +74 -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 +235 -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 +9 -2
- 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
package/src/business/project.ts
CHANGED
|
@@ -1,95 +1,114 @@
|
|
|
1
1
|
import type { Logger } from "pino"
|
|
2
|
-
import type {
|
|
3
|
-
import type { InputUnlockMethod, Project } from "../shared"
|
|
4
|
-
import type { RandomProvider } from "../common"
|
|
5
|
-
import type { ProjectUnlockService } from "./project-unlock"
|
|
6
|
-
import type { ProjectBackend, ProjectEvaluationSubsystem } from "../project"
|
|
7
|
-
import type { LockManager } from "../lock"
|
|
8
|
-
import type { PubSubManager } from "../pubsub"
|
|
2
|
+
import type { DatabaseManager, Project } from "../database"
|
|
9
3
|
import type { LibraryBackend } from "../library"
|
|
4
|
+
import type { ProjectEvaluationSubsystem, ProjectModelBackend } from "../project-model"
|
|
5
|
+
import type { PubSubManager } from "../pubsub"
|
|
6
|
+
import type { ProjectModelService } from "./project-model"
|
|
7
|
+
import type { ProjectUnlockService } from "./project-unlock"
|
|
10
8
|
import {
|
|
11
|
-
isUnitModel,
|
|
12
9
|
type HubModel,
|
|
13
10
|
type HubModelPatch,
|
|
14
11
|
type InstanceId,
|
|
15
12
|
type InstanceModel,
|
|
16
13
|
type InstanceModelPatch,
|
|
14
|
+
isUnitModel,
|
|
17
15
|
} from "@highstate/contract"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class ProjectNameConflictError extends Error {
|
|
33
|
-
constructor(readonly projectName: string) {
|
|
34
|
-
super(`Project with name "${projectName}" already exists`)
|
|
35
|
-
this.name = "ProjectNameConflictError"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
16
|
+
import { createId } from "@paralleldrive/cuid2"
|
|
17
|
+
import { createProjectLogger } from "../common"
|
|
18
|
+
import { projectDatabaseVersion } from "../database/abstractions"
|
|
19
|
+
import {
|
|
20
|
+
type FullProjectModel,
|
|
21
|
+
forSchema,
|
|
22
|
+
type ProjectInput,
|
|
23
|
+
type ProjectModelStorageSpec,
|
|
24
|
+
ProjectNotFoundError,
|
|
25
|
+
type ProjectOutput,
|
|
26
|
+
projectOutputSchema,
|
|
27
|
+
type UnlockMethodInput,
|
|
28
|
+
} from "../shared"
|
|
29
|
+
import { includeForInstanceState, mapInstanceStateResult } from "./instance-state"
|
|
38
30
|
|
|
39
31
|
export class ProjectService {
|
|
40
32
|
constructor(
|
|
41
|
-
private readonly
|
|
33
|
+
private readonly database: DatabaseManager,
|
|
42
34
|
private readonly projectUnlockService: ProjectUnlockService,
|
|
43
35
|
private readonly projectEvaluationSubsystem: ProjectEvaluationSubsystem,
|
|
44
|
-
private readonly
|
|
36
|
+
private readonly projectModelService: ProjectModelService,
|
|
37
|
+
private readonly projectModelBackends: Record<string, ProjectModelBackend>,
|
|
45
38
|
private readonly libraryBackend: LibraryBackend,
|
|
46
|
-
private readonly lockManager: LockManager,
|
|
47
39
|
private readonly pubsubManager: PubSubManager,
|
|
48
|
-
private readonly random: RandomProvider,
|
|
49
40
|
private readonly logger: Logger,
|
|
50
41
|
) {}
|
|
51
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Returns all projects in the system.
|
|
45
|
+
*/
|
|
46
|
+
async getProjects(): Promise<ProjectOutput[]> {
|
|
47
|
+
return await this.database.backend.project.findMany({
|
|
48
|
+
select: forSchema(projectOutputSchema),
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Creates a new project with the given input and unlock method.
|
|
54
|
+
*
|
|
55
|
+
* This will set up the project database and persist the unlock method.
|
|
56
|
+
*
|
|
57
|
+
* @param projectInput The input for the new project.
|
|
58
|
+
* @param unlockMethodInput The unlock method to use for the new project.
|
|
59
|
+
*/
|
|
52
60
|
async createProject(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
unlockMethod: InputUnlockMethod,
|
|
61
|
+
projectInput: ProjectInput,
|
|
62
|
+
unlockMethodInput: UnlockMethodInput,
|
|
56
63
|
): Promise<Project> {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
64
|
+
// start by generating a random ID
|
|
65
|
+
const projectId = createId()
|
|
66
|
+
const logger = createProjectLogger(this.logger, projectId)
|
|
67
|
+
|
|
68
|
+
logger.info("creating new project")
|
|
69
|
+
|
|
70
|
+
// setup project database
|
|
71
|
+
const [encryptedMasterKey, unlockSuite] = await this.projectUnlockService.setupProjectDatabase(
|
|
72
|
+
projectId,
|
|
73
|
+
unlockMethodInput,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
logger.info("project database set up")
|
|
77
|
+
|
|
78
|
+
// finally, create the project in the database
|
|
79
|
+
const project = await this.database.backend.project.create({
|
|
80
|
+
data: {
|
|
81
|
+
id: projectId,
|
|
82
|
+
name: projectInput.name,
|
|
83
|
+
meta: projectInput.meta,
|
|
84
|
+
databaseVersion: projectDatabaseVersion,
|
|
85
|
+
encryptedMasterKey,
|
|
86
|
+
unlockSuite,
|
|
87
|
+
spaceId: projectInput.spaceId,
|
|
88
|
+
modelStorageId: projectInput.modelStorageId,
|
|
89
|
+
libraryId: projectInput.libraryId,
|
|
90
|
+
pulumiBackendId: projectInput.pulumiBackendId,
|
|
91
|
+
},
|
|
92
|
+
})
|
|
82
93
|
|
|
83
|
-
|
|
94
|
+
logger.info("project successfully created")
|
|
84
95
|
|
|
85
|
-
|
|
96
|
+
return project
|
|
97
|
+
}
|
|
86
98
|
|
|
87
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Returns the project with the given ID.
|
|
101
|
+
*
|
|
102
|
+
* If the project does not exist, this will throw an error.
|
|
103
|
+
*
|
|
104
|
+
* @param projectId The ID of the project to get.
|
|
105
|
+
*/
|
|
106
|
+
async getProjectOrThrow(projectId: string): Promise<ProjectOutput> {
|
|
107
|
+
const project = await this.database.backend.project.findUnique({
|
|
108
|
+
where: { id: projectId },
|
|
109
|
+
select: forSchema(projectOutputSchema),
|
|
88
110
|
})
|
|
89
|
-
}
|
|
90
111
|
|
|
91
|
-
async getProjectOrThrow(projectId: string): Promise<Project> {
|
|
92
|
-
const project = await this.stateManager.getProjectRepository().get(projectId)
|
|
93
112
|
if (!project) {
|
|
94
113
|
throw new ProjectNotFoundError(projectId)
|
|
95
114
|
}
|
|
@@ -98,25 +117,18 @@ export class ProjectService {
|
|
|
98
117
|
}
|
|
99
118
|
|
|
100
119
|
/**
|
|
101
|
-
* Get the project model containing instances, hubs +
|
|
120
|
+
* Get the project model containing instances, hubs + virtual and ghost instances.
|
|
102
121
|
*
|
|
103
122
|
* @param projectId The ID of the project to get the model for.
|
|
104
123
|
* @param signal Optional abort signal for cancellation.
|
|
105
124
|
*/
|
|
106
|
-
async getProjectModel(projectId: string
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
])
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
instances: instances.filter(instance => instance.type in library.components),
|
|
117
|
-
hubs,
|
|
118
|
-
virtualInstances: virtualInstances.filter(instance => instance.type in library.components),
|
|
119
|
-
}
|
|
125
|
+
async getProjectModel(projectId: string): Promise<FullProjectModel> {
|
|
126
|
+
const [projectModel] = await this.projectModelService.getProjectModel(projectId, {
|
|
127
|
+
includeVirtualInstances: true,
|
|
128
|
+
includeGhostInstances: true,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
return projectModel
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
/**
|
|
@@ -131,24 +143,43 @@ export class ProjectService {
|
|
|
131
143
|
instanceId: InstanceId,
|
|
132
144
|
newName: string,
|
|
133
145
|
): Promise<InstanceModel> {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
try {
|
|
147
|
+
// rename the instance in the model
|
|
148
|
+
const { project, backend, spec } = await this.getProjectWithBackend(projectId)
|
|
149
|
+
const instance = await backend.renameInstance(project, spec, instanceId, newName)
|
|
150
|
+
|
|
151
|
+
// rename in the database state
|
|
152
|
+
const database = await this.database.forProject(projectId)
|
|
153
|
+
|
|
154
|
+
await database.$transaction(async tx => {
|
|
155
|
+
const state = await tx.instanceState.findUnique({
|
|
156
|
+
where: { instanceId },
|
|
157
|
+
select: { id: true },
|
|
142
158
|
})
|
|
143
159
|
|
|
144
|
-
|
|
160
|
+
if (!state) {
|
|
161
|
+
// ignore if state doesn't exist yet
|
|
162
|
+
return
|
|
163
|
+
}
|
|
145
164
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
165
|
+
await tx.instanceState.update({
|
|
166
|
+
where: { id: state.id },
|
|
167
|
+
data: { instanceId: instance.id },
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
await this.pubsubManager.publish(["project-model", projectId], {
|
|
172
|
+
updatedInstances: [instance],
|
|
173
|
+
deletedInstanceIds: [instanceId],
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
177
|
+
|
|
178
|
+
return instance
|
|
179
|
+
} catch (error) {
|
|
180
|
+
this.logger.error({ error, projectId, instanceId, newName }, "failed to rename instance")
|
|
181
|
+
throw error
|
|
182
|
+
}
|
|
152
183
|
}
|
|
153
184
|
|
|
154
185
|
/**
|
|
@@ -163,30 +194,28 @@ export class ProjectService {
|
|
|
163
194
|
instanceId: InstanceId,
|
|
164
195
|
patch: InstanceModelPatch,
|
|
165
196
|
): Promise<InstanceModel> {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
void this.projectEvaluationSubsystem.evaluateProject(project)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return instance
|
|
185
|
-
} catch (error) {
|
|
186
|
-
this.logger.error({ error, projectId, instanceId }, "failed to update instance")
|
|
187
|
-
throw error
|
|
197
|
+
try {
|
|
198
|
+
const { project, backend, spec } = await this.getProjectWithBackend(projectId)
|
|
199
|
+
const instance = await backend.updateInstance(project, spec, instanceId, patch)
|
|
200
|
+
const library = await this.libraryBackend.loadLibrary(project.libraryId)
|
|
201
|
+
|
|
202
|
+
await this.pubsubManager.publish(["project-model", projectId], {
|
|
203
|
+
updatedInstances: [instance],
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
if (!isUnitModel(library.components[instance.type]) && patch.args) {
|
|
207
|
+
// evaluate the project if arguments changed for composite instancer
|
|
208
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
209
|
+
} else if (patch.hubInputs || patch.injectionInputs || patch.inputs) {
|
|
210
|
+
// TODO: only evaluate if inputs changed for composite instances
|
|
211
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
188
212
|
}
|
|
189
|
-
|
|
213
|
+
|
|
214
|
+
return instance
|
|
215
|
+
} catch (error) {
|
|
216
|
+
this.logger.error({ error, projectId, instanceId }, "failed to update instance")
|
|
217
|
+
throw error
|
|
218
|
+
}
|
|
190
219
|
}
|
|
191
220
|
|
|
192
221
|
/**
|
|
@@ -196,21 +225,19 @@ export class ProjectService {
|
|
|
196
225
|
* @param instanceId The ID of the instance to delete.
|
|
197
226
|
*/
|
|
198
227
|
async deleteInstance(projectId: string, instanceId: InstanceId): Promise<void> {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
})
|
|
228
|
+
try {
|
|
229
|
+
const { project, backend, spec } = await this.getProjectWithBackend(projectId)
|
|
230
|
+
await backend.deleteInstance(project, spec, instanceId)
|
|
231
|
+
|
|
232
|
+
await this.pubsubManager.publish(["project-model", projectId], {
|
|
233
|
+
deletedInstanceIds: [instanceId],
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
237
|
+
} catch (error) {
|
|
238
|
+
this.logger.error({ error, projectId, instanceId }, "failed to delete instance")
|
|
239
|
+
throw error
|
|
240
|
+
}
|
|
214
241
|
}
|
|
215
242
|
|
|
216
243
|
/**
|
|
@@ -221,23 +248,23 @@ export class ProjectService {
|
|
|
221
248
|
* @param patch The patch to apply to the hub.
|
|
222
249
|
*/
|
|
223
250
|
async updateHub(projectId: string, hubId: string, patch: HubModelPatch): Promise<HubModel> {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const hub = await this.projectBackend.updateHub(project, hubId, patch)
|
|
251
|
+
try {
|
|
252
|
+
const { project, backend, spec } = await this.getProjectWithBackend(projectId)
|
|
253
|
+
const hub = await backend.updateHub(project, spec, hubId, patch)
|
|
228
254
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
void this.projectEvaluationSubsystem.evaluateProject(project)
|
|
255
|
+
await this.pubsubManager.publish(["project-model", projectId], {
|
|
256
|
+
updatedHubs: [hub],
|
|
257
|
+
})
|
|
234
258
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
this.logger.error({ error, projectId, hubId }, "failed to update hub")
|
|
238
|
-
throw error
|
|
259
|
+
if (patch.inputs || patch.injectionInputs) {
|
|
260
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
239
261
|
}
|
|
240
|
-
|
|
262
|
+
|
|
263
|
+
return hub
|
|
264
|
+
} catch (error) {
|
|
265
|
+
this.logger.error({ error, projectId, hubId }, "failed to update hub")
|
|
266
|
+
throw error
|
|
267
|
+
}
|
|
241
268
|
}
|
|
242
269
|
|
|
243
270
|
/**
|
|
@@ -247,21 +274,19 @@ export class ProjectService {
|
|
|
247
274
|
* @param hubId The ID of the hub to delete.
|
|
248
275
|
*/
|
|
249
276
|
async deleteHub(projectId: string, hubId: string): Promise<void> {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
})
|
|
277
|
+
try {
|
|
278
|
+
const { project, backend, spec } = await this.getProjectWithBackend(projectId)
|
|
279
|
+
await backend.deleteHub(project, spec, hubId)
|
|
280
|
+
|
|
281
|
+
await this.pubsubManager.publish(["project-model", projectId], {
|
|
282
|
+
deletedHubIds: [hubId],
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
286
|
+
} catch (error) {
|
|
287
|
+
this.logger.error({ error, projectId, hubId }, "failed to delete hub")
|
|
288
|
+
throw error
|
|
289
|
+
}
|
|
265
290
|
}
|
|
266
291
|
|
|
267
292
|
/**
|
|
@@ -276,24 +301,107 @@ export class ProjectService {
|
|
|
276
301
|
instances: InstanceModel[],
|
|
277
302
|
hubs: HubModel[],
|
|
278
303
|
): Promise<void> {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
await
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
304
|
+
try {
|
|
305
|
+
const database = await this.database.forProject(projectId)
|
|
306
|
+
|
|
307
|
+
const states = await database.$transaction(async tx => {
|
|
308
|
+
const { project, backend, spec } = await this.getProjectWithBackend(projectId)
|
|
309
|
+
await backend.createNodes(project, spec, instances, hubs)
|
|
310
|
+
|
|
311
|
+
// ensure instance states exist for created instances
|
|
312
|
+
return await Promise.all(
|
|
313
|
+
instances.map(async instance => {
|
|
314
|
+
const result = await tx.instanceState.upsert({
|
|
315
|
+
where: { instanceId: instance.id },
|
|
316
|
+
create: {
|
|
317
|
+
instanceId: instance.id,
|
|
318
|
+
kind: instance.kind,
|
|
319
|
+
source: "resident",
|
|
320
|
+
status: "undeployed",
|
|
321
|
+
},
|
|
322
|
+
update: {
|
|
323
|
+
// turn any virtual instance into resident
|
|
324
|
+
// the next evaluation will throw an error indicating the instance is now duplicate and will no longer produce this virtual instance
|
|
325
|
+
source: "resident",
|
|
326
|
+
},
|
|
327
|
+
// in case we restoring instance for existing state, to stream it correctly
|
|
328
|
+
include: includeForInstanceState({
|
|
329
|
+
includeEvaluationState: true,
|
|
330
|
+
includeExtra: true,
|
|
331
|
+
includeLastOperationState: true,
|
|
332
|
+
loadCustomStatuses: true,
|
|
333
|
+
}),
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
return mapInstanceStateResult(result)
|
|
337
|
+
}),
|
|
294
338
|
)
|
|
295
|
-
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
void this.pubsubManager.publish(["project-model", projectId], {
|
|
342
|
+
updatedHubs: hubs,
|
|
343
|
+
updatedInstances: instances,
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
for (const state of states) {
|
|
347
|
+
void this.pubsubManager.publish(["instance-state", projectId], { type: "updated", state })
|
|
296
348
|
}
|
|
349
|
+
|
|
350
|
+
void this.projectEvaluationSubsystem.evaluateProject(projectId)
|
|
351
|
+
} catch (error) {
|
|
352
|
+
this.logger.error(
|
|
353
|
+
{ error, projectId, instanceCount: instances.length, hubCount: hubs.length },
|
|
354
|
+
"failed to create many nodes",
|
|
355
|
+
)
|
|
356
|
+
throw error
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Get the project, backend, and storage spec in a single optimized SQL call.
|
|
362
|
+
*
|
|
363
|
+
* @param projectId The ID of the project.
|
|
364
|
+
* @returns Object containing project, backend, and spec.
|
|
365
|
+
*/
|
|
366
|
+
private async getProjectWithBackend(projectId: string): Promise<{
|
|
367
|
+
project: ProjectOutput
|
|
368
|
+
backend: ProjectModelBackend
|
|
369
|
+
spec: ProjectModelStorageSpec
|
|
370
|
+
}> {
|
|
371
|
+
const result = await this.database.backend.project.findUnique({
|
|
372
|
+
where: { id: projectId },
|
|
373
|
+
select: {
|
|
374
|
+
...forSchema(projectOutputSchema),
|
|
375
|
+
modelStorage: {
|
|
376
|
+
select: {
|
|
377
|
+
spec: true,
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
297
381
|
})
|
|
382
|
+
|
|
383
|
+
if (!result) {
|
|
384
|
+
throw new ProjectNotFoundError(projectId)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const { modelStorage, ...project } = result
|
|
388
|
+
const spec = modelStorage.spec
|
|
389
|
+
const backend = this.getProjectModelBackend(spec.type)
|
|
390
|
+
|
|
391
|
+
return { project, backend, spec }
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Get the appropriate project model backend for the given project.
|
|
396
|
+
*
|
|
397
|
+
* @param project The project to get the backend for.
|
|
398
|
+
* @returns The project model backend.
|
|
399
|
+
*/
|
|
400
|
+
private getProjectModelBackend(type: string): ProjectModelBackend {
|
|
401
|
+
const backend = this.projectModelBackends[type]
|
|
402
|
+
if (!backend) {
|
|
403
|
+
throw new Error(`Project model backend not found for type: ${type}`)
|
|
404
|
+
}
|
|
405
|
+
return backend
|
|
298
406
|
}
|
|
299
407
|
}
|