@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.
Files changed (331) hide show
  1. package/dist/{chunk-OU5OQBLB.js → chunk-I7BWSAN6.js} +3 -28
  2. package/dist/{chunk-OU5OQBLB.js.map → chunk-I7BWSAN6.js.map} +1 -1
  3. package/dist/chunk-RC6Q3XQQ.js +1547 -0
  4. package/dist/chunk-RC6Q3XQQ.js.map +1 -0
  5. package/dist/chunk-VB4YL327.js +139 -0
  6. package/dist/chunk-VB4YL327.js.map +1 -0
  7. package/dist/database/local/prisma.config.js +26 -0
  8. package/dist/database/local/prisma.config.js.map +1 -0
  9. package/dist/highstate.manifest.json +2 -1
  10. package/dist/index.js +7590 -7289
  11. package/dist/index.js.map +1 -1
  12. package/dist/library/package-resolution-worker.js +1 -1
  13. package/dist/library/package-resolution-worker.js.map +1 -1
  14. package/dist/library/worker/main.js +35 -29
  15. package/dist/library/worker/main.js.map +1 -1
  16. package/dist/shared/index.js +2 -2
  17. package/package.json +18 -9
  18. package/prisma/backend/_schema/layout.prisma +7 -0
  19. package/prisma/backend/_schema/library.prisma +17 -0
  20. package/prisma/backend/_schema/project.prisma +101 -0
  21. package/prisma/backend/_schema/pulumi.prisma +17 -0
  22. package/prisma/backend/postgresql/main.prisma +17 -0
  23. package/prisma/backend/sqlite/main.prisma +17 -0
  24. package/prisma/backend/sqlite/migrations/20250817070609_initiial/migration.sql +34 -0
  25. package/prisma/backend/sqlite/migrations/20250817104948_add_fields/migration.sql +59 -0
  26. package/prisma/backend/sqlite/migrations/20250818082732_add_models/migration.sql +41 -0
  27. package/prisma/backend/sqlite/migrations/20250818083106_a/migration.sql +19 -0
  28. package/prisma/backend/sqlite/migrations/20250818101945_hi/migration.sql +1 -0
  29. package/prisma/backend/sqlite/migrations/20250819082315_a/migration.sql +5 -0
  30. package/prisma/backend/sqlite/migrations/migration_lock.toml +3 -0
  31. package/prisma/project/api-key.prisma +32 -0
  32. package/prisma/project/artifact.prisma +52 -0
  33. package/prisma/project/custom-status.prisma +46 -0
  34. package/prisma/project/evaluation.prisma +45 -0
  35. package/prisma/project/instance.prisma +157 -0
  36. package/prisma/project/layout.prisma +23 -0
  37. package/prisma/project/lock.prisma +18 -0
  38. package/prisma/project/main.prisma +17 -0
  39. package/prisma/project/migrations/20250816081310_initial/migration.sql +300 -0
  40. package/prisma/project/migrations/20250816082523_test/migration.sql +72 -0
  41. package/prisma/project/migrations/20250818065643_update/migration.sql +42 -0
  42. package/prisma/project/migrations/20250818070758_a/migration.sql +8 -0
  43. package/prisma/project/migrations/20250818070913_a/migration.sql +8 -0
  44. package/prisma/project/migrations/20250818082720_add_motels/migration.sql +11 -0
  45. package/prisma/project/migrations/20250818112523_hello/migration.sql +35 -0
  46. package/prisma/project/migrations/20250819082305_a/migration.sql +14 -0
  47. package/prisma/project/migrations/20250819165004_add_missing_fields/migration.sql +216 -0
  48. package/prisma/project/migrations/20250819171309_a/migration.sql +22 -0
  49. package/prisma/project/migrations/20250820113949_a/migration.sql +66 -0
  50. package/prisma/project/migrations/20250820144256_b/migration.sql +31 -0
  51. package/prisma/project/migrations/20250820145547_a/migration.sql +24 -0
  52. package/prisma/project/migrations/20250820182517_b/migration.sql +2 -0
  53. package/prisma/project/migrations/20250821172324_a/migration.sql +2 -0
  54. package/prisma/project/migrations/20250822081339_a/migration.sql +219 -0
  55. package/prisma/project/migrations/20250822083742_b/migration.sql +1 -0
  56. package/prisma/project/migrations/20250822105134_boom/migration.sql +1 -0
  57. package/prisma/project/migrations/20250822141028_b/migration.sql +1 -0
  58. package/prisma/project/migrations/20250822142342_b/migration.sql +16 -0
  59. package/prisma/project/migrations/20250824072720_a/migration.sql +1 -0
  60. package/prisma/project/migrations/20250824093656_b/migration.sql +21 -0
  61. package/prisma/project/migrations/20250825082518_a/migration.sql +1 -0
  62. package/prisma/project/migrations/20250825085343_b/migration.sql +1 -0
  63. package/prisma/project/migrations/20250825091312_a/migration.sql +1 -0
  64. package/prisma/project/migrations/20250903095431_hi/migration.sql +44 -0
  65. package/prisma/project/migrations/20250903174255_a/migration.sql +24 -0
  66. package/prisma/project/migrations/20250908095205_hi/migration.sql +18 -0
  67. package/prisma/project/migrations/20250909155857_hi/migration.sql +15 -0
  68. package/prisma/project/migrations/migration_lock.toml +3 -0
  69. package/prisma/project/model.prisma +37 -0
  70. package/prisma/project/operation.prisma +148 -0
  71. package/prisma/project/page.prisma +49 -0
  72. package/prisma/project/secret.prisma +54 -0
  73. package/prisma/project/service-account.prisma +42 -0
  74. package/prisma/project/terminal.prisma +107 -0
  75. package/prisma/project/trigger.prisma +37 -0
  76. package/prisma/project/unlock-method.prisma +46 -0
  77. package/prisma/project/worker.prisma +169 -0
  78. package/src/artifact/abstractions.ts +13 -13
  79. package/src/artifact/encryption.ts +30 -54
  80. package/src/artifact/factory.ts +6 -9
  81. package/src/artifact/local.ts +33 -46
  82. package/src/business/api-key.ts +24 -36
  83. package/src/business/artifact.test.ts +978 -0
  84. package/src/business/artifact.ts +136 -216
  85. package/src/business/evaluation.ts +328 -0
  86. package/src/business/index.ts +5 -2
  87. package/src/business/instance-lock.test.ts +1060 -0
  88. package/src/business/instance-lock.ts +387 -78
  89. package/src/business/instance-state.test.ts +735 -0
  90. package/src/business/instance-state.ts +582 -337
  91. package/src/business/operation.test.ts +439 -0
  92. package/src/business/operation.ts +174 -208
  93. package/src/business/project-model.ts +258 -0
  94. package/src/business/project-unlock.ts +168 -126
  95. package/src/business/project.ts +287 -179
  96. package/src/business/secret.test.ts +469 -130
  97. package/src/business/secret.ts +177 -217
  98. package/src/business/settings.test.ts +695 -0
  99. package/src/business/settings.ts +855 -0
  100. package/src/business/terminal-session.ts +90 -0
  101. package/src/business/unit-extra.test.ts +539 -0
  102. package/src/business/unit-extra.ts +160 -0
  103. package/src/business/worker.test.ts +356 -579
  104. package/src/business/worker.ts +238 -339
  105. package/src/common/codebase.ts +65 -0
  106. package/src/common/index.ts +3 -5
  107. package/src/common/logger.ts +5 -0
  108. package/src/common/utils.ts +4 -3
  109. package/src/config.ts +10 -11
  110. package/src/database/_generated/backend/postgresql/client.ts +72 -0
  111. package/src/database/_generated/backend/postgresql/commonInputTypes.ts +350 -0
  112. package/src/database/_generated/backend/postgresql/enums.ts +13 -0
  113. package/src/database/_generated/backend/postgresql/internal/class.ts +320 -0
  114. package/src/database/_generated/backend/postgresql/internal/prismaNamespace.ts +1238 -0
  115. package/src/database/_generated/backend/postgresql/models/Library.ts +1263 -0
  116. package/src/database/_generated/backend/postgresql/models/Project.ts +2175 -0
  117. package/src/database/_generated/backend/postgresql/models/ProjectModelStorage.ts +1263 -0
  118. package/src/database/_generated/backend/postgresql/models/ProjectSpace.ts +1602 -0
  119. package/src/database/_generated/backend/postgresql/models/PulumiBackend.ts +1263 -0
  120. package/src/database/_generated/backend/postgresql/models/UserWorkspaseLayout.ts +1065 -0
  121. package/src/database/_generated/backend/postgresql/models.ts +16 -0
  122. package/src/database/_generated/backend/postgresql/pjtg.ts +182 -0
  123. package/src/database/_generated/backend/sqlite/client.ts +72 -0
  124. package/src/database/_generated/backend/sqlite/commonInputTypes.ts +331 -0
  125. package/src/database/_generated/backend/sqlite/enums.ts +13 -0
  126. package/src/database/_generated/backend/sqlite/internal/class.ts +318 -0
  127. package/src/database/_generated/backend/sqlite/internal/prismaNamespace.ts +1207 -0
  128. package/src/database/_generated/backend/sqlite/models/Library.ts +1261 -0
  129. package/src/database/_generated/backend/sqlite/models/Project.ts +2169 -0
  130. package/src/database/_generated/backend/sqlite/models/ProjectModelStorage.ts +1261 -0
  131. package/src/database/_generated/backend/sqlite/models/ProjectSpace.ts +1599 -0
  132. package/src/database/_generated/backend/sqlite/models/PulumiBackend.ts +1261 -0
  133. package/src/database/_generated/backend/sqlite/models/UserWorkspaseLayout.ts +1063 -0
  134. package/src/database/_generated/backend/sqlite/models.ts +16 -0
  135. package/src/database/_generated/backend/sqlite/pjtg.ts +182 -0
  136. package/src/database/_generated/project/client.ts +204 -0
  137. package/src/database/_generated/project/commonInputTypes.ts +827 -0
  138. package/src/database/_generated/project/enums.ts +104 -0
  139. package/src/database/_generated/project/internal/class.ts +479 -0
  140. package/src/database/_generated/project/internal/prismaNamespace.ts +2974 -0
  141. package/src/database/_generated/project/models/ApiKey.ts +1506 -0
  142. package/src/database/_generated/project/models/Artifact.ts +2051 -0
  143. package/src/database/_generated/project/models/HubModel.ts +1125 -0
  144. package/src/database/_generated/project/models/InstanceCustomStatus.ts +1713 -0
  145. package/src/database/_generated/project/models/InstanceEvaluationState.ts +1312 -0
  146. package/src/database/_generated/project/models/InstanceLock.ts +1268 -0
  147. package/src/database/_generated/project/models/InstanceModel.ts +1125 -0
  148. package/src/database/_generated/project/models/InstanceOperationState.ts +1707 -0
  149. package/src/database/_generated/project/models/InstanceState.ts +4613 -0
  150. package/src/database/_generated/project/models/Operation.ts +1647 -0
  151. package/src/database/_generated/project/models/OperationLog.ts +1455 -0
  152. package/src/database/_generated/project/models/Page.ts +1838 -0
  153. package/src/database/_generated/project/models/Secret.ts +1692 -0
  154. package/src/database/_generated/project/models/ServiceAccount.ts +2165 -0
  155. package/src/database/_generated/project/models/Terminal.ts +2038 -0
  156. package/src/database/_generated/project/models/TerminalSession.ts +1454 -0
  157. package/src/database/_generated/project/models/TerminalSessionLog.ts +1280 -0
  158. package/src/database/_generated/project/models/Trigger.ts +1430 -0
  159. package/src/database/_generated/project/models/UnlockMethod.ts +1220 -0
  160. package/src/database/_generated/project/models/UserCompositeViewport.ts +1280 -0
  161. package/src/database/_generated/project/models/UserProjectViewport.ts +1059 -0
  162. package/src/database/_generated/project/models/Worker.ts +1459 -0
  163. package/src/database/_generated/project/models/WorkerUnitRegistration.ts +1524 -0
  164. package/src/database/_generated/project/models/WorkerVersion.ts +1974 -0
  165. package/src/database/_generated/project/models/WorkerVersionLog.ts +1318 -0
  166. package/src/database/_generated/project/models.ts +35 -0
  167. package/src/database/_generated/project/pjtg.ts +182 -0
  168. package/src/database/abstractions.ts +19 -0
  169. package/src/database/factory.ts +37 -0
  170. package/src/database/index.ts +6 -0
  171. package/src/database/local/backend.ts +134 -0
  172. package/src/database/local/index.ts +3 -0
  173. package/src/database/local/meta.ts +46 -0
  174. package/src/database/local/prisma.config.ts +25 -0
  175. package/src/database/local/project.ts +39 -0
  176. package/src/database/manager.ts +181 -0
  177. package/src/database/migrate.ts +35 -0
  178. package/src/database/prisma.ts +56 -0
  179. package/src/database/well-known.ts +38 -0
  180. package/src/index.ts +4 -4
  181. package/src/library/abstractions.ts +3 -5
  182. package/src/library/factory.ts +1 -1
  183. package/src/library/local.ts +81 -26
  184. package/src/library/package-resolution-worker.ts +1 -1
  185. package/src/library/worker/evaluator.ts +40 -23
  186. package/src/library/worker/loader.lite.ts +1 -1
  187. package/src/library/worker/main.ts +3 -10
  188. package/src/library/worker/protocol.ts +0 -1
  189. package/src/lock/index.ts +0 -1
  190. package/src/lock/manager.ts +0 -10
  191. package/src/orchestrator/manager.ts +190 -104
  192. package/src/orchestrator/operation-context.ts +357 -0
  193. package/src/orchestrator/operation-plan.destroy.test.md +357 -0
  194. package/src/orchestrator/operation-plan.destroy.test.ts +775 -0
  195. package/src/orchestrator/operation-plan.fixtures.ts +213 -0
  196. package/src/orchestrator/operation-plan.md +198 -0
  197. package/src/orchestrator/operation-plan.refresh.test.md +199 -0
  198. package/src/orchestrator/operation-plan.refresh.test.ts +367 -0
  199. package/src/orchestrator/operation-plan.ts +709 -0
  200. package/src/orchestrator/operation-plan.update.test.md +485 -0
  201. package/src/orchestrator/operation-plan.update.test.ts +1066 -0
  202. package/src/orchestrator/operation-workset.ts +233 -578
  203. package/src/orchestrator/operation.ts +440 -948
  204. package/src/orchestrator/plan-test-builder.ts +267 -0
  205. package/src/project-model/abstractions.ts +118 -0
  206. package/src/project-model/backends/codebase.ts +365 -0
  207. package/src/project-model/backends/database.ts +440 -0
  208. package/src/project-model/errors.ts +81 -0
  209. package/src/project-model/factory.ts +24 -0
  210. package/src/project-model/index.ts +4 -0
  211. package/src/project-model/utils.test.ts +544 -0
  212. package/src/project-model/utils.ts +242 -0
  213. package/src/pubsub/abstractions.ts +10 -1
  214. package/src/pubsub/factory.ts +4 -4
  215. package/src/pubsub/index.ts +1 -0
  216. package/src/pubsub/manager.ts +29 -13
  217. package/src/pubsub/memory.ts +31 -0
  218. package/src/runner/abstractions.ts +40 -41
  219. package/src/runner/artifact-env.ts +19 -8
  220. package/src/runner/factory.ts +6 -6
  221. package/src/runner/force-abort.ts +3 -6
  222. package/src/runner/local.ts +74 -67
  223. package/src/runner/pulumi.ts +23 -63
  224. package/src/services.ts +181 -123
  225. package/src/shared/models/backend/index.ts +3 -1
  226. package/src/shared/models/backend/library.ts +9 -1
  227. package/src/shared/models/backend/project.ts +43 -42
  228. package/src/shared/models/backend/pulumi.ts +14 -0
  229. package/src/shared/models/backend/unlock-method.ts +1 -1
  230. package/src/shared/models/backend/well-known.ts +58 -0
  231. package/src/shared/models/base.ts +40 -26
  232. package/src/shared/models/errors.ts +82 -1
  233. package/src/shared/models/index.ts +3 -2
  234. package/src/shared/models/prisma.ts +36 -0
  235. package/src/shared/models/project/api-key.ts +37 -59
  236. package/src/shared/models/project/artifact.ts +16 -76
  237. package/src/shared/models/project/custom-status.ts +12 -0
  238. package/src/shared/models/project/index.ts +8 -7
  239. package/src/shared/models/project/lock.ts +10 -78
  240. package/src/shared/models/project/model.ts +19 -1
  241. package/src/shared/models/project/operation.ts +235 -99
  242. package/src/shared/models/project/page.ts +37 -48
  243. package/src/shared/models/project/secret.ts +29 -89
  244. package/src/shared/models/project/service-account.ts +12 -17
  245. package/src/shared/models/project/state.ts +100 -407
  246. package/src/shared/models/project/terminal.ts +75 -88
  247. package/src/shared/models/project/trigger.ts +13 -49
  248. package/src/shared/models/project/unlock-method.ts +20 -26
  249. package/src/shared/models/project/worker.ts +89 -90
  250. package/src/shared/resolvers/graph-resolver.ts +21 -0
  251. package/src/shared/resolvers/index.ts +1 -1
  252. package/src/shared/resolvers/input-hash.ts +24 -14
  253. package/src/shared/resolvers/input.ts +9 -2
  254. package/src/shared/resolvers/registry.ts +5 -4
  255. package/src/shared/resolvers/state.ts +12 -1
  256. package/src/shared/resolvers/validation.ts +7 -3
  257. package/src/shared/utils/index.ts +1 -2
  258. package/src/shared/utils/promise-tracker.ts +30 -3
  259. package/src/terminal/abstractions.ts +1 -1
  260. package/src/terminal/docker.ts +3 -3
  261. package/src/terminal/manager.ts +102 -118
  262. package/src/test-utils/database.ts +119 -0
  263. package/src/test-utils/index.ts +2 -0
  264. package/src/test-utils/services.ts +134 -0
  265. package/src/unlock/abstractions.ts +5 -23
  266. package/src/unlock/memory.ts +9 -14
  267. package/src/worker/abstractions.ts +7 -4
  268. package/src/worker/docker.ts +14 -19
  269. package/src/worker/manager.ts +366 -97
  270. package/dist/chunk-NAAIDR4U.js +0 -8499
  271. package/dist/chunk-NAAIDR4U.js.map +0 -1
  272. package/dist/chunk-Y7DXREVO.js +0 -1745
  273. package/dist/chunk-Y7DXREVO.js.map +0 -1
  274. package/dist/magic-string.es-5ABAC4JN.js +0 -1292
  275. package/dist/magic-string.es-5ABAC4JN.js.map +0 -1
  276. package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +0 -356
  277. package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +0 -274
  278. package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +0 -223
  279. package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +0 -147
  280. package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +0 -280
  281. package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +0 -360
  282. package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +0 -215
  283. package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +0 -427
  284. package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +0 -217
  285. package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +0 -132
  286. package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +0 -454
  287. package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +0 -426
  288. package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +0 -372
  289. package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +0 -383
  290. package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +0 -245
  291. package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +0 -174
  292. package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +0 -432
  293. package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +0 -220
  294. package/src/business/backend-unlock.ts +0 -10
  295. package/src/common/clock.ts +0 -18
  296. package/src/common/performance.ts +0 -44
  297. package/src/common/random.ts +0 -68
  298. package/src/common/test/index.ts +0 -2
  299. package/src/common/test/render.ts +0 -98
  300. package/src/common/test/tracer.ts +0 -359
  301. package/src/hotstate/abstractions.ts +0 -48
  302. package/src/hotstate/factory.ts +0 -17
  303. package/src/hotstate/index.ts +0 -3
  304. package/src/hotstate/manager.ts +0 -192
  305. package/src/hotstate/memory.ts +0 -100
  306. package/src/hotstate/validation.ts +0 -100
  307. package/src/lock/test.ts +0 -108
  308. package/src/project/abstractions.ts +0 -78
  309. package/src/project/evaluation.ts +0 -248
  310. package/src/project/factory.ts +0 -11
  311. package/src/project/index.ts +0 -3
  312. package/src/project/local.ts +0 -417
  313. package/src/pubsub/local.ts +0 -36
  314. package/src/pubsub/validation.ts +0 -33
  315. package/src/shared/utils/args.ts +0 -25
  316. package/src/state/abstractions.ts +0 -289
  317. package/src/state/encryption.ts +0 -98
  318. package/src/state/factory.ts +0 -20
  319. package/src/state/index.ts +0 -7
  320. package/src/state/local/backend.ts +0 -106
  321. package/src/state/local/collection.ts +0 -361
  322. package/src/state/local/index.ts +0 -2
  323. package/src/state/manager.ts +0 -890
  324. package/src/state/memory/backend.ts +0 -70
  325. package/src/state/memory/collection.ts +0 -270
  326. package/src/state/memory/index.ts +0 -2
  327. package/src/state/repository/index.ts +0 -2
  328. package/src/state/repository/repository.index.ts +0 -193
  329. package/src/state/repository/repository.ts +0 -507
  330. package/src/state/test.ts +0 -457
  331. /package/src/{state → database/local}/keyring.ts +0 -0
@@ -1,139 +1,275 @@
1
- import { z } from "zod"
2
- import { objectMetaSchema } from "@highstate/contract"
1
+ import type { Operation, OperationStatus, OperationType } from "../../../database"
2
+ import { instanceIdSchema, objectMetaSchema, z } from "@highstate/contract"
3
3
 
4
- export const operationTypeSchema = z.enum(["update", "preview", "destroy", "recreate", "refresh"])
4
+ /**
5
+ * Phase type for operation execution.
6
+ */
7
+ export const operationPhaseTypeSchema = z.enum(["destroy", "update", "refresh"])
5
8
 
6
- export const operationStatusSchema = z.enum([
7
- "pending",
8
- "running",
9
- "completed",
10
- "failed",
11
- "cancelled",
12
- "failing",
13
- ])
14
-
15
- export const operationOptionsSchema = z.object({
9
+ /**
10
+ * Instance information for operation phase.
11
+ */
12
+ export const operationPhaseInstanceSchema = z.object({
16
13
  /**
17
- * Whether to force update all dependencies of the instances even if they are not changed.
18
- *
19
- * Only applicable for `update`, `preview`, `recreate`, and `refresh` operations.
20
- *
21
- * By default, `false`.
14
+ * The ID of the instance.
22
15
  */
23
- forceUpdateDependencies: z.boolean().default(false),
16
+ id: instanceIdSchema,
24
17
 
25
18
  /**
26
- * Whether to force update all children of the composite instances even if they are not changed.
27
- *
28
- * Only applicable for `update`, `preview`, `recreate`, and `refresh` operations.
29
- *
30
- * By default, `false`.
19
+ * The parent ID of the instance, either from the model or the state.
31
20
  */
32
- forceUpdateChildren: z.boolean().default(false),
21
+ parentId: z.string().optional(),
33
22
 
34
23
  /**
35
- * Whether to destroy all dependents of the instances when destroying them.
36
- *
37
- * Only applicable for `destroy` and `recreate` operations.
38
- *
39
- * By default, `true`.
40
- */
41
- destroyDependentInstances: z.boolean().default(true),
24
+ * Human-readable explanation of the decision.
25
+ * */
26
+ message: z.string(),
27
+ })
42
28
 
29
+ /**
30
+ * Single phase of operation execution.
31
+ */
32
+ export const operationPhaseSchema = z.object({
43
33
  /**
44
- * Whether to invoke destroy triggers when destroying the instances.
45
- *
46
- * Only applicable for `destroy`.
47
- *
48
- * By default, `true`.
34
+ * Type of phase being executed.
49
35
  */
50
- invokeDestroyTriggers: z.boolean().default(true),
36
+ type: operationPhaseTypeSchema,
51
37
 
52
38
  /**
53
- * Whether to delete unreachable resources when updating or destroying the instances.
54
- * This is potentially dangerous and should be used with caution.
55
- *
56
- * By default, `false`.
39
+ * List of instances to be processed in this phase.
57
40
  */
58
- deleteUnreachableResources: z.boolean().default(false),
41
+ instances: z.array(operationPhaseInstanceSchema),
42
+ })
59
43
 
60
- /**
61
- * Whether to delete the stack state even if the destroy operation fails.
62
- * This is very dangerous and should be used only when the stack is unrecoverable.
63
- *
64
- * By default, `false`.
65
- */
66
- forceDeleteState: z.boolean().default(false),
44
+ export type OperationPhase = z.infer<typeof operationPhaseSchema>
45
+ export type OperationPhaseType = z.infer<typeof operationPhaseTypeSchema>
46
+ export type OperationPhaseInstance = z.infer<typeof operationPhaseInstanceSchema>
67
47
 
68
- /**
69
- * Whether to allow partial updates of composite instances when updating, destroying or recreating them.
70
- *
71
- * If `true`, the operation will only update/destroy composite instance children that are directly referenced by other affected instances.
72
- * If `false`, the operation will update/destroy all children at of the composite instances at all levels if at least one of them is referenced by affected instances.
73
- *
74
- * By default, `false`.
75
- */
76
- allowPartialCompositeInstanceUpdates: z.boolean().default(false),
48
+ export const operationOptionsSchema = z
49
+ .object({
50
+ /**
51
+ * Force update all dependencies regardless of their current state.
52
+ *
53
+ * **Operation Behavior Impact:**
54
+ * - bypasses hash-based change detection for dependency chains;
55
+ * - includes **ALL** dependencies (up-to-date, out-of-date, and error states);
56
+ * - traverses the entire dependency graph from requested instances.
57
+ *
58
+ * **Usage with other options:**
59
+ * - combined with `forceUpdateChildren`: updates entire dependency tree **AND** all composite children;
60
+ * - independent of `allowPartialCompositeInstanceCreation`: affects dependency traversal, not composite logic.
61
+ */
62
+ forceUpdateDependencies: z.boolean().default(false),
77
63
 
78
- /**
79
- * Whether to refresh the state before running the operation.
80
- *
81
- * By default, `false`.
82
- */
83
- refresh: z.boolean().default(false),
84
- })
64
+ /**
65
+ * Force update all children of composite instances regardless of their state.
66
+ *
67
+ * **Operation Behavior Impact:**
68
+ * - overrides selective child inclusion logic for composites;
69
+ * - includes **ALL** children of affected composites (up-to-date, out-of-date, and error states);
70
+ * - applied after dependency traversal and parent inclusion.
71
+ *
72
+ * **Usage with other options:**
73
+ * - combined with `forceUpdateDependencies`: creates comprehensive force-update behavior;
74
+ * - overrides `allowPartialCompositeInstanceCreation`: when enabled, **ALL** children are included regardless of existence.
75
+ */
76
+ forceUpdateChildren: z.boolean().default(false),
85
77
 
86
- export const operationRequestSchema = z.object({
87
- projectId: z.string(),
88
- type: operationTypeSchema,
89
- instanceIds: z.array(z.string()),
90
- options: operationOptionsSchema.partial().optional(),
91
- })
78
+ /**
79
+ * Include dependent instances when destroying instances.
80
+ *
81
+ * **Operation Behavior Impact:**
82
+ * - extends destroy operations to include instances that depend on the target;
83
+ * - traverses the dependency graph in reverse (dependents, not dependencies);
84
+ * - prevents orphaned instances that would fail without their dependencies.
85
+ *
86
+ * **Usage with other options:**
87
+ * - works with `invokeDestroyTriggers`: ensures triggers run for all dependents;
88
+ * - independent of update-related options.
89
+ */
90
+ destroyDependentInstances: z.boolean().default(true),
92
91
 
93
- export const operationSchema = z.object({
94
- id: z.uuidv7(),
95
- meta: objectMetaSchema,
96
- status: operationStatusSchema,
92
+ /**
93
+ * Execute destroy triggers when destroying instances.
94
+ *
95
+ * **Operation Behavior Impact:**
96
+ * - affects how individual units are destroyed (triggers vs direct deletion);
97
+ * - does not change which instances are selected for destruction;
98
+ * - controls trigger execution during the destruction phase.
99
+ *
100
+ * **Usage with other options:**
101
+ * - used with `destroyDependentInstances`: ensures triggers run for cascade deletions;
102
+ * - independent of update-related options.
103
+ */
104
+ invokeDestroyTriggers: z.boolean().default(true),
97
105
 
98
- error: z.string().nullable(),
106
+ /**
107
+ * Delete Pulumi resources that are no longer referenced in the state.
108
+ *
109
+ * **Operation Behavior Impact:**
110
+ * - does not affect which instances are selected for operations;
111
+ * - deletes orphaned Pulumi resources within individual instances.
112
+ *
113
+ * **Usage with other options:**
114
+ * - independent of instance selection options;
115
+ * - complements destroy-related options for thorough cleanup.
116
+ */
117
+ deleteUnreachableResources: z.boolean().default(false),
99
118
 
100
- type: operationTypeSchema,
119
+ /**
120
+ * Force deletion of instance state even if the destroy operation fails.
121
+ *
122
+ * **Operation Behavior Impact:**
123
+ * - forces state deletion even when destroy operations fail;
124
+ * - does not affect which instances are selected for operations;
125
+ * - bypasses normal destroy procedures as emergency fallback.
126
+ *
127
+ * **Usage with other options:**
128
+ * - used with destroy-related options when normal cleanup fails;
129
+ * - should be used cautiously as it can create state inconsistencies.
130
+ */
131
+ forceDeleteState: z.boolean().default(false),
101
132
 
102
- requestedInstanceIds: z.array(z.string()),
133
+ /**
134
+ * Allow partial update of composite instances without requiring all outdated children.
135
+ *
136
+ * **Operation Behavior Impact:**
137
+ * - controls whether composite operations must include all outdated children or only necessary ones;
138
+ * - when `false` (default): all outdated children of substantive composites are included in operations;
139
+ * - when `true`: only necessary children are included, allowing partial composite operations;
140
+ * - applied during composite child traversal phase for substantive composites only.
141
+ *
142
+ * **Usage with other options:**
143
+ * - overridden by `forceUpdateChildren`: when force is enabled, **ALL** children are included regardless;
144
+ * - independent of `forceUpdateDependencies`: affects composite logic, not dependency traversal.
145
+ */
146
+ allowPartialCompositeInstanceUpdate: z.boolean().default(false),
103
147
 
104
- instanceIdsToUpdate: z.array(z.string()).default(() => []),
105
- instanceIdsToDestroy: z.array(z.string()).default(() => []),
148
+ /**
149
+ * Allow partial destruction of composite instances during cascade operations.
150
+ *
151
+ * **Operation Behavior Impact:**
152
+ * - controls whether cascade destruction must include all children or only necessary ones;
153
+ * - when `false` (default): cascade destruction includes **ALL** children of affected composites;
154
+ * - when `true`: cascade destruction includes only directly dependent children;
155
+ * - does not affect explicit composite destruction (always destroys all children);
156
+ * - does not affect parent propagation when destroying sibling composites.
157
+ *
158
+ * **Usage with other options:**
159
+ * - works with `destroyDependentInstances`: controls completeness of cascade destruction;
160
+ * - independent of update-related options.
161
+ */
162
+ allowPartialCompositeInstanceDestruction: z.boolean().default(false),
106
163
 
107
- options: operationOptionsSchema,
164
+ /**
165
+ * Also refresh the state of instances during the operation.
166
+ *
167
+ * **Operation Behavior Impact:**
168
+ * - does not change which instances are selected for operations;
169
+ * - synchronizes state with actual infrastructure during the operation.
170
+ *
171
+ * **Usage with other options:**
172
+ * - additive with dependency resolution options: refreshes all selected instances;
173
+ * - works with both all operation types.
174
+ */
175
+ refresh: z.boolean().default(false),
108
176
 
109
- startedAt: z.number(),
110
- completedAt: z.number().nullable(),
111
- })
177
+ /**
178
+ * Enable debug logging for Pulumi engine and resource providers.
179
+ *
180
+ * **Security Note:**
181
+ * Debug mode may expose sensitive information including credentials in the logs.
182
+ * Use only when absolutely necessary for troubleshooting.
183
+ *
184
+ * **Implementation:**
185
+ * - sets Pulumi's debug option to true;
186
+ * - sets TF_LOG=DEBUG environment variable for Terraform providers.
187
+ */
188
+ debug: z.boolean().default(false),
189
+ })
190
+ .partial()
112
191
 
113
- export type OperationType = z.infer<typeof operationTypeSchema>
114
- export type OperationStatus = z.infer<typeof operationStatusSchema>
115
- export type Operation = z.infer<typeof operationSchema>
116
- export type OperationRequest = z.infer<typeof operationRequestSchema>
117
- export type OperationOptions = z.infer<typeof operationOptionsSchema>
192
+ export const operationTypeSchema = z.enum([
193
+ "update",
194
+ "preview",
195
+ "destroy",
196
+ "recreate",
197
+ "refresh",
198
+ ]) satisfies z.ZodType<OperationType>
118
199
 
119
- export function isFinalOperationStatus(status: OperationStatus): boolean {
120
- return status === "completed" || status === "failed" || status === "cancelled"
121
- }
200
+ export const operationStatusSchema = z.enum([
201
+ "pending",
202
+ "running",
203
+ "failing",
204
+ "completed",
205
+ "failed",
206
+ "cancelled",
207
+ ]) satisfies z.ZodType<OperationStatus>
122
208
 
123
- export const operationLogEntrySchema = z.tuple([
124
- z.uuidv7(),
125
- z.string(), // The log message
126
- ])
209
+ export const operationMetaSchema = objectMetaSchema.pick({
210
+ title: true,
211
+ description: true,
212
+ })
213
+
214
+ export const operationInputSchema = z.object({
215
+ projectId: z.string(),
216
+ type: operationTypeSchema,
217
+ instanceIds: z.array(instanceIdSchema).min(1),
218
+ options: operationOptionsSchema.partial().optional(),
219
+ meta: operationMetaSchema.optional(),
220
+ plan: operationPhaseSchema.array().optional(),
221
+ })
127
222
 
128
- export type OperationLogEntry = z.infer<typeof operationLogEntrySchema>
223
+ export type OperationMeta = z.infer<typeof operationMetaSchema>
224
+ export type OperationInput = z.infer<typeof operationInputSchema>
225
+ export type OperationOptions = z.infer<typeof operationOptionsSchema>
129
226
 
130
227
  export const operationEventSchema = z.discriminatedUnion("type", [
131
228
  z.object({
132
229
  type: z.literal("updated"),
133
- operation: operationSchema,
230
+ operation: z.custom<Operation>(),
134
231
  }),
135
232
  z.object({
136
233
  type: z.literal("deleted"),
137
234
  operationId: z.string(),
138
235
  }),
139
236
  ])
237
+
238
+ export const operationOutputSchema = z.object({
239
+ id: z.cuid2(),
240
+ type: operationTypeSchema,
241
+ status: operationStatusSchema,
242
+ meta: operationMetaSchema,
243
+ startedAt: z.date(),
244
+ updatedAt: z.date(),
245
+ finishedAt: z.date().nullable(),
246
+ })
247
+
248
+ export type OperationOutput = z.infer<typeof operationOutputSchema>
249
+
250
+ export type { Operation, OperationLog, OperationStatus, OperationType } from "../../../database"
251
+
252
+ export const finalOperationStatuses: OperationStatus[] = ["completed", "failed", "cancelled"]
253
+
254
+ /**
255
+ * Checks if an operation status is final (stable).
256
+ *
257
+ * Final statuses are: completed, failed, cancelled
258
+ * Transient statuses are: pending, running, failing
259
+ *
260
+ * @param status The operation status to check
261
+ * @returns True if the status is final
262
+ */
263
+ export function isFinalOperationStatus(status: OperationStatus): boolean {
264
+ return finalOperationStatuses.includes(status)
265
+ }
266
+
267
+ /**
268
+ * Checks if an operation status exists and is transient (not stable).
269
+ *
270
+ * @param status The operation status to check
271
+ * @returns True if the status is transient
272
+ */
273
+ export function isTransientOperationStatus(status?: OperationStatus): boolean {
274
+ return !!status && !finalOperationStatuses.includes(status)
275
+ }
@@ -1,57 +1,46 @@
1
+ import type { ServiceAccount } from "../../../database"
2
+ import {
3
+ commonObjectMetaSchema,
4
+ pageBlockSchema,
5
+ serviceAccountMetaSchema,
6
+ } from "@highstate/contract"
1
7
  import { z } from "zod"
2
- import { fileSchema, objectMetaSchema, userObjectMetaSchema } from "@highstate/contract"
3
-
4
- /**
5
- * Page block schema for database storage and unit API.
6
- */
7
- export const pageBlockSchema = z.union([
8
- z.object({
9
- type: z.literal("markdown"),
10
- content: z.string(),
11
- }),
12
- z.object({
13
- type: z.literal("qr"),
14
- content: z.string(),
15
- showContent: z.coerce.boolean(),
16
- language: z.string().optional(),
17
- }),
18
- z.object({
19
- type: z.literal("file"),
20
- ...fileSchema.shape,
21
- }),
22
- ])
23
-
24
- export type PageBlock = z.infer<typeof pageBlockSchema>
25
-
26
- /**
27
- * Page info for frontend display.
28
- * Contains only basic information visible to the frontend.
29
- */
30
- export const pageSchema = z.object({
31
- id: z.string(),
32
- instanceId: z.string().optional(),
33
- meta: objectMetaSchema,
8
+ import { collectionQuerySchema } from "../base"
9
+
10
+ export const pageOutputSchema = z.object({
11
+ id: z.cuid2(),
12
+ meta: commonObjectMetaSchema,
13
+ name: z.string().nullable(),
14
+ stateId: z.cuid2().nullable(),
15
+ serviceAccountId: z.cuid2().nullable(),
16
+ serviceAccountMeta: serviceAccountMetaSchema.nullable(),
17
+ createdAt: z.date(),
18
+ updatedAt: z.date(),
34
19
  })
35
20
 
36
- export type Page = z.infer<typeof pageSchema>
21
+ export type PageOutput = z.infer<typeof pageOutputSchema>
37
22
 
38
- /**
39
- * The content of a page separated from the page info.
40
- */
41
- export const pageContentSchema = z.object({
42
- id: z.string(),
43
- content: z.array(pageBlockSchema),
23
+ export const pageQuerySchema = collectionQuerySchema.extend({
24
+ serviceAccountId: z.string().optional(),
25
+ stateId: z.string().optional(),
26
+ artifactId: z.string().optional(),
44
27
  })
45
28
 
46
- export type PageContent = z.infer<typeof pageContentSchema>
29
+ export type PageQuery = z.infer<typeof pageQuerySchema>
47
30
 
48
- /**
49
- * Page schema for unit API.
50
- * This is what units provide - excludes id, instanceId and some fields from meta since those are set by the system.
51
- */
52
- export const unitPageSchema = pageContentSchema.omit({ id: true }).extend({
53
- name: z.string(),
54
- meta: userObjectMetaSchema,
31
+ export const pageDetailsOutputSchema = z.object({
32
+ ...pageOutputSchema.shape,
33
+ content: z.array(pageBlockSchema),
55
34
  })
56
35
 
57
- export type UnitPage = z.infer<typeof unitPageSchema>
36
+ export type PageDetailsOutput = z.infer<typeof pageDetailsOutputSchema>
37
+
38
+ export function toPageOutput(
39
+ page: Omit<PageOutput, "serviceAccountMeta">,
40
+ serviceAccount?: Pick<ServiceAccount, "meta"> | null,
41
+ ): PageOutput {
42
+ return {
43
+ ...page,
44
+ serviceAccountMeta: serviceAccount?.meta ?? null,
45
+ }
46
+ }
@@ -1,98 +1,38 @@
1
- import { z } from "zod"
2
- import { objectMetaSchema } from "@highstate/contract"
3
-
4
- export const secretDescriptorSchema = z.discriminatedUnion("type", [
5
- z.object({
6
- type: z.literal("system"),
7
- secretName: z.string(),
8
- }),
9
- z.object({
10
- type: z.literal("instance"),
11
- instanceId: z.string(),
12
- secretName: z.string(),
13
- }),
14
- ])
15
-
16
- /**
17
- * Secret info for frontend display.
18
- * Contains only basic information visible to the frontend without the actual secret value.
19
- */
20
- export const secretSchema = z.object({
21
- /**
22
- * The UUIDv7 of the secret generated when the secret is first created.
23
- */
24
- id: z.uuidv7(),
1
+ import type { ServiceAccount } from "../../../database"
2
+ import { globalCommonObjectMetaSchema, serviceAccountMetaSchema, z } from "@highstate/contract"
3
+ import { collectionQuerySchema } from "../base"
4
+
5
+ export const secretOutputSchema = z.object({
6
+ id: z.cuid2(),
7
+ meta: globalCommonObjectMetaSchema,
8
+ name: z.string().nullable(),
9
+ systemName: z.string().nullable(),
10
+ stateId: z.cuid2().nullable(),
11
+ serviceAccountId: z.cuid2().nullable(),
12
+ serviceAccountMeta: serviceAccountMetaSchema.nullable(),
13
+ createdAt: z.date(),
14
+ updatedAt: z.date(),
15
+ })
25
16
 
26
- /**
27
- * The metadata of the secret object.
28
- */
29
- meta: objectMetaSchema,
17
+ export type SecretOutput = z.infer<typeof secretOutputSchema>
30
18
 
31
- /**
32
- * The descriptor of the secret in the object form, which follows one of these formats when serialized:
33
- * - `system:<secretName>`
34
- * - `instance:<instanceId>:<secretName>`
35
- */
36
- descriptor: secretDescriptorSchema.optional(),
19
+ export const secretQuerySchema = collectionQuerySchema.extend({
20
+ serviceAccountId: z.string().optional(),
21
+ stateId: z.string().optional(),
37
22
  })
38
23
 
39
- export type SecretDescriptor = z.infer<typeof secretDescriptorSchema>
40
- export type Secret = z.infer<typeof secretSchema>
24
+ export type SecretQuery = z.infer<typeof secretQuerySchema>
41
25
 
42
- /**
43
- * Formats a SecretDescriptor into a string representation.
44
- *
45
- * @param descriptor The SecretDescriptor to format.
46
- * @returns The formatted secret descriptor string.
47
- */
48
- export function formatSecretDescriptor(descriptor: SecretDescriptor): string {
49
- switch (descriptor.type) {
50
- case "system":
51
- return `system:${descriptor.secretName}`
52
- case "instance":
53
- return `instance:${descriptor.instanceId}:${descriptor.secretName}`
26
+ export function toSecretOutput(
27
+ secret: Omit<SecretOutput, "serviceAccountMeta">,
28
+ serviceAccount?: Pick<ServiceAccount, "meta"> | null,
29
+ ): SecretOutput {
30
+ return {
31
+ ...secret,
32
+ serviceAccountMeta: serviceAccount?.meta ?? null,
54
33
  }
55
34
  }
56
35
 
57
- /**
58
- * Parses a secret descriptor string into a structured SecretDescriptor object.
59
- *
60
- * @param descriptorString The secret descriptor string to parse.
61
- * @returns The parsed SecretDescriptor object.
62
- * @throws Error if the secret descriptor format is invalid.
63
- */
64
- export function parseSecretDescriptor(descriptorString: string): SecretDescriptor {
65
- const parts = descriptorString.split(":")
66
- if (parts.length < 2) {
67
- throw new Error(`Invalid secret descriptor format: ${descriptorString}`)
68
- }
69
-
70
- switch (parts[0]) {
71
- case "system": {
72
- if (parts.length !== 2) {
73
- throw new Error(`Invalid system secret descriptor: ${descriptorString}`)
74
- }
75
- return { type: "system", secretName: parts[1] }
76
- }
77
-
78
- case "instance": {
79
- // instance format is "instance:<instanceId>:<secretName>" where instanceId may contain colons
80
- const secretName = parts[parts.length - 1]
81
- const instanceId = parts.slice(1, -1).join(":")
82
- if (!instanceId || !secretName) {
83
- throw new Error(`Invalid instance secret descriptor: ${descriptorString}`)
84
- }
85
- return { type: "instance", instanceId, secretName }
86
- }
87
-
88
- default:
89
- throw new Error(`Unknown secret descriptor type: ${parts[0]}`)
90
- }
36
+ export enum SystemSecretNames {
37
+ PulumiPassword = "pulumi-password",
91
38
  }
92
-
93
- export const WellKnownSecretDescriptors = {
94
- PulumiPassword: {
95
- type: "system",
96
- secretName: "pulumi-password",
97
- },
98
- } satisfies Record<string, SecretDescriptor>
@@ -1,22 +1,17 @@
1
- import { z } from "zod"
2
- import { objectMetaSchema } from "@highstate/contract"
1
+ import { serviceAccountMetaSchema, z } from "@highstate/contract"
2
+ import { collectionQuerySchema } from "../base"
3
3
 
4
- export const serviceAccountSchema = z.object({
5
- id: z.uuidv7(),
4
+ export const serviceAccountOutputSchema = z.object({
5
+ id: z.cuid2(),
6
+ meta: serviceAccountMetaSchema,
7
+ createdAt: z.date(),
8
+ updatedAt: z.date(),
9
+ })
6
10
 
7
- meta: objectMetaSchema.pick({
8
- title: true,
9
- description: true,
10
- icon: true,
11
- iconColor: true,
12
- createdAt: true,
13
- updatedAt: true,
14
- }),
11
+ export type ServiceAccountOutput = z.infer<typeof serviceAccountOutputSchema>
15
12
 
16
- /**
17
- * The ID of the artifact that stores the avatar image for this service account.
18
- */
19
- avatarArtifactId: z.string().optional(),
13
+ export const serviceAccountQuerySchema = collectionQuerySchema.extend({
14
+ artifactId: z.string().optional(),
20
15
  })
21
16
 
22
- export type ServiceAccount = z.infer<typeof serviceAccountSchema>
17
+ export type ServiceAccountQuery = z.infer<typeof serviceAccountQuerySchema>