@tailor-platform/sdk 2.0.0-next.3 → 2.0.0-next.5

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 (327) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/dist/aigateway-DR4Kwuik.mjs +9 -0
  3. package/dist/{aigateway-B3oZZE6v.mjs.map → aigateway-DR4Kwuik.mjs.map} +1 -1
  4. package/dist/{application-eHp9jXld.mjs → application-Bf8wxOi6.mjs} +701 -597
  5. package/dist/application-Bf8wxOi6.mjs.map +1 -0
  6. package/dist/application-CUkjzfij.mjs +3 -0
  7. package/dist/authconnection-CZvi9ANm.mjs +9 -0
  8. package/dist/authconnection-CZvi9ANm.mjs.map +1 -0
  9. package/dist/brand-Eo4pLXPJ.mjs.map +1 -1
  10. package/dist/cli/cache/bundle-cache.d.mts +2 -1
  11. package/dist/cli/cache/store.d.mts +1 -1
  12. package/dist/cli/commands/api/index.d.mts +1 -0
  13. package/dist/cli/commands/deploy/aigateway.d.mts +5 -1
  14. package/dist/cli/commands/deploy/application.d.mts +7 -1
  15. package/dist/cli/commands/deploy/apply-phases.d.mts +14 -1
  16. package/dist/cli/commands/deploy/auth.d.mts +5 -1
  17. package/dist/cli/commands/deploy/deploy.d.mts +5 -0
  18. package/dist/cli/commands/deploy/executor.d.mts +7 -1
  19. package/dist/cli/commands/deploy/function-registry.d.mts +5 -0
  20. package/dist/cli/commands/deploy/idp.d.mts +5 -1
  21. package/dist/cli/commands/deploy/resolver.d.mts +5 -1
  22. package/dist/cli/commands/deploy/secret-manager.d.mts +5 -1
  23. package/dist/cli/commands/deploy/staticwebsite.d.mts +5 -1
  24. package/dist/cli/commands/deploy/tailordb/index.d.mts +8 -1
  25. package/dist/cli/commands/deploy/types.d.mts +3 -1
  26. package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +3 -0
  27. package/dist/cli/commands/deploy/workflow.d.mts +4 -1
  28. package/dist/cli/commands/executor/get.d.mts +0 -1
  29. package/dist/cli/commands/executor/jobs.d.mts +0 -1
  30. package/dist/cli/commands/executor/list.d.mts +0 -1
  31. package/dist/cli/commands/executor/transform.d.mts +1 -0
  32. package/dist/cli/commands/executor/trigger.d.mts +0 -1
  33. package/dist/cli/commands/executor/webhook.d.mts +0 -1
  34. package/dist/cli/commands/function/get.d.mts +0 -1
  35. package/dist/cli/commands/function/list.d.mts +0 -1
  36. package/dist/cli/commands/function/transform.d.mts +1 -0
  37. package/dist/cli/commands/generate/service.d.mts +5 -1
  38. package/dist/cli/commands/machineuser/list.d.mts +0 -1
  39. package/dist/cli/commands/machineuser/token.d.mts +0 -1
  40. package/dist/cli/commands/oauth2client/get.d.mts +0 -1
  41. package/dist/cli/commands/oauth2client/list.d.mts +0 -1
  42. package/dist/cli/commands/oauth2client/transform.d.mts +1 -0
  43. package/dist/cli/commands/organization/folder/create.d.mts +0 -1
  44. package/dist/cli/commands/organization/folder/delete.d.mts +0 -1
  45. package/dist/cli/commands/organization/folder/get.d.mts +0 -1
  46. package/dist/cli/commands/organization/folder/list.d.mts +0 -1
  47. package/dist/cli/commands/organization/folder/update.d.mts +0 -1
  48. package/dist/cli/commands/organization/get.d.mts +0 -1
  49. package/dist/cli/commands/organization/list.d.mts +0 -1
  50. package/dist/cli/commands/organization/transform.d.mts +2 -0
  51. package/dist/cli/commands/organization/tree.d.mts +0 -1
  52. package/dist/cli/commands/organization/update.d.mts +0 -1
  53. package/dist/cli/commands/remove.d.mts +0 -1
  54. package/dist/cli/commands/show.d.mts +9 -4
  55. package/dist/cli/commands/tailordb/migrate/config.d.mts +0 -1
  56. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +16 -3
  57. package/dist/cli/commands/tailordb/migrate/generate.d.mts +0 -1
  58. package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +6 -0
  59. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
  60. package/dist/cli/commands/tailordb/truncate.d.mts +0 -1
  61. package/dist/cli/commands/workflow/executions.d.mts +0 -1
  62. package/dist/cli/commands/workflow/get.d.mts +2 -1
  63. package/dist/cli/commands/workflow/list.d.mts +0 -1
  64. package/dist/cli/commands/workflow/resume.d.mts +0 -1
  65. package/dist/cli/commands/workflow/start.d.mts +0 -1
  66. package/dist/cli/commands/workflow/status.d.mts +1 -0
  67. package/dist/cli/commands/workflow/transform.d.mts +1 -0
  68. package/dist/cli/commands/workflow/wait.d.mts +0 -1
  69. package/dist/cli/commands/workflow/waiter.d.mts +1 -1
  70. package/dist/cli/commands/workspace/app/health.d.mts +0 -1
  71. package/dist/cli/commands/workspace/app/list.d.mts +0 -1
  72. package/dist/cli/commands/workspace/app/transform.d.mts +2 -0
  73. package/dist/cli/commands/workspace/create.d.mts +0 -1
  74. package/dist/cli/commands/workspace/delete.d.mts +0 -1
  75. package/dist/cli/commands/workspace/get.d.mts +0 -1
  76. package/dist/cli/commands/workspace/list.d.mts +0 -1
  77. package/dist/cli/commands/workspace/restore.d.mts +0 -1
  78. package/dist/cli/commands/workspace/transform.d.mts +2 -0
  79. package/dist/cli/commands/workspace/user/invite.d.mts +0 -1
  80. package/dist/cli/commands/workspace/user/list.d.mts +0 -1
  81. package/dist/cli/commands/workspace/user/remove.d.mts +0 -1
  82. package/dist/cli/commands/workspace/user/transform.d.mts +1 -0
  83. package/dist/cli/commands/workspace/user/update.d.mts +0 -1
  84. package/dist/cli/index.d.mts +6 -3
  85. package/dist/cli/index.mjs +273 -104
  86. package/dist/cli/index.mjs.map +1 -1
  87. package/dist/cli/lib.d.mts +4 -2
  88. package/dist/cli/lib.mjs +4 -4
  89. package/dist/cli/lib.mjs.map +1 -1
  90. package/dist/cli/query/index.d.mts +4 -1
  91. package/dist/cli/services/application.d.mts +12 -1
  92. package/dist/cli/services/auth/service.d.mts +2 -0
  93. package/dist/cli/services/executor/service.d.mts +1 -1
  94. package/dist/cli/services/http-adapter/bundler.d.mts +3 -1
  95. package/dist/cli/services/http-adapter/service.d.mts +2 -1
  96. package/dist/cli/services/resolver/service.d.mts +1 -1
  97. package/dist/cli/services/tailordb/service.d.mts +3 -1
  98. package/dist/cli/services/workflow/bundler.d.mts +2 -1
  99. package/dist/cli/services/workflow/service.d.mts +1 -1
  100. package/dist/cli/shared/args.d.mts +1 -1
  101. package/dist/cli/shared/client.d.mts +1 -1
  102. package/dist/cli/shared/config-loader.d.mts +0 -1
  103. package/dist/cli/shared/context.d.mts +2 -1
  104. package/dist/cli/shared/script-executor.d.mts +0 -1
  105. package/dist/cli/shared/seed-chunker.d.mts +7 -3
  106. package/dist/cli/shared/type-generator.d.mts +0 -1
  107. package/dist/cli/ts-hook.mjs +43 -13
  108. package/dist/completion/zsh-worker.zsh +10 -10
  109. package/dist/configure/config/index.d.mts +0 -1
  110. package/dist/configure/config/types.d.mts +3 -1
  111. package/dist/configure/index.d.mts +17 -5
  112. package/dist/configure/index.mjs +309 -5
  113. package/dist/configure/index.mjs.map +1 -1
  114. package/dist/configure/services/aigateway/index.d.mts +0 -1
  115. package/dist/configure/services/aigateway/types.d.mts +0 -1
  116. package/dist/configure/services/auth/index.d.mts +0 -1
  117. package/dist/configure/services/auth/types.d.mts +15 -14
  118. package/dist/configure/services/executor/executor.d.mts +1 -1
  119. package/dist/configure/services/executor/index.d.mts +1 -0
  120. package/dist/configure/services/executor/operation.d.mts +2 -2
  121. package/dist/configure/services/executor/trigger/event.d.mts +0 -1
  122. package/dist/configure/services/executor/trigger/index.d.mts +0 -1
  123. package/dist/configure/services/executor/trigger/schedule.d.mts +0 -1
  124. package/dist/configure/services/executor/trigger/webhook.d.mts +0 -1
  125. package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -2
  126. package/dist/configure/services/idp/index.d.mts +1 -5
  127. package/dist/configure/services/idp/permission.d.mts +4 -5
  128. package/dist/configure/services/idp/types.d.mts +0 -1
  129. package/dist/configure/services/index.d.mts +8 -1
  130. package/dist/configure/services/resolver/resolver.d.mts +1 -0
  131. package/dist/configure/services/resolver/types.d.mts +0 -1
  132. package/dist/configure/services/secrets/index.d.mts +0 -1
  133. package/dist/configure/services/secrets/types.d.mts +0 -1
  134. package/dist/configure/services/staticwebsite/index.d.mts +0 -1
  135. package/dist/configure/services/staticwebsite/types.d.mts +0 -1
  136. package/dist/configure/services/tailordb/permission.d.mts +4 -5
  137. package/dist/configure/services/tailordb/schema.d.mts +104 -68
  138. package/dist/configure/services/tailordb/types.d.mts +66 -17
  139. package/dist/configure/services/workflow/execution-policy.d.mts +70 -0
  140. package/dist/configure/services/workflow/execution-policy.types.d.mts +103 -0
  141. package/dist/configure/services/workflow/index.d.mts +4 -1
  142. package/dist/configure/services/workflow/job.d.mts +7 -3
  143. package/dist/configure/services/workflow/wait-point.d.mts +0 -1
  144. package/dist/configure/services/workflow/workflow.d.mts +1 -1
  145. package/dist/configure/types/field-runtime.d.mts +0 -1
  146. package/dist/configure/types/field.d.mts +1 -2
  147. package/dist/configure/types/field.types.d.mts +6 -45
  148. package/dist/configure/types/index.d.mts +1 -0
  149. package/dist/configure/types/type.d.mts +1 -2
  150. package/dist/{context-Bd266-ru.mjs → context-DYQVYWqZ.mjs} +4 -5
  151. package/dist/{context-Bd266-ru.mjs.map → context-DYQVYWqZ.mjs.map} +1 -1
  152. package/dist/{file-BbdFGdMV.mjs → file-BUcmVIH2.mjs} +12 -14
  153. package/dist/file-BUcmVIH2.mjs.map +1 -0
  154. package/dist/{file-utils-CYZnO1pX.mjs → file-utils-yEiIS4nJ.mjs} +2 -2
  155. package/dist/file-utils-yEiIS4nJ.mjs.map +1 -0
  156. package/dist/{globals-DhwZj0RB.mjs → globals-BjhJJ2dN.mjs} +2 -2
  157. package/dist/globals-BjhJJ2dN.mjs.map +1 -0
  158. package/dist/iconv-QWaZh0TT.mjs +38 -0
  159. package/dist/iconv-QWaZh0TT.mjs.map +1 -0
  160. package/dist/{idp-Bx25ZBdN.mjs → idp-RA_swu-h.mjs} +4 -5
  161. package/dist/idp-RA_swu-h.mjs.map +1 -0
  162. package/dist/kysely/index.d.mts +3 -4
  163. package/dist/{kysely-type-5eAChaHO.mjs → kysely-type-DqIRgDYR.mjs} +4 -5
  164. package/dist/kysely-type-DqIRgDYR.mjs.map +1 -0
  165. package/dist/parser/service/auth/index.d.mts +1 -1
  166. package/dist/parser/service/auth/schema.d.mts +2 -0
  167. package/dist/parser/service/http-adapter/index.d.mts +1 -1
  168. package/dist/parser/service/idp/types.d.mts +1 -0
  169. package/dist/parser/service/tailordb/types.d.mts +6 -1
  170. package/dist/plugin/builtin/enum-constants/index.d.mts +0 -1
  171. package/dist/plugin/builtin/file-utils/index.d.mts +0 -1
  172. package/dist/plugin/builtin/file-utils/index.mjs +1 -1
  173. package/dist/plugin/builtin/kysely-type/index.d.mts +0 -1
  174. package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
  175. package/dist/plugin/builtin/seed/index.d.mts +0 -1
  176. package/dist/plugin/get-generated-type.d.mts +0 -1
  177. package/dist/plugin/manager.d.mts +2 -1
  178. package/dist/plugin/types.d.mts +0 -1
  179. package/dist/plugin/with-context.d.mts +0 -1
  180. package/dist/{register-ts-hook-ZpBacA07.mjs → register-ts-hook-BhzVkej0.mjs} +799 -446
  181. package/dist/register-ts-hook-BhzVkej0.mjs.map +1 -0
  182. package/dist/{registry-DH4m7eYo.mjs → registry-BSbq6SPo.mjs} +4 -3
  183. package/dist/registry-BSbq6SPo.mjs.map +1 -0
  184. package/dist/resource_pb-BRv7AMXK.mjs +49 -0
  185. package/dist/resource_pb-BRv7AMXK.mjs.map +1 -0
  186. package/dist/runtime/aigateway.d.mts +5 -15
  187. package/dist/runtime/aigateway.mjs +2 -2
  188. package/dist/runtime/authconnection.d.mts +5 -15
  189. package/dist/runtime/authconnection.mjs +2 -2
  190. package/dist/runtime/context.d.mts +14 -6
  191. package/dist/runtime/context.mjs +2 -2
  192. package/dist/runtime/file.d.mts +14 -54
  193. package/dist/runtime/file.mjs +2 -2
  194. package/dist/runtime/globals.d.mts +1 -2
  195. package/dist/runtime/iconv.d.mts +5 -53
  196. package/dist/runtime/iconv.mjs +2 -2
  197. package/dist/runtime/idp.d.mts +13 -70
  198. package/dist/runtime/idp.mjs +2 -2
  199. package/dist/runtime/index.d.mts +11 -12
  200. package/dist/runtime/index.mjs +9 -9
  201. package/dist/runtime/secretmanager.d.mts +7 -20
  202. package/dist/runtime/secretmanager.mjs +2 -2
  203. package/dist/runtime/types.d.mts +9 -4
  204. package/dist/runtime/workflow.d.mts +42 -41
  205. package/dist/runtime/workflow.mjs +2 -2
  206. package/dist/{schema-89dYxNC2.mjs → schema-iCd1ugGp.mjs} +257 -54
  207. package/dist/schema-iCd1ugGp.mjs.map +1 -0
  208. package/dist/secretmanager-CYlpffsz.mjs +13 -0
  209. package/dist/secretmanager-CYlpffsz.mjs.map +1 -0
  210. package/dist/seed/index.d.mts +3 -2
  211. package/dist/service-BT0GPd01.mjs +3 -0
  212. package/dist/{service-ufH7sS8o.mjs → service-CzZEVrp9.mjs} +14 -9
  213. package/dist/service-CzZEVrp9.mjs.map +1 -0
  214. package/dist/{service_pb-CIrhGwHk.mjs → service_pb-Bk7dL-yT.mjs} +27 -50
  215. package/dist/service_pb-Bk7dL-yT.mjs.map +1 -0
  216. package/dist/{service_pb-DjwIn4jO.mjs → service_pb-DZkfjB_6.mjs} +1 -1
  217. package/dist/tailor-proto/src/tailor/v1/aigateway_pb.d.mts +0 -1
  218. package/dist/tailor-proto/src/tailor/v1/aigateway_resource_pb.d.mts +0 -1
  219. package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +0 -1
  220. package/dist/tailor-proto/src/tailor/v1/application_resource_pb.d.mts +0 -1
  221. package/dist/tailor-proto/src/tailor/v1/auth_pb.d.mts +0 -1
  222. package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +0 -1
  223. package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +0 -1
  224. package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +0 -1
  225. package/dist/tailor-proto/src/tailor/v1/executor_pb.d.mts +0 -1
  226. package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +0 -1
  227. package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +0 -1
  228. package/dist/tailor-proto/src/tailor/v1/function_registry_pb.d.mts +0 -1
  229. package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +0 -1
  230. package/dist/tailor-proto/src/tailor/v1/http_adapter_resource_pb.d.mts +0 -1
  231. package/dist/tailor-proto/src/tailor/v1/idp_pb.d.mts +0 -1
  232. package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +0 -1
  233. package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +0 -1
  234. package/dist/tailor-proto/src/tailor/v1/metadata_resource_pb.d.mts +0 -1
  235. package/dist/tailor-proto/src/tailor/v1/meter_pb.d.mts +0 -1
  236. package/dist/tailor-proto/src/tailor/v1/pipeline_pb.d.mts +0 -1
  237. package/dist/tailor-proto/src/tailor/v1/pipeline_resource_pb.d.mts +0 -1
  238. package/dist/tailor-proto/src/tailor/v1/resource_pb.d.mts +0 -1
  239. package/dist/tailor-proto/src/tailor/v1/secret_manager_pb.d.mts +0 -1
  240. package/dist/tailor-proto/src/tailor/v1/secret_manager_resource_pb.d.mts +0 -1
  241. package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +1 -2
  242. package/dist/tailor-proto/src/tailor/v1/stateflow_pb.d.mts +0 -1
  243. package/dist/tailor-proto/src/tailor/v1/stateflow_resource_pb.d.mts +0 -1
  244. package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +0 -1
  245. package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +0 -1
  246. package/dist/tailor-proto/src/tailor/v1/tailordb_pb.d.mts +0 -1
  247. package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +0 -1
  248. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_pb.d.mts +0 -1
  249. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +0 -1
  250. package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +29 -10
  251. package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +35 -2
  252. package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +0 -1
  253. package/dist/tailor-proto/src/tailor/v1/workspace_resource_pb.d.mts +0 -1
  254. package/dist/types/aigateway.generated.d.mts +5 -2
  255. package/dist/types/auth-connection.generated.d.mts +24 -11
  256. package/dist/types/auth.generated.d.mts +115 -84
  257. package/dist/types/executor.generated.d.mts +76 -84
  258. package/dist/types/helpers.d.mts +7 -6
  259. package/dist/types/http-adapter.generated.d.mts +11 -5
  260. package/dist/types/idp.generated.d.mts +536 -524
  261. package/dist/types/resolver.generated.d.mts +26 -11
  262. package/dist/types/staticwebsite.generated.d.mts +7 -3
  263. package/dist/types/tailordb.generated.d.mts +57 -29
  264. package/dist/types/workflow.generated.d.mts +9 -4
  265. package/dist/utils/test/index.d.mts +1 -2
  266. package/dist/utils/test/index.mjs +36 -10
  267. package/dist/utils/test/index.mjs.map +1 -1
  268. package/dist/utils/test/mock.d.mts +0 -1
  269. package/dist/vitest/environment.mjs +1 -1
  270. package/dist/vitest/index.d.mts +1 -1
  271. package/dist/vitest/index.mjs +11 -11
  272. package/dist/vitest/index.mjs.map +1 -1
  273. package/dist/vitest/mock-kysely.d.mts +0 -1
  274. package/dist/vitest/mocks/aigateway.d.mts +2 -2
  275. package/dist/vitest/mocks/authconnection.d.mts +2 -2
  276. package/dist/vitest/mocks/idp.d.mts +2 -2
  277. package/dist/vitest/mocks/secretmanager.d.mts +3 -1
  278. package/dist/vitest/mocks/tailordb.d.mts +6 -3
  279. package/dist/vitest/mocks/workflow.d.mts +15 -8
  280. package/dist/vitest/setup.mjs +1 -1
  281. package/dist/vitest/workflow-local.d.mts +1 -0
  282. package/dist/workflow-GNuSnsTx.mjs +22 -0
  283. package/dist/workflow-GNuSnsTx.mjs.map +1 -0
  284. package/docs/cli/auth.md +3 -3
  285. package/docs/cli/setup.md +9 -9
  286. package/docs/cli-reference.md +7 -6
  287. package/docs/configuration.md +24 -0
  288. package/docs/migration/v2.md +317 -0
  289. package/docs/plugin/custom.md +4 -4
  290. package/docs/plugin/index.md +2 -2
  291. package/docs/runtime.md +4 -2
  292. package/docs/services/aigateway.md +2 -0
  293. package/docs/services/auth.md +2 -2
  294. package/docs/services/resolver.md +1 -1
  295. package/docs/services/tailordb-migration.md +1 -1
  296. package/docs/services/tailordb.md +125 -93
  297. package/docs/services/workflow.md +78 -0
  298. package/package.json +22 -22
  299. package/dist/aigateway-B3oZZE6v.mjs +0 -15
  300. package/dist/application-D2hSK1ZL.mjs +0 -3
  301. package/dist/application-eHp9jXld.mjs.map +0 -1
  302. package/dist/authconnection-BGQM8FZI.mjs +0 -15
  303. package/dist/authconnection-BGQM8FZI.mjs.map +0 -1
  304. package/dist/cli/shared/trigger-context.d.mts +0 -1
  305. package/dist/field-runtime-CAnh_oow.mjs +0 -183
  306. package/dist/field-runtime-CAnh_oow.mjs.map +0 -1
  307. package/dist/file-BbdFGdMV.mjs.map +0 -1
  308. package/dist/file-utils-CYZnO1pX.mjs.map +0 -1
  309. package/dist/globals-DhwZj0RB.mjs.map +0 -1
  310. package/dist/iconv-D2vi8G36.mjs +0 -63
  311. package/dist/iconv-D2vi8G36.mjs.map +0 -1
  312. package/dist/idp-Bx25ZBdN.mjs.map +0 -1
  313. package/dist/kysely-type-5eAChaHO.mjs.map +0 -1
  314. package/dist/register-ts-hook-ZpBacA07.mjs.map +0 -1
  315. package/dist/registry-DH4m7eYo.mjs.map +0 -1
  316. package/dist/rolldown-runtime-DXywRVcq.mjs +0 -20
  317. package/dist/schema-89dYxNC2.mjs.map +0 -1
  318. package/dist/secretmanager-BVxw3ih_.mjs +0 -24
  319. package/dist/secretmanager-BVxw3ih_.mjs.map +0 -1
  320. package/dist/service-CkIwEctX.mjs +0 -3
  321. package/dist/service-ufH7sS8o.mjs.map +0 -1
  322. package/dist/service_pb-CIrhGwHk.mjs.map +0 -1
  323. package/dist/types-C-lQ4se3.mjs +0 -4
  324. package/dist/types-CXF2OYdR.mjs +0 -199
  325. package/dist/types-CXF2OYdR.mjs.map +0 -1
  326. package/dist/workflow-Bo59B75H.mjs +0 -50
  327. package/dist/workflow-Bo59B75H.mjs.map +0 -1
@@ -1,13 +1,14 @@
1
- import { t as db } from "./schema-89dYxNC2.mjs";
2
- import { $ as CreateUserProfileConfigRequestSchema, A as UpdatePipelineServiceRequestSchema, At as Condition_Operator, B as UpdateExecutorExecutorRequestSchema, Ct as UserProfileProviderConfig_UserProfileProviderType, D as CreatePipelineResolverRequestSchema, Dt as ApplicationSchemaUpdateAttemptStatus, E as UpdateSecretManagerSecretRequestSchema, Et as UpdateApplicationRequestSchema, F as IdPPermissionOperator, G as CreateAuthHookRequestSchema, H as ExecutorTargetType, I as IdPPermissionPermit, J as CreateAuthOAuth2ClientRequestSchema, K as CreateAuthIDPConfigRequestSchema, L as FunctionExecution_Status, M as CreateIdPServiceRequestSchema, Mt as PageDirection, N as UpdateIdPServiceRequestSchema, O as CreatePipelineServiceRequestSchema, Ot as Subgraph_ServiceType, P as IdPLang, Q as CreateTenantConfigRequestSchema, S as UpdateStaticWebsiteRequestSchema, St as TenantProviderConfig_TenantProviderType, T as CreateSecretManagerVaultRequestSchema, Tt as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, U as ExecutorTriggerType, V as ExecutorJobStatus, W as CreateAuthConnectionRequestSchema, X as CreateAuthSCIMResourceRequestSchema, Y as CreateAuthSCIMConfigRequestSchema, Z as CreateAuthServiceRequestSchema, _ as TailorDBType_Permission_Operator, _t as AuthSCIMAttribute_Mutability, a as WorkspacePlatformUserRole, at as UpdateAuthSCIMConfigRequestSchema, b as AddCustomDomainRequestSchema, bt as AuthSCIMConfig_AuthorizationType, c as UpdateWorkflowRequestSchema, ct as UpdateTenantConfigRequestSchema, d as CreateTailorDBServiceRequestSchema, dt as AuthConnection_Type, et as UpdateAuthConnectionRequestSchema, f as CreateTailorDBTypeRequestSchema, ft as AuthHookPoint, g as TailorDBGQLPermission_Permit, gt as AuthOAuth2Client_GrantType, h as TailorDBGQLPermission_Operator, ht as AuthOAuth2Client_ClientType, it as UpdateAuthOAuth2ClientRequestSchema, j as PipelineResolver_OperationType, jt as FilterSchema, k as UpdatePipelineResolverRequestSchema, kt as ConditionSchema, l as WorkflowExecution_Status, lt as UpdateUserProfileConfigRequestSchema, m as TailorDBGQLPermission_Action, mt as AuthInvokerSchema, nt as UpdateAuthIDPConfigRequestSchema, o as CreateWorkflowJobFunctionRequestSchema, ot as UpdateAuthSCIMResourceRequestSchema, p as UpdateTailorDBTypeRequestSchema, pt as AuthIDPConfig_AuthType, q as CreateAuthMachineUserRequestSchema, rt as UpdateAuthMachineUserRequestSchema, s as CreateWorkflowRequestSchema, st as UpdateAuthServiceRequestSchema, t as OperatorService, tt as UpdateAuthHookRequestSchema, u as WorkflowJobExecution_Status, ut as AuthConnection_Status, v as TailorDBType_Permission_Permit, vt as AuthSCIMAttribute_Type, w as CreateSecretManagerSecretRequestSchema, wt as CreateApplicationRequestSchema, x as CreateStaticWebsiteRequestSchema, y as TailorDBType_PermitAction, yt as AuthSCIMAttribute_Uniqueness, z as CreateExecutorExecutorRequestSchema } from "./service_pb-CIrhGwHk.mjs";
1
+ import { t as db } from "./schema-iCd1ugGp.mjs";
2
+ import { i as PageDirection, n as Condition_Operator, r as FilterSchema, t as ConditionSchema } from "./resource_pb-BRv7AMXK.mjs";
3
3
  import { t as assertDefined } from "./assert-DBxo8jPo.mjs";
4
4
  import { a as parseBoolean, i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-BEiZZ3qT.mjs";
5
- import { $ as getConsoleBaseUrl, C as getDistDir, E as loadConfig, F as loadPlatformClientConfig, J as fetchAllTolerant, L as loadWorkspaceId, M as loadConfigPath, P as loadMachineUserName, R as platformConfigFromProfile, S as createBundleCache, T as hashFile, V as resolveConfigUser, W as writePlatformConfig, X as fetchPaged, Y as fetchMachineUserToken, at as isDefaultPlatform, b as getPluginGenerationDependencies, d as buildExecutorArgsExpr, et as getOAuth2ClientId, f as buildResolverOperationHookExpr, g as platformBundleDefinePlugin, h as stringifyFunction, i as resolverBundleKey, it as initOperatorClient, j as loadAccessToken, l as HTTP_METHODS, m as assertUniqueTailorDBTypeNamesWithExternal, n as generatePluginFilesIfNeeded, nt as getPlatformBaseUrl, o as getApplicationAuthNamespace, ot as resolveStaticWebsiteUrls, p as assertUniqueLocalTailorDBTypeNames, q as fetchAll, r as loadApplication, st as byName, t as defineApplication, tt as getOrNull, w as hashContent, x as hasGenerationHooks, z as readPlatformConfig } from "./application-eHp9jXld.mjs";
6
- import { c as stripTailorDBTypeBuilderHelpers, h as loadFilesWithIgnores, t as createExecutorService, u as TailorDBTypeSchema } from "./service-ufH7sS8o.mjs";
5
+ import { B as readPlatformConfig, C as createBundleCache, Ct as positiveIntArg, D as loadConfig, E as hashFile, Et as workspaceArgs, F as loadMachineUserName, G as writePlatformConfig, H as resolveConfigUser, I as loadPlatformClientConfig, J as fetchAll, M as loadAccessToken, N as loadConfigPath, R as loadWorkspaceId, S as hasGenerationHooks, St as parseDuration, T as hashContent, Tt as toPageDirection, X as fetchMachineUserToken, Y as fetchAllTolerant, Z as fetchPaged, _ as platformBundleDefinePlugin, _t as nonNegativeIntArg, at as initOperatorClient, bt as pagedLogArgs, ct as byName, dt as confirmationArgs, et as getConsoleBaseUrl, f as buildExecutorArgsExpr, ft as deploymentArgs, g as stringifyFunction, h as assertUniqueTailorDBTypeNamesWithExternal, i as resolverBundleKey, m as assertUniqueLocalTailorDBTypeNames, mt as folderArgs, n as generatePluginFilesIfNeeded, nt as getOrNull, o as getApplicationAuthNamespace, ot as isDefaultPlatform, p as buildResolverOperationHookExpr, pt as durationArg, r as loadApplication, rt as getPlatformBaseUrl, s as WorkflowJobFunctionExecutionPolicySchema, st as resolveStaticWebsiteUrls, t as defineApplication, tt as getOAuth2ClientId, u as HTTP_METHODS, ut as configArg, vt as orderArg, w as getDistDir, wt as resolveMachineUserInputSource, x as getPluginGenerationDependencies, xt as paginationArgs, yt as organizationArgs, z as platformConfigFromProfile } from "./application-Bf8wxOi6.mjs";
6
+ import { c as stripTailorDBTypeBuilderHelpers, h as loadFilesWithIgnores, t as createExecutorService, u as TailorDBTypeSchema } from "./service-CzZEVrp9.mjs";
7
7
  import { t as multiline } from "./multiline-sfHpTZZK.mjs";
8
8
  import { t as readPackageJson } from "./package-json-8b0O9TlX.mjs";
9
9
  import { i as userAgent } from "./secret-file-aoNXJmKa.mjs";
10
10
  import { n as isCLIError, t as createCLIError } from "./errors-118wUDRr.mjs";
11
+ import { $ as CreateAuthServiceRequestSchema, A as CreatePipelineServiceRequestSchema, At as Subgraph_ServiceType, C as CreateStaticWebsiteRequestSchema, D as CreateSecretManagerVaultRequestSchema, Dt as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, E as CreateSecretManagerSecretRequestSchema, Et as CreateApplicationRequestSchema, F as UpdateIdPServiceRequestSchema, G as ExecutorTriggerType, H as UpdateExecutorExecutorRequestSchema, I as IdPLang, J as CreateAuthIDPConfigRequestSchema, K as CreateAuthConnectionRequestSchema, L as IdPPermissionOperator, M as UpdatePipelineServiceRequestSchema, Mt as UpdateAIGatewayRequestSchema, N as PipelineResolver_OperationType, O as UpdateSecretManagerSecretRequestSchema, Ot as UpdateApplicationRequestSchema, P as CreateIdPServiceRequestSchema, Q as CreateAuthSCIMResourceRequestSchema, R as IdPPermissionPermit, S as AddCustomDomainRequestSchema, St as AuthSCIMConfig_AuthorizationType, Tt as UserProfileProviderConfig_UserProfileProviderType, U as ExecutorJobStatus, V as CreateExecutorExecutorRequestSchema, W as ExecutorTargetType, X as CreateAuthOAuth2ClientRequestSchema, Y as CreateAuthMachineUserRequestSchema, Z as CreateAuthSCIMConfigRequestSchema, _ as TailorDBGQLPermission_Operator, _t as AuthOAuth2Client_ClientType, a as WorkspacePlatformUserRole, at as UpdateAuthMachineUserRequestSchema, b as TailorDBType_Permission_Permit, bt as AuthSCIMAttribute_Type, c as CreateWorkflowRequestSchema, ct as UpdateAuthSCIMResourceRequestSchema, d as WorkflowExecution_Status, dt as UpdateUserProfileConfigRequestSchema, et as CreateTenantConfigRequestSchema, f as WorkflowJobExecution_Status, ft as AuthConnection_Status, g as TailorDBGQLPermission_Action, gt as AuthInvokerSchema, h as UpdateTailorDBTypeRequestSchema, ht as AuthIDPConfig_AuthType, it as UpdateAuthIDPConfigRequestSchema, j as UpdatePipelineResolverRequestSchema, jt as CreateAIGatewayRequestSchema, k as CreatePipelineResolverRequestSchema, kt as ApplicationSchemaUpdateAttemptStatus, l as UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, lt as UpdateAuthServiceRequestSchema, m as CreateTailorDBTypeRequestSchema, mt as AuthHookPoint, nt as UpdateAuthConnectionRequestSchema, o as CreateWorkflowJobFunctionExecutionPolicyRequestSchema, ot as UpdateAuthOAuth2ClientRequestSchema, p as CreateTailorDBServiceRequestSchema, pt as AuthConnection_Type, q as CreateAuthHookRequestSchema, rt as UpdateAuthHookRequestSchema, s as CreateWorkflowJobFunctionRequestSchema, st as UpdateAuthSCIMConfigRequestSchema, t as OperatorService, tt as CreateUserProfileConfigRequestSchema, u as UpdateWorkflowRequestSchema, ut as UpdateTenantConfigRequestSchema, v as TailorDBGQLPermission_Permit, vt as AuthOAuth2Client_GrantType, w as UpdateStaticWebsiteRequestSchema, wt as TenantProviderConfig_TenantProviderType, x as TailorDBType_PermitAction, xt as AuthSCIMAttribute_Uniqueness, y as TailorDBType_Permission_Operator, yt as AuthSCIMAttribute_Mutability, z as FunctionExecution_Status } from "./service_pb-Bk7dL-yT.mjs";
11
12
  import { r as withSpan } from "./telemetry-BRVdwh14.mjs";
12
13
  import * as mod from "node:module";
13
14
  import * as path from "pathe";
@@ -16,8 +17,7 @@ import { arg, createDefineCommand, defineCommand, runCommand } from "politty";
16
17
  import { z } from "zod";
17
18
  import { ScalarType, create, fromJson, toJson } from "@bufbuild/protobuf";
18
19
  import * as fs$1 from "node:fs";
19
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
20
- import { parseEnv } from "node:util";
20
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
21
21
  import { ValueSchema, timestampDate } from "@bufbuild/protobuf/wkt";
22
22
  import { formatDistanceToNowStrict } from "date-fns";
23
23
  import { getBorderCharacters, table } from "table";
@@ -48,240 +48,6 @@ import { createPrompt } from "@toiroakr/read-multiline";
48
48
  import { astVisitor, parse } from "pgsql-ast-parser";
49
49
  import { parse as parse$1 } from "@0no-co/graphql.web";
50
50
 
51
- //#region src/cli/shared/args.ts
52
- const unitToMs = {
53
- ms: 1,
54
- s: 1e3,
55
- m: 60 * 1e3
56
- };
57
- const durationPattern = /^(\d+)(ms|s|m)$/;
58
- /**
59
- * Schema for duration string validation (e.g., "3s", "500ms", "1m")
60
- * Only validates format; use parseDuration() to convert to milliseconds
61
- */
62
- const durationArg = z.string().refine((val) => durationPattern.test(val), { message: "Invalid duration format. Expected format: '3s', '500ms', '1m'" }).refine((val) => {
63
- const match = val.match(durationPattern);
64
- if (!match) return false;
65
- const digits = match[1];
66
- return digits !== void 0 && parseInt(digits, 10) > 0;
67
- }, { message: "Duration must be greater than 0" });
68
- /**
69
- * Parse a validated duration string into milliseconds
70
- * @param duration - Duration string (e.g., "3s", "500ms", "1m")
71
- * @returns Duration in milliseconds
72
- */
73
- function parseDuration(duration) {
74
- const match = assertDefined(duration.match(durationPattern), `invalid duration format: ${duration}`);
75
- const value = parseInt(assertDefined(match[1], "duration digits group missing"), 10);
76
- const unit = assertDefined(match[2], "duration unit group missing");
77
- return value * unitToMs[unit];
78
- }
79
- /**
80
- * Schema for positive integer validation (from string input)
81
- * Transforms the string to a number
82
- */
83
- const positiveIntArg = z.coerce.number().int().positive();
84
- /**
85
- * Schema for non-negative integer validation (from string input).
86
- * Accepts 0 (used for `--limit 0` to disable the limit).
87
- */
88
- const nonNegativeIntArg = z.coerce.number().int().nonnegative();
89
- /**
90
- * Schema for sort order (`asc` or `desc`).
91
- */
92
- const orderArg = z.enum(["asc", "desc"]);
93
- /**
94
- * Translate a CLI `--order` value into the proto `PageDirection` enum.
95
- * Returns `undefined` when the user did not specify an order so that
96
- * callers can omit the field and fall back to the server default.
97
- * @param order - Order string from CLI args (`"asc"` | `"desc"` | undefined)
98
- * @returns PageDirection, or undefined when `order` is undefined
99
- */
100
- function toPageDirection(order) {
101
- if (order === void 0) return void 0;
102
- return order === "asc" ? PageDirection.ASC : PageDirection.DESC;
103
- }
104
- /**
105
- * Load env files from parsed arguments.
106
- * Processes --env-file first, then --env-file-if-exists.
107
- *
108
- * Follows Node.js --env-file behavior:
109
- * - Variables already set in the environment are NOT overwritten
110
- * - Variables from later files override those from earlier files
111
- * @param envFiles - Required env file path(s) that must exist
112
- * @param envFilesIfExists - Optional env file path(s) that are loaded if they exist
113
- */
114
- function loadEnvFiles(envFiles, envFilesIfExists) {
115
- const originalEnvKeys = new Set(Object.keys(process.env));
116
- const load = (files, required) => {
117
- for (const file of [files ?? []].flat()) {
118
- const envPath = path.resolve(process.cwd(), file);
119
- if (!fs$1.existsSync(envPath)) {
120
- if (required) throw new Error(`Environment file not found: ${envPath}`);
121
- continue;
122
- }
123
- const parsed = parseEnv(fs$1.readFileSync(envPath, "utf-8"));
124
- for (const [key, value] of Object.entries(parsed)) {
125
- if (originalEnvKeys.has(key)) continue;
126
- process.env[key] = value;
127
- }
128
- }
129
- };
130
- load(envFiles, true);
131
- load(envFilesIfExists, false);
132
- }
133
- /**
134
- * Common arguments for all CLI commands
135
- *
136
- * NOTE: --env-file and --env-file-if-exists collide with Node.js flags due to a bug
137
- * (https://github.com/nodejs/node/issues/54232). Node.js parses these even after the
138
- * script path, causing warnings (twice due to tsx loader).
139
- */
140
- const commonArgs = {
141
- "env-file": arg(z.string().optional(), {
142
- alias: "e",
143
- description: "Path to the environment file (error if not found)",
144
- completion: {
145
- type: "file",
146
- matcher: [".env.*", ".env"]
147
- }
148
- }),
149
- "env-file-if-exists": arg(z.string().optional(), {
150
- description: "Path to the environment file (ignored if not found)",
151
- completion: {
152
- type: "file",
153
- matcher: [".env.*", ".env"]
154
- },
155
- effect: (_value, { args }) => {
156
- loadEnvFiles(args["env-file"], args["env-file-if-exists"]);
157
- }
158
- }),
159
- verbose: arg(z.boolean().default(false), {
160
- description: "Enable verbose logging",
161
- effect: (value) => {
162
- verboseMode = value;
163
- }
164
- }),
165
- json: arg(z.boolean().default(false), {
166
- alias: "j",
167
- description: "Output as JSON",
168
- effect: (value) => {
169
- logger.jsonMode = value;
170
- }
171
- })
172
- };
173
- /**
174
- * Arguments for commands that require workspace context
175
- */
176
- const workspaceArgs = {
177
- "workspace-id": arg(z.string().optional(), {
178
- alias: "w",
179
- description: "Workspace ID",
180
- env: "TAILOR_PLATFORM_WORKSPACE_ID",
181
- completion: { type: "none" }
182
- }),
183
- profile: arg(z.string().optional(), {
184
- alias: "p",
185
- description: "Workspace profile",
186
- env: "TAILOR_PLATFORM_PROFILE",
187
- completion: { type: "none" }
188
- })
189
- };
190
- /**
191
- * Shared config arg for commands that accept a config file path
192
- */
193
- const configArg = { config: arg(z.string().default("tailor.config.ts"), {
194
- alias: "c",
195
- description: "Path to Tailor config file",
196
- env: "TAILOR_CONFIG_PATH",
197
- completion: {
198
- type: "file",
199
- extensions: ["ts"]
200
- }
201
- }) };
202
- /**
203
- * Shared config arg for commands that accept one or more comma-separated config file paths
204
- */
205
- const multiConfigArg = { config: arg(z.string().default("tailor.config.ts"), {
206
- alias: "c",
207
- description: "Path to SDK config file. Use comma-separated paths to deploy multiple apps together.",
208
- env: "TAILOR_PLATFORM_SDK_CONFIG_PATH",
209
- completion: {
210
- type: "file",
211
- extensions: ["ts"]
212
- }
213
- }) };
214
- /**
215
- * Arguments for commands that interact with deployed resources (includes config)
216
- */
217
- const deploymentArgs = {
218
- ...workspaceArgs,
219
- ...configArg
220
- };
221
- /**
222
- * Arguments for commands that require confirmation
223
- */
224
- const confirmationArgs = { yes: arg(z.boolean().default(false), {
225
- alias: "y",
226
- description: "Skip confirmation prompts"
227
- }) };
228
- /**
229
- * Arguments for commands that require organization context
230
- */
231
- const organizationArgs = { "organization-id": arg(z.string(), {
232
- alias: "o",
233
- description: "Organization ID",
234
- env: "TAILOR_PLATFORM_ORGANIZATION_ID",
235
- completion: { type: "none" }
236
- }) };
237
- /**
238
- * Arguments for list commands that accept `--order` / `--limit`. Sort
239
- * order defaults to `desc` (newest first) because most callers want the
240
- * latest items; pass `--order asc` to opt in to ascending order. The
241
- * limit is unbounded by default so existing invocations keep returning
242
- * every item; pass `--limit N` to cap the result size.
243
- * @param defaultOrder - Default value for `--order` (defaults to `"desc"`)
244
- * @returns Argument shape suitable for spreading into a command schema
245
- */
246
- const paginationArgs = (defaultOrder = "desc") => ({
247
- order: arg(orderArg.default(defaultOrder), { description: "Sort order (asc or desc)" }),
248
- limit: arg(nonNegativeIntArg.optional(), {
249
- alias: "l",
250
- description: "Maximum number of items to return (0 or omit: unlimited)"
251
- })
252
- });
253
- /**
254
- * Arguments for time-series log list commands. Defaults to newest-first
255
- * (`desc`) and a 50-item cap so that listing stays responsive on busy
256
- * workspaces. Pass `--limit 0` to disable the cap and fetch all entries.
257
- */
258
- const pagedLogArgs = {
259
- order: arg(orderArg.default("desc"), { description: "Sort order (asc or desc)" }),
260
- limit: arg(nonNegativeIntArg.default(50), {
261
- alias: "l",
262
- description: "Maximum number of items to return (0: unlimited)"
263
- })
264
- };
265
- /**
266
- * Arguments for commands that require folder context
267
- */
268
- const folderArgs = { "folder-id": arg(z.string(), {
269
- alias: "f",
270
- description: "Folder ID",
271
- env: "TAILOR_PLATFORM_FOLDER_ID",
272
- completion: { type: "none" }
273
- }) };
274
- let verboseMode = false;
275
- /**
276
- * Returns whether verbose mode is enabled.
277
- * Used by the global cleanup handler which doesn't have access to parsed args.
278
- * @returns Whether verbose mode is enabled
279
- */
280
- function isVerbose() {
281
- return verboseMode;
282
- }
283
-
284
- //#endregion
285
51
  //#region src/cli/shared/command.ts
286
52
  /**
287
53
  * defineCommand with global args type (CommonArgsType).
@@ -1601,7 +1367,7 @@ var PluginManager = class {
1601
1367
  }
1602
1368
  /**
1603
1369
  * Extend a TailorDB type with new fields.
1604
- * This method handles the `db.type()` call and metadata copying internally.
1370
+ * This method handles the `db.table()` call and metadata copying internally.
1605
1371
  * @param params - Parameters for type extension
1606
1372
  * @returns The extended TailorDB type
1607
1373
  */
@@ -1616,7 +1382,7 @@ var PluginManager = class {
1616
1382
  };
1617
1383
  const pluralForm = originalType.metadata.settings?.pluralForm;
1618
1384
  const typeName = pluralForm ? [originalType.name, pluralForm] : originalType.name;
1619
- return copyMetadataToExtendedType(originalType, db.type(typeName, fieldsWithoutId));
1385
+ return copyMetadataToExtendedType(originalType, db.table(typeName, fieldsWithoutId));
1620
1386
  }
1621
1387
  };
1622
1388
  /**
@@ -2531,35 +2297,59 @@ const SecretsStateSchema = z.object({
2531
2297
  vaults: z.record(z.string(), z.record(z.string(), z.string())),
2532
2298
  connections: z.record(z.string(), z.string()).optional()
2533
2299
  });
2300
+ const PersistedSecretsStateSchema = z.object({
2301
+ version: z.literal(1),
2302
+ workspaceId: z.string(),
2303
+ applicationKey: z.string(),
2304
+ state: SecretsStateSchema
2305
+ });
2534
2306
  /**
2535
- * Get the file path for the secrets state JSON.
2536
- * @returns Absolute path to secrets-state.json
2307
+ * Get the file path for one workspace and application's secrets state JSON.
2308
+ * @param scope - Workspace and application identity for the deployment
2309
+ * @returns Absolute path to the scoped state file
2537
2310
  */
2538
- function getSecretsStatePath() {
2539
- return path.join(getDistDir(), "secrets-state.json");
2311
+ function getSecretsStatePath(scope) {
2312
+ const scopeHash = hashValue(JSON.stringify([scope.workspaceId, applicationStateKey(scope)]));
2313
+ return path.join(getDistDir(), "secrets-state", `${scopeHash}.json`);
2540
2314
  }
2541
- /**
2542
- * Load secrets hash state from disk.
2543
- * @returns Persisted state, or empty state if file is missing or corrupted
2544
- */
2545
- function loadSecretsState() {
2546
- const filePath = getSecretsStatePath();
2547
- if (!existsSync(filePath)) return { vaults: {} };
2315
+ function loadPersistedSecretsState(scope) {
2548
2316
  try {
2549
- const raw = readFileSync(filePath, "utf-8");
2550
- return SecretsStateSchema.parse(JSON.parse(raw));
2317
+ const raw = readFileSync(getSecretsStatePath(scope), "utf-8");
2318
+ const persistedState = PersistedSecretsStateSchema.parse(JSON.parse(raw));
2319
+ if (persistedState.workspaceId !== scope.workspaceId || persistedState.applicationKey !== applicationStateKey(scope)) return;
2320
+ return persistedState;
2551
2321
  } catch {
2552
- return { vaults: {} };
2322
+ return;
2553
2323
  }
2554
2324
  }
2325
+ function applicationStateKey(scope) {
2326
+ if (!scope.applicationId) throw new Error(`Application "${scope.applicationName}" has no stable id for secrets state`);
2327
+ return `id:${scope.applicationId}`;
2328
+ }
2329
+ /**
2330
+ * Load secrets hash state for one workspace and application from disk.
2331
+ * @param scope - Workspace and application identity for the deployment
2332
+ * @returns Persisted state, or empty state if the scope is missing or the file is invalid
2333
+ */
2334
+ function loadSecretsState(scope) {
2335
+ if (!scope.applicationId) return { vaults: {} };
2336
+ return loadPersistedSecretsState(scope)?.state ?? { vaults: {} };
2337
+ }
2555
2338
  /**
2556
- * Save secrets hash state to disk.
2339
+ * Save secrets hash state for one workspace and application to disk.
2340
+ * @param scope - Workspace and application identity for the deployment
2557
2341
  * @param state - The secrets state to persist
2558
2342
  */
2559
- function saveSecretsState(state) {
2560
- const filePath = getSecretsStatePath();
2343
+ function saveSecretsState(scope, state) {
2344
+ if (!scope.applicationId) return;
2345
+ const filePath = getSecretsStatePath(scope);
2561
2346
  mkdirSync(path.dirname(filePath), { recursive: true });
2562
- writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
2347
+ writeFileSync(filePath, JSON.stringify({
2348
+ version: 1,
2349
+ workspaceId: scope.workspaceId,
2350
+ applicationKey: applicationStateKey(scope),
2351
+ state
2352
+ }, null, 2), "utf-8");
2563
2353
  }
2564
2354
  /**
2565
2355
  * Compute SHA-256 hex digest of a value.
@@ -2625,6 +2415,11 @@ function buildUpdateMask(existing, desired, secretChanged) {
2625
2415
  * @returns Planned changes for auth connections
2626
2416
  */
2627
2417
  async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2418
+ const stateScope = {
2419
+ workspaceId,
2420
+ applicationId: appId,
2421
+ applicationName: appName
2422
+ };
2628
2423
  const changeSet = createChangeSet("Auth connections");
2629
2424
  const conflicts = [];
2630
2425
  const unmanaged = [];
@@ -2648,7 +2443,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2648
2443
  allLabels: metadata?.labels
2649
2444
  };
2650
2445
  }));
2651
- const state = loadSecretsState();
2446
+ const state = loadSecretsState(stateScope);
2652
2447
  for (const [name, config] of Object.entries(desiredConnections)) {
2653
2448
  const existing = existingConnections[name];
2654
2449
  const metaRequest = await buildMetaRequest({
@@ -2709,7 +2504,8 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2709
2504
  changeSet,
2710
2505
  conflicts,
2711
2506
  unmanaged,
2712
- resourceOwners
2507
+ resourceOwners,
2508
+ stateScope
2713
2509
  };
2714
2510
  }
2715
2511
  /**
@@ -2719,7 +2515,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2719
2515
  * @param phase - Apply phase
2720
2516
  */
2721
2517
  async function applyAuthConnections(client, result, phase) {
2722
- const { changeSet } = result;
2518
+ const { changeSet, stateScope } = result;
2723
2519
  if (phase === "create-update") {
2724
2520
  await Promise.all(changeSet.creates.map(async (create) => {
2725
2521
  await client.createAuthConnection(create.request);
@@ -2733,26 +2529,29 @@ async function applyAuthConnections(client, result, phase) {
2733
2529
  await Promise.all(changeSet.updates.map(async (update) => {
2734
2530
  await client.setMetadata(update.metaRequest);
2735
2531
  }));
2736
- const state = loadSecretsState();
2737
- if (!state.connections) state.connections = {};
2738
- for (const create of changeSet.creates) {
2739
- const conn = create.request.connection;
2740
- if (conn?.config?.case === "oauth2") state.connections[create.name] = hashValue(conn.config.value.clientSecret ?? "");
2741
- }
2742
- for (const replace of changeSet.replaces) {
2743
- const conn = replace.updateRequest.connection;
2744
- if (conn?.config?.case === "oauth2" && replace.updateRequest.updateMask?.paths?.includes("oauth2.client_secret")) state.connections[replace.name] = hashValue(conn.config.value.clientSecret ?? "");
2532
+ const secretReplaces = changeSet.replaces.filter((replace) => replace.updateRequest.updateMask?.paths?.includes("oauth2.client_secret"));
2533
+ if (changeSet.creates.length > 0 || secretReplaces.length > 0) {
2534
+ const state = loadSecretsState(stateScope);
2535
+ if (!state.connections) state.connections = {};
2536
+ for (const create of changeSet.creates) {
2537
+ const conn = create.request.connection;
2538
+ if (conn?.config?.case === "oauth2") state.connections[create.name] = hashValue(conn.config.value.clientSecret ?? "");
2539
+ }
2540
+ for (const replace of secretReplaces) {
2541
+ const conn = replace.updateRequest.connection;
2542
+ if (conn?.config?.case === "oauth2") state.connections[replace.name] = hashValue(conn.config.value.clientSecret ?? "");
2543
+ }
2544
+ saveSecretsState(stateScope, state);
2745
2545
  }
2746
- saveSecretsState(state);
2747
2546
  } else {
2748
2547
  await Promise.all(changeSet.deletes.map(async (del) => {
2749
2548
  await client.deleteAuthConnection(del.request);
2750
2549
  }));
2751
2550
  if (changeSet.deletes.length > 0) {
2752
- const state = loadSecretsState();
2551
+ const state = loadSecretsState(stateScope);
2753
2552
  if (state.connections) {
2754
2553
  for (const del of changeSet.deletes) delete state.connections[del.name];
2755
- saveSecretsState(state);
2554
+ saveSecretsState(stateScope, state);
2756
2555
  }
2757
2556
  }
2758
2557
  }
@@ -3915,7 +3714,10 @@ async function applyAuth(client, result, phase = "create-update") {
3915
3714
  await Promise.all([...changeSet.machineUser.creates.map((create) => client.createAuthMachineUser(create.request)), ...changeSet.machineUser.updates.map((update) => client.updateAuthMachineUser(update.request))]);
3916
3715
  };
3917
3716
  const applyCreateUpdateDependents = async () => {
3918
- await applyAuthConnections(client, { changeSet: changeSet.connection }, "create-update");
3717
+ await applyAuthConnections(client, {
3718
+ changeSet: changeSet.connection,
3719
+ stateScope: result.connectionStateScope
3720
+ }, "create-update");
3919
3721
  await Promise.all([...changeSet.idpConfig.creates.map(async (create) => {
3920
3722
  if (create.idpConfig.kind === "BuiltInIdP") assertDefined(create.request.idpConfig, "request missing idpConfig").config = await protoBuiltinIdPConfig(client, assertDefined(create.request.workspaceId, "request missing workspaceId"), create.idpConfig);
3921
3723
  return client.createAuthIDPConfig(create.request);
@@ -3958,7 +3760,10 @@ async function applyAuth(client, result, phase = "create-update") {
3958
3760
  await Promise.all(changeSet.tenantConfig.deletes.map((del) => client.deleteTenantConfig(del.request)));
3959
3761
  await Promise.all(changeSet.userProfileConfig.deletes.map((del) => client.deleteUserProfileConfig(del.request)));
3960
3762
  await Promise.all(changeSet.idpConfig.deletes.map((del) => client.deleteAuthIDPConfig(del.request)));
3961
- await applyAuthConnections(client, { changeSet: changeSet.connection }, "delete-resources");
3763
+ await applyAuthConnections(client, {
3764
+ changeSet: changeSet.connection,
3765
+ stateScope: result.connectionStateScope
3766
+ }, "delete-resources");
3962
3767
  } else if (phase === "delete-services") await Promise.all(changeSet.service.deletes.map((del) => client.deleteAuthService(del.request)));
3963
3768
  }
3964
3769
  /**
@@ -4002,7 +3807,8 @@ async function planAuth(context) {
4002
3807
  },
4003
3808
  conflicts: [...conflicts, ...connectionResult.conflicts],
4004
3809
  unmanaged: [...unmanaged, ...connectionResult.unmanaged],
4005
- resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners])
3810
+ resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners]),
3811
+ connectionStateScope: connectionResult.stateScope
4006
3812
  };
4007
3813
  }
4008
3814
  async function planServices$2(client, workspaceId, appName, appId, auths, forceApplyAll = false) {
@@ -5878,7 +5684,12 @@ async function planSecretManager(context) {
5878
5684
  getName: (resource) => resource.name,
5879
5685
  getTrn: (name) => resourceTrn(workspaceId, "vault", name)
5880
5686
  });
5881
- const state = loadSecretsState();
5687
+ const stateScope = {
5688
+ workspaceId,
5689
+ applicationId: application.id,
5690
+ applicationName: application.name
5691
+ };
5692
+ const state = loadSecretsState(stateScope);
5882
5693
  const skippedSecrets = [];
5883
5694
  await Promise.all(secretVaults.map(async (vault) => {
5884
5695
  const vaultName = vault.vaultName;
@@ -5987,7 +5798,8 @@ async function planSecretManager(context) {
5987
5798
  skippedSecrets,
5988
5799
  conflicts,
5989
5800
  unmanaged,
5990
- resourceOwners
5801
+ resourceOwners,
5802
+ stateScope
5991
5803
  };
5992
5804
  }
5993
5805
  /**
@@ -5995,11 +5807,11 @@ async function planSecretManager(context) {
5995
5807
  * @param client - Operator client instance
5996
5808
  * @param result - Planned secret changes
5997
5809
  * @param phase - Apply phase
5998
- * @param application - Application to read secrets from for hash state persistence
5810
+ * @param application - Application used for ownership metadata and hash state persistence
5999
5811
  * @returns Promise that resolves when secret changes are applied
6000
5812
  */
6001
5813
  async function applySecretManager(client, result, phase = "create-update", application) {
6002
- const { vaultChangeSet, secretChangeSet } = result;
5814
+ const { vaultChangeSet, secretChangeSet, stateScope } = result;
6003
5815
  if (phase === "create-update") {
6004
5816
  await Promise.all(vaultChangeSet.creates.map(async (create) => {
6005
5817
  await client.createSecretManagerVault(vaultCreateRequest(create));
@@ -6022,13 +5834,14 @@ async function applySecretManager(client, result, phase = "create-update", appli
6022
5834
  }));
6023
5835
  await Promise.all(secretChangeSet.creates.map((create) => client.createSecretManagerSecret(secretCreateRequest(create))));
6024
5836
  await Promise.all(secretChangeSet.updates.map((update) => client.updateSecretManagerSecret(secretUpdateRequest(update))));
6025
- if (application) {
6026
- const state = loadSecretsState();
6027
- for (const vault of application.secrets) {
6028
- if (!Object.hasOwn(state.vaults, vault.vaultName)) state.vaults[vault.vaultName] = {};
6029
- for (const secret of vault.secrets) if (secret.value != null) assertDefined(state.vaults[vault.vaultName], "vault state entry missing")[secret.name] = hashValue(secret.value);
5837
+ const secretHashUpdates = [...secretChangeSet.creates, ...secretChangeSet.updates];
5838
+ if (application && secretHashUpdates.length > 0) {
5839
+ const state = loadSecretsState(stateScope);
5840
+ for (const secret of secretHashUpdates) {
5841
+ if (!Object.hasOwn(state.vaults, secret.vaultName)) state.vaults[secret.vaultName] = {};
5842
+ assertDefined(state.vaults[secret.vaultName], "vault state entry missing")[secret.secretName] = hashValue(secret.value);
6030
5843
  }
6031
- saveSecretsState(state);
5844
+ saveSecretsState(stateScope, state);
6032
5845
  }
6033
5846
  } else {
6034
5847
  await Promise.all(secretChangeSet.deletes.map((del) => client.deleteSecretManagerSecret({
@@ -6041,13 +5854,13 @@ async function applySecretManager(client, result, phase = "create-update", appli
6041
5854
  secretmanagerVaultName: del.name
6042
5855
  })));
6043
5856
  if (secretChangeSet.deletes.length > 0 || vaultChangeSet.deletes.length > 0) {
6044
- const state = loadSecretsState();
5857
+ const state = loadSecretsState(stateScope);
6045
5858
  for (const del of secretChangeSet.deletes) if (Object.hasOwn(state.vaults, del.vaultName)) {
6046
5859
  delete assertDefined(state.vaults[del.vaultName], "vault state entry missing")[del.secretName];
6047
5860
  if (Object.keys(assertDefined(state.vaults[del.vaultName], "vault state entry missing")).length === 0) delete state.vaults[del.vaultName];
6048
5861
  }
6049
5862
  for (const del of vaultChangeSet.deletes) delete state.vaults[del.name];
6050
- saveSecretsState(state);
5863
+ saveSecretsState(stateScope, state);
6051
5864
  }
6052
5865
  }
6053
5866
  }
@@ -6142,6 +5955,7 @@ function formatDiffChange(change) {
6142
5955
  case "relationship_removed": return ` - [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}`;
6143
5956
  case "relationship_modified": return ` ~ [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}: ${change.reason ?? "modified"}`;
6144
5957
  case "permission_modified": return ` ~ [Permission] ${change.reason ?? "modified"}`;
5958
+ case "type_scripts_modified": return ` ~ [Type Scripts] ${change.typeName}: ${change.reason ?? "type-level hooks/validate changed"}`;
6145
5959
  default: {
6146
5960
  const unknown = change;
6147
5961
  return ` ? ${unknown.typeName}.${unknown.fieldName ?? ""}`;
@@ -6236,7 +6050,8 @@ const DIFF_CHANGE_LABELS = {
6236
6050
  relationship_added: "relationship(s) added",
6237
6051
  relationship_removed: "relationship(s) removed",
6238
6052
  relationship_modified: "relationship(s) modified",
6239
- permission_modified: "permission(s) modified"
6053
+ permission_modified: "permission(s) modified",
6054
+ type_scripts_modified: "type script(s) modified"
6240
6055
  };
6241
6056
  /**
6242
6057
  * Format a summary of the migration diff
@@ -6250,6 +6065,181 @@ function formatDiffSummary(diff) {
6250
6065
  return parts.length > 0 ? parts.join(", ") : "No changes";
6251
6066
  }
6252
6067
 
6068
+ //#endregion
6069
+ //#region src/parser/service/tailordb/type-script.ts
6070
+ const INPUT = "_input";
6071
+ const NEW_RECORD = "_newRecord";
6072
+ const OLD_RECORD = "_oldRecord";
6073
+ const NOW = "_now";
6074
+ const SOURCE_HASH_PREFIX = "// @sdk-source-hash:";
6075
+ const TIME_TYPES = /* @__PURE__ */ new Set([
6076
+ "datetime",
6077
+ "date",
6078
+ "time"
6079
+ ]);
6080
+ const key = (name) => JSON.stringify(name);
6081
+ function collectFieldScriptSources(fields) {
6082
+ const entries = [];
6083
+ for (const [name, config] of Object.entries(fields).toSorted(([a], [b]) => a.localeCompare(b))) {
6084
+ const data = {};
6085
+ if (config.hooks?.create?.expr) data.hc = config.hooks.create.expr;
6086
+ if (config.hooks?.update?.expr) data.hu = config.hooks.update.expr;
6087
+ if (config.validate?.some((v) => v.script?.expr)) data.v = config.validate.filter((v) => v.script?.expr).map((v) => [v.script?.expr, v.errorMessage]);
6088
+ if (config.default !== void 0) {
6089
+ data.d = config.default instanceof Date ? config.default.toISOString() : config.default;
6090
+ data.t = config.type;
6091
+ }
6092
+ if (config.fields) {
6093
+ const nested = collectFieldScriptSources(config.fields);
6094
+ if (nested.length > 0) {
6095
+ data.f = nested;
6096
+ data.a = !!config.array;
6097
+ }
6098
+ }
6099
+ if (Object.keys(data).length > 0) entries.push([name, data]);
6100
+ }
6101
+ return entries;
6102
+ }
6103
+ function computeSourceScriptHash(fields, options) {
6104
+ const fieldSources = collectFieldScriptSources(fields);
6105
+ if (!(fieldSources.length > 0 || options?.typeHookExpr?.create || options?.typeHookExpr?.update || options?.typeValidateExpr)) return void 0;
6106
+ const payload = [fieldSources];
6107
+ if (options?.typeHookExpr?.create) payload.push(["thc", options.typeHookExpr.create]);
6108
+ if (options?.typeHookExpr?.update) payload.push(["thu", options.typeHookExpr.update]);
6109
+ if (options?.typeValidateExpr) payload.push(["tve", options.typeValidateExpr]);
6110
+ return createHash("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
6111
+ }
6112
+ function extractSourceScriptHash(expr) {
6113
+ return expr.match(/\/\/ @sdk-source-hash:([0-9a-f]+)\s*$/)?.[1];
6114
+ }
6115
+ const isNestedType = (config) => config.type === "nested" && config.fields !== void 0;
6116
+ function serializeDefault(value, fieldType) {
6117
+ if (value === "now" && TIME_TYPES.has(fieldType)) return NOW;
6118
+ if (value instanceof Date) return `new Date(${JSON.stringify(value.toISOString())})`;
6119
+ return JSON.stringify(value);
6120
+ }
6121
+ /**
6122
+ * Build the object literal that reconstructs one record level with hook
6123
+ * overrides and defaults applied. For create, defaults are appended as
6124
+ * `?? defaultValue` after the hook expression (field hook → default).
6125
+ * Returns null when no field under this level has a hook or default for
6126
+ * the operation.
6127
+ * @param {Record<string, ScriptFieldConfig>} fields - Field configurations
6128
+ * @param {string} accessExpr - JS expression to access the parent object
6129
+ * @param {string} oldAccessExpr - JS expression to access the old record parent
6130
+ * @param {HookOperation} operation - Hook operation type
6131
+ * @param {boolean} nested - Whether building inside a nested field (rejects defaults)
6132
+ * @returns {string | null} Object literal expression or null
6133
+ */
6134
+ function buildHookObject(fields, accessExpr, oldAccessExpr, operation, nested = false) {
6135
+ const parts = [];
6136
+ for (const [name, config] of Object.entries(fields)) {
6137
+ const access = `${accessExpr}[${key(name)}]`;
6138
+ const oldAccess = `${oldAccessExpr}?.[${key(name)}]`;
6139
+ if (isNestedType(config) && config.fields) {
6140
+ if (config.array) {
6141
+ const inner = buildHookObject(config.fields, "__el", "undefined", operation, true);
6142
+ if (inner !== null) parts.push(`${key(name)}: (${access} || []).map((__el) => Object.assign({}, __el, ${inner}))`);
6143
+ } else {
6144
+ const inner = buildHookObject(config.fields, `(${access} || {})`, oldAccess, operation, true);
6145
+ if (inner !== null) parts.push(`${key(name)}: Object.assign({}, ${access}, ${inner})`);
6146
+ }
6147
+ continue;
6148
+ }
6149
+ const hook = config.hooks?.[operation];
6150
+ if (nested && config.default !== void 0) throw new Error(`.default() cannot be used on nested inner field "${name}"`);
6151
+ const hasDefault = operation === "create" && config.default !== void 0;
6152
+ if (hook && hasDefault) parts.push(`${key(name)}: ((_value) => (${hook.expr}))(${access}) ?? ${serializeDefault(config.default, config.type)}`);
6153
+ else if (hook && operation === "create") parts.push(`${key(name)}: ((_value) => (${hook.expr}))(${access})`);
6154
+ else if (hook) parts.push(`${key(name)}: ((_value, _oldValue) => (${hook.expr}))(${access}, ${oldAccess} ?? null)`);
6155
+ else if (hasDefault) parts.push(`${key(name)}: ${access} ?? ${serializeDefault(config.default, config.type)}`);
6156
+ }
6157
+ if (parts.length === 0) return null;
6158
+ return `{ ${parts.join(", ")} }`;
6159
+ }
6160
+ /**
6161
+ * Build validation statements for one record level.
6162
+ * Each leaf field with validators contributes a block that runs every
6163
+ * validator and records all failing messages keyed by dotted field path.
6164
+ * @param {Record<string, ScriptFieldConfig>} fields - Field configurations
6165
+ * @param {string} accessExpr - JS expression to access the parent object
6166
+ * @param {string} keyPrefix - Dotted path prefix for error keys
6167
+ * @returns {string[]} Array of validation statement strings
6168
+ */
6169
+ function buildValidateStatements(fields, accessExpr, keyPrefix) {
6170
+ const statements = [];
6171
+ for (const [name, config] of Object.entries(fields)) {
6172
+ const access = `${accessExpr}[${key(name)}]`;
6173
+ const fieldPath = keyPrefix ? `${keyPrefix}.${name}` : name;
6174
+ const validators = (config.validate ?? []).filter((v) => v.script?.expr);
6175
+ if (validators.length > 0) {
6176
+ const checks = validators.map((v) => `{ const __r = (${v.script?.expr}); if (typeof __r === "string") { __errs[${key(fieldPath)}] = __r; } }`).join("\n");
6177
+ statements.push(`{ const _value = ${access};\n${checks}\n}`);
6178
+ }
6179
+ if (isNestedType(config) && config.fields) if (config.array) {
6180
+ const innerParts = [];
6181
+ for (const [innerName, innerConfig] of Object.entries(config.fields)) {
6182
+ const innerValidators = (innerConfig.validate ?? []).filter((v) => v.script?.expr);
6183
+ if (innerValidators.length > 0) {
6184
+ const errorKeyExpr = `${JSON.stringify(fieldPath + "[")} + __idx + ${JSON.stringify("]." + innerName)}`;
6185
+ const checks = innerValidators.map((v) => `{ const __r = (${v.script?.expr}); if (typeof __r === "string") { __errs[${errorKeyExpr}] = __r; } }`).join("\n");
6186
+ innerParts.push(`{ const _value = __el[${key(innerName)}];\n${checks}\n}`);
6187
+ }
6188
+ }
6189
+ if (innerParts.length > 0) statements.push(`(${access} || []).forEach((__el, __idx) => {\n${innerParts.join("\n")}\n});`);
6190
+ } else {
6191
+ const nested = buildValidateStatements(config.fields, access, fieldPath);
6192
+ if (nested.length > 0) statements.push(`if (${access} != null) {\n${nested.join("\n")}\n}`);
6193
+ }
6194
+ }
6195
+ return statements;
6196
+ }
6197
+ function wrapHook(objectExpr) {
6198
+ return `((_invoker) => { const ${NOW} = new Date(); return ${objectExpr}; })(typeof _invoker !== "undefined" ? _invoker : undefined)`;
6199
+ }
6200
+ function wrapValidate(statements, typeValidateExpr) {
6201
+ const issuesFn = typeValidateExpr ? " const __issues = (f, m) => { __errs[f] = m; };" : "";
6202
+ const typeValidateStmt = typeValidateExpr ? ` ${typeValidateExpr};` : "";
6203
+ return `((_invoker) => { const __errs = {};${issuesFn}\n${statements.join("\n")}${typeValidateStmt}\nreturn __errs; })(typeof _invoker !== "undefined" ? _invoker : undefined)`;
6204
+ }
6205
+ /**
6206
+ * Aggregate every field's create/update hook, default, and validate into
6207
+ * type-level scripts. Hooks compute a single shared timestamp (`now`) per
6208
+ * operation, so all fields touched in one create/update observe the same
6209
+ * instant. Defaults are applied after hooks on create only. Validators
6210
+ * run with the same rules on create and update.
6211
+ * @param fields - Per-field script configuration
6212
+ * @param options - Optional type-level hook/validate expressions
6213
+ * @returns Aggregated type-level scripts
6214
+ */
6215
+ function buildTypeScripts(fields, options) {
6216
+ const result = {};
6217
+ const typeHookExpr = options?.typeHookExpr;
6218
+ const typeValidateExpr = options?.typeValidateExpr;
6219
+ const hash = computeSourceScriptHash(fields, options);
6220
+ const hashSuffix = hash ? ` ${SOURCE_HASH_PREFIX}${hash}` : "";
6221
+ const hook = {};
6222
+ for (const operation of ["create", "update"]) {
6223
+ const perFieldExpr = buildHookObject(fields, INPUT, OLD_RECORD, operation);
6224
+ const typeLevelExpr = typeHookExpr?.[operation];
6225
+ let expr;
6226
+ if (perFieldExpr !== null && typeLevelExpr) expr = `((_invoker) => { const ${NOW} = new Date(); const __fl = ${perFieldExpr}; return Object.assign({}, __fl, ((${INPUT}) => ${typeLevelExpr})(Object.assign({}, ${INPUT}, __fl))); })(typeof _invoker !== "undefined" ? _invoker : undefined)`;
6227
+ else if (typeLevelExpr) expr = wrapHook(typeLevelExpr);
6228
+ else if (perFieldExpr !== null) expr = wrapHook(perFieldExpr);
6229
+ if (expr) hook[operation] = { expr: expr + hashSuffix };
6230
+ }
6231
+ if (hook.create || hook.update) result.typeHook = hook;
6232
+ const statements = buildValidateStatements(fields, NEW_RECORD, "");
6233
+ if (statements.length > 0 || typeValidateExpr) {
6234
+ const expr = wrapValidate(statements, typeValidateExpr) + hashSuffix;
6235
+ result.typeValidate = {
6236
+ create: { expr },
6237
+ update: { expr }
6238
+ };
6239
+ }
6240
+ return result;
6241
+ }
6242
+
6253
6243
  //#endregion
6254
6244
  //#region src/cli/commands/tailordb/migrate/migration-number.ts
6255
6245
  /**
@@ -6341,6 +6331,7 @@ const snapshotFieldConfigSchema = z.looseObject({
6341
6331
  validate: z.array(snapshotValidationSchema).optional(),
6342
6332
  serial: snapshotSerialSchema.optional(),
6343
6333
  scale: z.number().optional(),
6334
+ default: z.unknown().optional(),
6344
6335
  fields: z.lazy(() => snapshotRecordSchema(snapshotFieldConfigSchema)).optional()
6345
6336
  });
6346
6337
  const snapshotIndexConfigSchema = z.looseObject({
@@ -6586,6 +6577,20 @@ const permissionModifiedChangeSchema = z.looseObject({
6586
6577
  before: snapshotPermissionStateSchema.optional(),
6587
6578
  after: snapshotPermissionStateSchema.optional()
6588
6579
  });
6580
+ const typeScriptsStateSchema = z.looseObject({
6581
+ typeHookExpr: z.looseObject({
6582
+ create: z.string().optional(),
6583
+ update: z.string().optional()
6584
+ }).optional(),
6585
+ typeValidateExpr: z.string().optional()
6586
+ });
6587
+ const typeScriptsModifiedChangeSchema = z.looseObject({
6588
+ kind: z.literal("type_scripts_modified"),
6589
+ typeName: z.string(),
6590
+ reason: z.string().optional(),
6591
+ before: typeScriptsStateSchema,
6592
+ after: typeScriptsStateSchema
6593
+ });
6589
6594
  const diffChangeSchema = z.discriminatedUnion("kind", [
6590
6595
  typeAddedChangeSchema,
6591
6596
  typeRemovedChangeSchema,
@@ -6603,7 +6608,8 @@ const diffChangeSchema = z.discriminatedUnion("kind", [
6603
6608
  relationshipAddedChangeSchema,
6604
6609
  relationshipRemovedChangeSchema,
6605
6610
  relationshipModifiedChangeSchema,
6606
- permissionModifiedChangeSchema
6611
+ permissionModifiedChangeSchema,
6612
+ typeScriptsModifiedChangeSchema
6607
6613
  ]);
6608
6614
  const breakingChangeInfoSchema = z.looseObject({
6609
6615
  typeName: z.string(),
@@ -6807,6 +6813,7 @@ function createSnapshotFieldConfigFromOperatorConfig(fieldConfig) {
6807
6813
  ...fieldConfig.serial.format && { format: fieldConfig.serial.format }
6808
6814
  };
6809
6815
  if (fieldConfig.scale !== void 0) config.scale = fieldConfig.scale;
6816
+ if (fieldConfig.default !== void 0) config.default = fieldConfig.default;
6810
6817
  if (fieldConfig.fields && Object.keys(fieldConfig.fields).length > 0) {
6811
6818
  config.fields = {};
6812
6819
  for (const [nestedName, nestedConfig] of Object.entries(fieldConfig.fields)) config.fields[nestedName] = createSnapshotFieldConfigFromOperatorConfig(nestedConfig);
@@ -6848,6 +6855,8 @@ function createSnapshotType(type) {
6848
6855
  };
6849
6856
  }
6850
6857
  if (type.files && Object.keys(type.files).length > 0) snapshotType.files = { ...type.files };
6858
+ if (type.typeHookExpr) snapshotType.typeHookExpr = type.typeHookExpr;
6859
+ if (type.typeValidateExpr) snapshotType.typeValidateExpr = type.typeValidateExpr;
6851
6860
  if (Object.keys(type.forwardRelationships).length > 0) {
6852
6861
  snapshotType.forwardRelationships = {};
6853
6862
  for (const [relName, rel] of Object.entries(type.forwardRelationships)) snapshotType.forwardRelationships[relName] = {
@@ -7031,6 +7040,18 @@ function applyDiffToSnapshot(snapshot, diff) {
7031
7040
  };
7032
7041
  break;
7033
7042
  }
7043
+ case "type_scripts_modified": {
7044
+ const existing = types[change.typeName];
7045
+ if (existing) {
7046
+ const { typeHookExpr: _, typeValidateExpr: __, ...rest } = existing;
7047
+ types[change.typeName] = {
7048
+ ...rest,
7049
+ ...change.after.typeHookExpr && { typeHookExpr: change.after.typeHookExpr },
7050
+ ...change.after.typeValidateExpr !== void 0 && { typeValidateExpr: change.after.typeValidateExpr }
7051
+ };
7052
+ }
7053
+ break;
7054
+ }
7034
7055
  case "field_added":
7035
7056
  case "field_modified": {
7036
7057
  const existing = types[change.typeName];
@@ -7255,6 +7276,10 @@ function areFieldsDifferent(oldField, newField) {
7255
7276
  if ((oldSerial.format ?? "") !== (newSerial.format ?? "")) return true;
7256
7277
  }
7257
7278
  if (oldField.scale !== newField.scale) return true;
7279
+ if (oldField.default !== newField.default) {
7280
+ if (typeof oldField.default !== typeof newField.default) return true;
7281
+ if (JSON.stringify(oldField.default) !== JSON.stringify(newField.default)) return true;
7282
+ }
7258
7283
  const oldFields = oldField.fields ?? {};
7259
7284
  const newFields = newField.fields ?? {};
7260
7285
  const oldFieldNames = Object.keys(oldFields);
@@ -7617,6 +7642,24 @@ function compareTypeSettings(ctx, typeName, previous, current) {
7617
7642
  after: snapshotTypeSettingsState(current)
7618
7643
  });
7619
7644
  }
7645
+ function typeScriptsState(type) {
7646
+ return {
7647
+ ...type.typeHookExpr && { typeHookExpr: type.typeHookExpr },
7648
+ ...type.typeValidateExpr !== void 0 && { typeValidateExpr: type.typeValidateExpr }
7649
+ };
7650
+ }
7651
+ function compareTypeScripts(ctx, typeName, previous, current) {
7652
+ const prevState = typeScriptsState(previous);
7653
+ const currState = typeScriptsState(current);
7654
+ if (JSON.stringify(prevState) === JSON.stringify(currState)) return;
7655
+ ctx.changes.push({
7656
+ kind: "type_scripts_modified",
7657
+ typeName,
7658
+ reason: "type-level scripts changed",
7659
+ before: prevState,
7660
+ after: currState
7661
+ });
7662
+ }
7620
7663
  /**
7621
7664
  * Compare two snapshots and generate a diff
7622
7665
  * @param {SchemaSnapshot} previous - Previous schema snapshot
@@ -7655,6 +7698,7 @@ function compareNormalizedSnapshots(previous, current) {
7655
7698
  const prevType = assertDefined(previous.types[typeName], `type "${typeName}" missing from previous snapshot`);
7656
7699
  const currType = assertDefined(current.types[typeName], `type "${typeName}" missing from current snapshot`);
7657
7700
  compareTypeSettings(ctx, typeName, prevType, currType);
7701
+ compareTypeScripts(ctx, typeName, prevType, currType);
7658
7702
  compareTypeFields(ctx, typeName, prevType, currType);
7659
7703
  compareIndexes(ctx, typeName, prevType.indexes, currType.indexes);
7660
7704
  compareFiles(ctx, typeName, prevType.files, currType.files);
@@ -8144,7 +8188,66 @@ const SYSTEM_FIELDS = /* @__PURE__ */ new Set(["id"]);
8144
8188
  * @returns {SchemaDrift[]} List of drifts detected
8145
8189
  */
8146
8190
  function compareRemoteWithSnapshot(remoteTypes, snapshot, remoteGqlPermissions = []) {
8147
- return compareNormalizedRemoteWithSnapshot(createRemoteComparableSnapshot(createSnapshotFromRemoteTypes(remoteTypes, snapshot.namespace, remoteGqlPermissions, snapshot)), createRemoteComparableSnapshot(snapshot));
8191
+ const structuralDrifts = compareNormalizedRemoteWithSnapshot(createRemoteComparableSnapshot(createSnapshotFromRemoteTypes(remoteTypes, snapshot.namespace, remoteGqlPermissions, snapshot)), createRemoteComparableSnapshot(snapshot));
8192
+ const scriptDrifts = compareScriptHashes(remoteTypes, snapshot);
8193
+ return [...structuralDrifts, ...scriptDrifts];
8194
+ }
8195
+ function extractRemoteScriptHash(remoteType) {
8196
+ const exprs = [
8197
+ remoteType.schema?.typeHook?.create?.expr,
8198
+ remoteType.schema?.typeHook?.update?.expr,
8199
+ remoteType.schema?.typeValidate?.create?.expr,
8200
+ remoteType.schema?.typeValidate?.update?.expr
8201
+ ];
8202
+ let found;
8203
+ for (const expr of exprs) if (expr) {
8204
+ const hash = extractSourceScriptHash(expr);
8205
+ if (hash) {
8206
+ if (found && found !== hash) return void 0;
8207
+ found = hash;
8208
+ }
8209
+ }
8210
+ return found;
8211
+ }
8212
+ function remoteHasScripts(remoteType) {
8213
+ return !!(remoteType.schema?.typeHook?.create?.expr || remoteType.schema?.typeHook?.update?.expr || remoteType.schema?.typeValidate?.create?.expr || remoteType.schema?.typeValidate?.update?.expr);
8214
+ }
8215
+ function compareScriptHashes(remoteTypes, snapshot) {
8216
+ const drifts = [];
8217
+ const remoteByName = new Map(remoteTypes.map((t) => [t.name, t]));
8218
+ for (const [typeName, snapshotType] of Object.entries(snapshot.types)) {
8219
+ const localHash = computeSourceScriptHash(snapshotType.fields, {
8220
+ typeHookExpr: snapshotType.typeHookExpr,
8221
+ typeValidateExpr: snapshotType.typeValidateExpr
8222
+ });
8223
+ const remoteType = remoteByName.get(typeName);
8224
+ if (!remoteType) continue;
8225
+ if (localHash) {
8226
+ const remoteHash = extractRemoteScriptHash(remoteType);
8227
+ if (localHash !== remoteHash) drifts.push({
8228
+ typeName,
8229
+ kind: "script_mismatch",
8230
+ details: remoteHash ? `Type '${typeName}' scripts differ between remote and snapshot` : `Type '${typeName}' has no script hash on remote`
8231
+ });
8232
+ } else if (remoteHasScripts(remoteType)) drifts.push({
8233
+ typeName,
8234
+ kind: "script_mismatch",
8235
+ details: `Type '${typeName}' has scripts on remote but not in snapshot`
8236
+ });
8237
+ }
8238
+ return drifts;
8239
+ }
8240
+ function stripFieldScriptProps(field) {
8241
+ const { hooks: _hooks, validate: _validate, default: _default, ...rest } = field;
8242
+ if (rest.fields) {
8243
+ const nested = createSnapshotRecord();
8244
+ for (const [name, f] of Object.entries(rest.fields)) nested[name] = stripFieldScriptProps(f);
8245
+ return {
8246
+ ...rest,
8247
+ fields: nested
8248
+ };
8249
+ }
8250
+ return rest;
8148
8251
  }
8149
8252
  function createRemoteComparableSnapshot(snapshot) {
8150
8253
  const types = createSnapshotRecord();
@@ -8152,10 +8255,11 @@ function createRemoteComparableSnapshot(snapshot) {
8152
8255
  const fields = createSnapshotRecord();
8153
8256
  for (const [fieldName, field] of Object.entries(type.fields)) {
8154
8257
  if (SYSTEM_FIELDS.has(fieldName)) continue;
8155
- fields[fieldName] = field;
8258
+ fields[fieldName] = stripFieldScriptProps(field);
8156
8259
  }
8260
+ const { typeHookExpr: _, typeValidateExpr: __, ...typeRest } = type;
8157
8261
  types[typeName] = {
8158
- ...type,
8262
+ ...typeRest,
8159
8263
  fields
8160
8264
  };
8161
8265
  }
@@ -8265,6 +8369,11 @@ function schemaDriftFromDiffChange(change) {
8265
8369
  kind: "permission_mismatch",
8266
8370
  details: change.reason ?? "Permissions differ between remote and snapshot"
8267
8371
  };
8372
+ case "type_scripts_modified": return {
8373
+ typeName: change.typeName,
8374
+ kind: "script_mismatch",
8375
+ details: change.reason ?? "Type-level scripts differ between remote and snapshot"
8376
+ };
8268
8377
  default: throw new Error("Unsupported diff change");
8269
8378
  }
8270
8379
  }
@@ -8349,6 +8458,10 @@ function generateTailorDBTypeManifestFromSnapshot(snapshotType, options = {}) {
8349
8458
  update: [],
8350
8459
  delete: []
8351
8460
  };
8461
+ const { typeHook, typeValidate } = buildTypeScripts(snapshotType.fields, {
8462
+ typeHookExpr: snapshotType.typeHookExpr,
8463
+ typeValidateExpr: snapshotType.typeValidateExpr
8464
+ });
8352
8465
  return {
8353
8466
  name: snapshotType.name,
8354
8467
  schema: {
@@ -8360,10 +8473,15 @@ function generateTailorDBTypeManifestFromSnapshot(snapshotType, options = {}) {
8360
8473
  directives: [],
8361
8474
  indexes,
8362
8475
  files,
8363
- permission
8476
+ permission,
8477
+ ...typeHook && { typeHook },
8478
+ ...typeValidate && { typeValidate }
8364
8479
  }
8365
8480
  };
8366
8481
  }
8482
+ function optionalOnCreate(config) {
8483
+ return config.hooks?.create || config.default !== void 0 ? { optionalOnCreate: true } : {};
8484
+ }
8367
8485
  /**
8368
8486
  * Convert a snapshot field config to proto format
8369
8487
  * @param {SnapshotFieldConfig} config - Snapshot field config
@@ -8374,7 +8492,6 @@ function convertFieldConfigToProto(config) {
8374
8492
  type: config.type,
8375
8493
  allowedValues: config.type === "enum" ? config.allowedValues?.map((v) => ({ ...v })) ?? [] : [],
8376
8494
  description: config.description || "",
8377
- validate: toProtoSnapshotFieldValidate(config),
8378
8495
  array: config.array ?? false,
8379
8496
  index: config.index ?? false,
8380
8497
  unique: config.unique ?? false,
@@ -8383,7 +8500,7 @@ function convertFieldConfigToProto(config) {
8383
8500
  foreignKeyField: config.foreignKeyField,
8384
8501
  required: config.required,
8385
8502
  vector: config.vector ?? false,
8386
- ...toProtoSnapshotFieldHooks(config),
8503
+ ...optionalOnCreate(config),
8387
8504
  ...config.serial && { serial: {
8388
8505
  start: BigInt(config.serial.start),
8389
8506
  ...config.serial.maxValue !== void 0 && { maxValue: BigInt(config.serial.maxValue) },
@@ -8394,20 +8511,6 @@ function convertFieldConfigToProto(config) {
8394
8511
  if (config.type === "nested" && config.fields) fieldEntry.fields = processNestedFieldsFromSnapshot(config.fields);
8395
8512
  return fieldEntry;
8396
8513
  }
8397
- function toProtoSnapshotFieldValidate(config) {
8398
- return (config.validate ?? []).map((val) => ({
8399
- action: TailorDBType_PermitAction.DENY,
8400
- errorMessage: val.errorMessage || "",
8401
- script: { expr: val.script && val.script.expr ? `!${val.script.expr}` : "" }
8402
- }));
8403
- }
8404
- function toProtoSnapshotFieldHooks(config) {
8405
- if (!config.hooks) return {};
8406
- return { hooks: {
8407
- create: config.hooks.create ? { expr: config.hooks.create.expr || "" } : void 0,
8408
- update: config.hooks.update ? { expr: config.hooks.update.expr || "" } : void 0
8409
- } };
8410
- }
8411
8514
  /**
8412
8515
  * Process nested fields from snapshot format to proto format
8413
8516
  * @param {Record<string, SnapshotFieldConfig>} fields - Nested fields
@@ -8421,14 +8524,12 @@ function processNestedFieldsFromSnapshot(fields) {
8421
8524
  type: "nested",
8422
8525
  allowedValues: fieldConfig.allowedValues?.map((v) => ({ ...v })) ?? [],
8423
8526
  description: fieldConfig.description || "",
8424
- validate: toProtoSnapshotFieldValidate(fieldConfig),
8425
8527
  required: fieldConfig.required,
8426
8528
  array: fieldConfig.array ?? false,
8427
8529
  index: false,
8428
8530
  unique: false,
8429
8531
  foreignKey: false,
8430
8532
  vector: false,
8431
- ...toProtoSnapshotFieldHooks(fieldConfig),
8432
8533
  fields: deepNestedFields,
8433
8534
  ...fieldConfig.scale !== void 0 && { scale: fieldConfig.scale }
8434
8535
  };
@@ -8436,14 +8537,13 @@ function processNestedFieldsFromSnapshot(fields) {
8436
8537
  type: fieldConfig.type,
8437
8538
  allowedValues: fieldConfig.type === "enum" ? fieldConfig.allowedValues?.map((v) => ({ ...v })) ?? [] : [],
8438
8539
  description: fieldConfig.description || "",
8439
- validate: toProtoSnapshotFieldValidate(fieldConfig),
8440
8540
  required: fieldConfig.required,
8441
8541
  array: fieldConfig.array ?? false,
8442
8542
  index: false,
8443
8543
  unique: false,
8444
8544
  foreignKey: false,
8445
8545
  vector: false,
8446
- ...toProtoSnapshotFieldHooks(fieldConfig),
8546
+ ...optionalOnCreate(fieldConfig),
8447
8547
  ...fieldConfig.serial && { serial: {
8448
8548
  start: BigInt(fieldConfig.serial.start),
8449
8549
  ...fieldConfig.serial.maxValue !== void 0 && { maxValue: BigInt(fieldConfig.serial.maxValue) },
@@ -9764,14 +9864,6 @@ const migrationSnapshotCache = {
9764
9864
  return snapshot;
9765
9865
  }
9766
9866
  };
9767
- /**
9768
- * Build the TailorDBType manifest for `typeName` from migration N's snapshot.
9769
- * @param migration - The pending migration whose snapshot to consult
9770
- * @param typeName - The type name to look up in the snapshot
9771
- * @param tailorDBInputs - Deploy inputs, used to resolve namespace gqlOperations
9772
- * @param executorUsedTypes - Types used by executors (drives publishRecordEvents default)
9773
- * @returns The manifest, or undefined if `typeName` is not in that snapshot.
9774
- */
9775
9867
  function buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes) {
9776
9868
  const snapshotType = migrationSnapshotCache.load(migration).types[typeName];
9777
9869
  if (!snapshotType) return void 0;
@@ -10282,18 +10374,28 @@ function normalizeComparableTailorDBType(type) {
10282
10374
  settings: normalized?.schema?.settings ?? {},
10283
10375
  indexes: normalized?.schema?.indexes ?? {},
10284
10376
  files: normalized?.schema?.files ?? {},
10285
- permission: normalized?.schema?.permission ?? {}
10377
+ permission: normalized?.schema?.permission ?? {},
10378
+ typeHook: normalized?.schema?.typeHook ?? {},
10379
+ typeValidate: normalized?.schema?.typeValidate ?? {}
10286
10380
  }
10287
10381
  }, []);
10288
10382
  }
10289
10383
  function normalizeTailorDBCompareValue(value, path) {
10290
10384
  if (value === void 0 || value === null) return value;
10385
+ if (typeof value === "boolean") {
10386
+ if (path.at(-1) === "optionalOnCreate" && value === false) return;
10387
+ return value;
10388
+ }
10291
10389
  if (typeof value === "number" || typeof value === "bigint" || typeof value === "string") {
10292
10390
  if (matchesNumericStringPath(path) && isNumericLikeValue(value)) return String(value);
10293
10391
  if ((path.at(-1) === "expr" || path.at(-1) === "description") && value === tailordbCompareKnownDefaults.emptyExpression) return;
10294
10392
  return value;
10295
10393
  }
10296
- if (Array.isArray(value)) return value.map((item, index) => normalizeTailorDBCompareValue(item, [...path, index])).filter((item) => item !== void 0);
10394
+ if (Array.isArray(value)) {
10395
+ const items = value.map((item, index) => normalizeTailorDBCompareValue(item, [...path, index])).filter((item) => item !== void 0);
10396
+ if (items.length === 0 && path.at(-1) === "validate") return;
10397
+ return items;
10398
+ }
10297
10399
  if (!isPlainObject(value)) return value;
10298
10400
  const normalizedEntries = Object.entries(value).map(([key, entryValue]) => [key, normalizeTailorDBCompareValue(entryValue, [...path, key])]).filter(([, entryValue]) => entryValue !== void 0);
10299
10401
  const normalizedObject = Object.fromEntries(normalizedEntries);
@@ -10546,11 +10648,11 @@ async function registerJobFunctions(client, changeSet, appName, appId, unchanged
10546
10648
  const allUsedJobNames = /* @__PURE__ */ new Set();
10547
10649
  unchangedWorkflowJobNames.forEach((jobName) => allUsedJobNames.add(jobName));
10548
10650
  for (const item of [...changeSet.creates, ...changeSet.updates]) for (const jobName of item.usedJobNames) allUsedJobNames.add(jobName);
10549
- const existingJobFunctions = await fetchAll(async (pageToken, _maxPageSize) => {
10651
+ const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
10550
10652
  const response = await client.listWorkflowJobFunctions({
10551
10653
  workspaceId,
10552
10654
  pageToken,
10553
- pageSize: 100
10655
+ pageSize: maxPageSize
10554
10656
  });
10555
10657
  return [response.jobFunctions.map((j) => j.name), response.nextPageToken];
10556
10658
  });
@@ -10730,11 +10832,11 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
10730
10832
  }
10731
10833
  async function planWorkflowJobFunctionDeletes(params) {
10732
10834
  const { client, workspaceId, appName, appId, retainedWorkflowJobNames } = params;
10733
- const existingJobFunctions = await fetchAll(async (pageToken, _maxPageSize) => {
10835
+ const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
10734
10836
  const response = await client.listWorkflowJobFunctions({
10735
10837
  workspaceId,
10736
10838
  pageToken,
10737
- pageSize: 100
10839
+ pageSize: maxPageSize
10738
10840
  });
10739
10841
  return [response.jobFunctions.map((jobFunction) => jobFunction.name), response.nextPageToken];
10740
10842
  });
@@ -10814,6 +10916,198 @@ function normalizeRetryPolicyForCompare(policy) {
10814
10916
  };
10815
10917
  }
10816
10918
 
10919
+ //#endregion
10920
+ //#region src/cli/commands/deploy/workflow-execution-policy.ts
10921
+ function toConcurrencyPolicyInit(policy) {
10922
+ if (!policy) return void 0;
10923
+ return { maxConcurrentExecutions: policy.maxConcurrentExecutions };
10924
+ }
10925
+ function normalizeComparableConcurrency(policy) {
10926
+ if (!policy || !policy.maxConcurrentExecutions) return void 0;
10927
+ return { maxConcurrentExecutions: policy.maxConcurrentExecutions };
10928
+ }
10929
+ /**
10930
+ * The declared key prefix, regardless of variant. `ExecutionPolicyWildcardInstance`
10931
+ * omits `key` from its public type to force callers through `keyFor()`, but
10932
+ * the underlying value always carries it when produced by
10933
+ * `defineWorkflowExecutionPolicy()` or `defineWorkflowExecutionPolicies()`.
10934
+ * @param policy - Declared policy from the config
10935
+ * @returns The declared key prefix
10936
+ */
10937
+ function declaredKey(policy) {
10938
+ if (policy.matchType === "exact") return policy.key;
10939
+ const key = policy.key;
10940
+ if (typeof key !== "string") throw new Error(`Invalid workflow execution policy "${policy.name}": prefix policies must be created via defineWorkflowExecutionPolicy() or defineWorkflowExecutionPolicies(), not a hand-constructed object.`);
10941
+ return key;
10942
+ }
10943
+ /**
10944
+ * The literal key the platform registers for a declared policy: `key` with a
10945
+ * trailing `*` appended when `matchType` is `"prefix"`.
10946
+ * @param policy - Declared policy from the config
10947
+ * @returns The platform-facing execution policy key
10948
+ */
10949
+ function toPlatformExecutionPolicyKey(policy) {
10950
+ const key = declaredKey(policy);
10951
+ return policy.matchType === "prefix" ? `${key}*` : key;
10952
+ }
10953
+ /**
10954
+ * Validate a declared execution policy against the parser schema. Throws with
10955
+ * a descriptive error when `name` or the platform-facing key violates the
10956
+ * platform grammar.
10957
+ * @param policy - Declared policy from the config
10958
+ */
10959
+ function validatePolicy(policy) {
10960
+ if (declaredKey(policy).endsWith("*")) throw new Error(`Invalid workflow execution policy "${policy.name}": key must not end with '*'; omit the '*' and set matchType: "prefix" for wildcard policies (the SDK appends '*' automatically).`);
10961
+ const parsed = WorkflowJobFunctionExecutionPolicySchema.safeParse({
10962
+ name: policy.name,
10963
+ key: toPlatformExecutionPolicyKey(policy),
10964
+ concurrencyPolicy: policy.concurrencyPolicy
10965
+ });
10966
+ if (!parsed.success) throw new Error(`Invalid workflow execution policy "${policy.name}": ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
10967
+ }
10968
+ /**
10969
+ * Plan workflow job function execution policy changes based on desired
10970
+ * declarations and current remote state.
10971
+ * @param client - Operator client instance
10972
+ * @param workspaceId - Workspace ID
10973
+ * @param appName - Application name
10974
+ * @param appId - Application ID for ownership metadata
10975
+ * @param declared - Policies declared in the config (property name → instance)
10976
+ * @returns Planned execution policy changes
10977
+ */
10978
+ async function planWorkflowJobFunctionExecutionPolicy(client, workspaceId, appName, appId, declared) {
10979
+ const changeSet = createChangeSet("Workflow execution policies");
10980
+ const conflicts = [];
10981
+ const unmanaged = [];
10982
+ const resourceOwners = /* @__PURE__ */ new Set();
10983
+ const declaredList = Object.values(declared);
10984
+ for (const policy of declaredList) validatePolicy(policy);
10985
+ const existing = await fetchExistingResourcesWithLabels({
10986
+ client,
10987
+ fetchPage: async (pageToken, pageSize) => {
10988
+ const response = await client.listWorkflowJobFunctionExecutionPolicies({
10989
+ workspaceId,
10990
+ pageToken,
10991
+ pageSize
10992
+ });
10993
+ return [response.policies, response.nextPageToken];
10994
+ },
10995
+ getName: (resource) => resource.name,
10996
+ getTrn: (name) => resourceTrn(workspaceId, "workflow_job_function_execution_policy", name)
10997
+ });
10998
+ const seenNames = /* @__PURE__ */ new Set();
10999
+ for (const policy of declaredList) {
11000
+ if (seenNames.has(policy.name)) throw new Error(`Duplicate workflow execution policy name "${policy.name}". Each policy must have a unique name within the workspace.`);
11001
+ seenNames.add(policy.name);
11002
+ const metaRequest = await buildMetaRequest({
11003
+ trn: resourceTrn(workspaceId, "workflow_job_function_execution_policy", policy.name),
11004
+ appName,
11005
+ appId
11006
+ });
11007
+ const found = existing[policy.name];
11008
+ if (found) {
11009
+ const owned = trackDesiredResourceOwnership({
11010
+ labels: found.allLabels,
11011
+ ownerLabel: found.label,
11012
+ appName,
11013
+ appId,
11014
+ resourceType: "Workflow execution policy",
11015
+ resourceName: policy.name,
11016
+ conflicts,
11017
+ unmanaged
11018
+ });
11019
+ const remoteKey = found.resource.executionPolicyKey;
11020
+ const desiredKey = toPlatformExecutionPolicyKey(policy);
11021
+ const remoteConcurrency = normalizeComparableConcurrency(found.resource.concurrencyPolicy);
11022
+ const desiredConcurrency = normalizeComparableConcurrency(policy.concurrencyPolicy);
11023
+ if (owned && hasMatchingSdkVersion(found.allLabels, metaRequest.labels) && remoteKey === desiredKey && areNormalizedEqual(remoteConcurrency, desiredConcurrency)) changeSet.unchanged.push({ name: policy.name });
11024
+ else if (remoteKey !== desiredKey) changeSet.replaces.push({
11025
+ name: policy.name,
11026
+ workspaceId,
11027
+ policy,
11028
+ metaRequest
11029
+ });
11030
+ else changeSet.updates.push({
11031
+ name: policy.name,
11032
+ workspaceId,
11033
+ policy,
11034
+ metaRequest
11035
+ });
11036
+ delete existing[policy.name];
11037
+ } else changeSet.creates.push({
11038
+ name: policy.name,
11039
+ workspaceId,
11040
+ policy,
11041
+ metaRequest
11042
+ });
11043
+ }
11044
+ for (const [name, remaining] of Object.entries(existing)) {
11045
+ if (!remaining) continue;
11046
+ if (trackRemainingResourceOwner({
11047
+ labels: remaining.allLabels,
11048
+ ownerLabel: remaining.label,
11049
+ appName,
11050
+ appId,
11051
+ resourceOwners
11052
+ })) changeSet.deletes.push({
11053
+ name,
11054
+ workspaceId
11055
+ });
11056
+ }
11057
+ return {
11058
+ changeSet,
11059
+ conflicts,
11060
+ unmanaged,
11061
+ resourceOwners
11062
+ };
11063
+ }
11064
+ /**
11065
+ * Apply planned workflow execution policy changes for the given phase.
11066
+ * @param client - Operator client instance
11067
+ * @param plan - Result of `planWorkflowJobFunctionExecutionPolicy`
11068
+ * @param phase - Apply phase
11069
+ * @returns Promise that resolves when policies are applied
11070
+ */
11071
+ async function applyWorkflowJobFunctionExecutionPolicy(client, plan, phase = "create-update") {
11072
+ const { changeSet } = plan;
11073
+ if (phase === "create-update") await Promise.all([
11074
+ ...changeSet.replaces.map(async (replace) => {
11075
+ await client.deleteWorkflowJobFunctionExecutionPolicy({
11076
+ workspaceId: replace.workspaceId,
11077
+ executionPolicyName: replace.name
11078
+ });
11079
+ await client.createWorkflowJobFunctionExecutionPolicy({
11080
+ workspaceId: replace.workspaceId,
11081
+ executionPolicyName: replace.policy.name,
11082
+ executionPolicyKey: toPlatformExecutionPolicyKey(replace.policy),
11083
+ concurrencyPolicy: toConcurrencyPolicyInit(replace.policy.concurrencyPolicy)
11084
+ });
11085
+ await client.setMetadata(replace.metaRequest);
11086
+ }),
11087
+ ...changeSet.creates.map(async (create) => {
11088
+ await client.createWorkflowJobFunctionExecutionPolicy({
11089
+ workspaceId: create.workspaceId,
11090
+ executionPolicyName: create.policy.name,
11091
+ executionPolicyKey: toPlatformExecutionPolicyKey(create.policy),
11092
+ concurrencyPolicy: toConcurrencyPolicyInit(create.policy.concurrencyPolicy)
11093
+ });
11094
+ await client.setMetadata(create.metaRequest);
11095
+ }),
11096
+ ...changeSet.updates.map(async (update) => {
11097
+ await client.updateWorkflowJobFunctionExecutionPolicy({
11098
+ workspaceId: update.workspaceId,
11099
+ executionPolicyName: update.policy.name,
11100
+ concurrencyPolicy: toConcurrencyPolicyInit(update.policy.concurrencyPolicy)
11101
+ });
11102
+ await client.setMetadata(update.metaRequest);
11103
+ })
11104
+ ]);
11105
+ else await Promise.all(changeSet.deletes.map((del) => client.deleteWorkflowJobFunctionExecutionPolicy({
11106
+ workspaceId: del.workspaceId,
11107
+ executionPolicyName: del.name
11108
+ })));
11109
+ }
11110
+
10817
11111
  //#endregion
10818
11112
  //#region src/cli/commands/deploy/apply-phases.ts
10819
11113
  /**
@@ -10847,10 +11141,12 @@ async function applyDeploymentPlans(client, workspaceId, deployments) {
10847
11141
  });
10848
11142
  await withSpan("apply.createUpdateDependentServices", async () => {
10849
11143
  await forEachDeployment((d) => applyExecutor(client, d.executor, "create-update"));
11144
+ await forEachDeployment((d) => applyWorkflowJobFunctionExecutionPolicy(client, d.workflowExecutionPolicy, "create-update"));
10850
11145
  await forEachDeployment((d) => applyWorkflow(client, d.workflow, "create-update"));
10851
11146
  });
10852
11147
  await withSpan("apply.deleteDependentServices", async () => {
10853
11148
  await forEachDeployment((d) => applyWorkflow(client, d.workflow, "delete"));
11149
+ await forEachDeployment((d) => applyWorkflowJobFunctionExecutionPolicy(client, d.workflowExecutionPolicy, "delete"));
10854
11150
  await forEachDeployment((d) => applyExecutor(client, d.executor, "delete"));
10855
11151
  await forEachDeployment((d) => applyStaticWebsite(client, d.staticWebsite, "delete"));
10856
11152
  await forEachDeployment((d) => applyAIGateway(client, d.aiGateway, "delete"));
@@ -11159,13 +11455,14 @@ function validateItems(params) {
11159
11455
  *
11160
11456
  * Collections not validated: idp client, tailorDB gqlPermission, functionRegistry — no
11161
11457
  * buf.validate annotations.
11162
- * Application cors and IdP userAuthPolicy.allowedReturnOrigins receive special
11163
- * handling: static-website URL placeholders are resolved at apply time, so the
11458
+ * Application cors, AIGateway cors, and IdP userAuthPolicy.allowedReturnOrigins receive
11459
+ * special handling: static-website URL placeholders are resolved at apply time, so the
11164
11460
  * relevant origin/URL constraints would false-positive on `<name>:url` entries
11165
- * here. Application cors is dropped entirely (no other constraint to lose); IdP
11166
- * `allowedReturnOrigins` substitutes placeholder entries with a dummy origin so
11167
- * the per-item regex and the cross-field `enable_mfa requires ≥1 origin` rule
11168
- * still get exercised on the rest of the payload.
11461
+ * here. Application cors and AIGateway cors are dropped entirely, forgoing their
11462
+ * per-item URL/origin constraints for the whole list rather than substituting
11463
+ * placeholders; IdP `allowedReturnOrigins` instead substitutes placeholder entries
11464
+ * with a dummy origin so the per-item regex and the cross-field `enable_mfa requires
11465
+ * ≥1 origin` rule still get exercised on the rest of the payload.
11169
11466
  * Workflow jobFunctions map excluded: versions are registered at apply time (registerJobFunctions)
11170
11467
  * and the map field carries no min_items constraint. Job names are validated separately via
11171
11468
  * CreateWorkflowJobFunctionRequestSchema using usedJobNames from the workflow change set.
@@ -11175,7 +11472,7 @@ function validateItems(params) {
11175
11472
  * @param input - Plan results from the plan phase
11176
11473
  */
11177
11474
  async function validatePlan(input) {
11178
- const { tailorDB, staticWebsite, idp, auth, pipeline, app, executor, workflow, secretManager } = input;
11475
+ const { tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, workflowExecutionPolicy, secretManager } = input;
11179
11476
  const validator = createValidator();
11180
11477
  const violations = [];
11181
11478
  function creates(schema, kind, items) {
@@ -11228,6 +11525,20 @@ async function validatePlan(input) {
11228
11525
  creates(CreateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.creates);
11229
11526
  updates(UpdateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.updates);
11230
11527
  creates(AddCustomDomainRequestSchema, "StaticWebsite custom domain", staticWebsite.customDomainChangeSet.creates);
11528
+ creates(CreateAIGatewayRequestSchema, "AIGateway", aiGateway.changeSet.creates.map((item) => ({
11529
+ name: item.name,
11530
+ request: {
11531
+ ...item.request,
11532
+ cors: void 0
11533
+ }
11534
+ })));
11535
+ updates(UpdateAIGatewayRequestSchema, "AIGateway", aiGateway.changeSet.updates.map((item) => ({
11536
+ name: item.name,
11537
+ request: {
11538
+ ...item.request,
11539
+ cors: void 0
11540
+ }
11541
+ })));
11231
11542
  const placeholderOriginReplacement = "https://placeholder.invalid";
11232
11543
  const substituteIdpReturnOrigins = (item) => {
11233
11544
  const request = item.request;
@@ -11318,6 +11629,23 @@ async function validatePlan(input) {
11318
11629
  }
11319
11630
  })));
11320
11631
  }
11632
+ creates(CreateWorkflowJobFunctionExecutionPolicyRequestSchema, "Workflow execution policy", [...workflowExecutionPolicy.changeSet.creates, ...workflowExecutionPolicy.changeSet.replaces].map((item) => ({
11633
+ name: item.name,
11634
+ request: {
11635
+ workspaceId: item.workspaceId,
11636
+ executionPolicyName: item.policy.name,
11637
+ executionPolicyKey: toPlatformExecutionPolicyKey(item.policy),
11638
+ ...item.policy.concurrencyPolicy && { concurrencyPolicy: { maxConcurrentExecutions: item.policy.concurrencyPolicy.maxConcurrentExecutions } }
11639
+ }
11640
+ })));
11641
+ updates(UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, "Workflow execution policy", workflowExecutionPolicy.changeSet.updates.map((item) => ({
11642
+ name: item.name,
11643
+ request: {
11644
+ workspaceId: item.workspaceId,
11645
+ executionPolicyName: item.policy.name,
11646
+ ...item.policy.concurrencyPolicy && { concurrencyPolicy: { maxConcurrentExecutions: item.policy.concurrencyPolicy.maxConcurrentExecutions } }
11647
+ }
11648
+ })));
11321
11649
  creates(CreateSecretManagerVaultRequestSchema, "Secret Manager vault", secretManager.vaultChangeSet.creates.map((item) => ({
11322
11650
  name: item.name,
11323
11651
  request: vaultCreateRequest(item)
@@ -11550,6 +11878,7 @@ function buildPlanReport(results) {
11550
11878
  const executorEntries = formatExecutorChangeEntries(results.executor.changeSet, buildPlannedExecutorsByName(results.executor.changeSet), results.functionRegistry.executorFunctionChanges);
11551
11879
  const resolverEntries = formatResolverChangeEntries(results.pipeline.changeSet.resolver, results.functionRegistry.resolverFunctionChanges);
11552
11880
  const workflowEntries = formatWorkflowChangeEntries(results.workflow.changeSet, results.functionRegistry.workflowJobChanges);
11881
+ const workflowExecutionPolicyEntries = formatChangeSetEntries(results.workflowExecutionPolicy.changeSet, ["executionPolicy"]);
11553
11882
  const authHookEntries = formatAuthHookChangeEntries(results.auth.changeSet.authHook, results.functionRegistry.authHookFunctionChanges);
11554
11883
  const tailorDBEntries = [...formatTailorDBResourceChangeEntries(results.tailorDB.changeSet.type, results.tailorDB.changeSet.gqlPermission)];
11555
11884
  const pipelineEntries = [...resolverEntries];
@@ -11580,6 +11909,7 @@ function buildPlanReport(results) {
11580
11909
  ...pipelineEntries,
11581
11910
  ...executorEntries,
11582
11911
  ...workflowEntries,
11912
+ ...workflowExecutionPolicyEntries,
11583
11913
  ...idpEntries,
11584
11914
  ...authEntries
11585
11915
  ];
@@ -11952,7 +12282,7 @@ async function planDeploymentTarget(params) {
11952
12282
  };
11953
12283
  const functionRegistry = await withSpan("plan.functionRegistry", () => planFunctionRegistry(client, workspaceId, application.name, application.id, functionEntries));
11954
12284
  const unchangedWorkflowJobs = new Set(functionRegistry.changeSet.unchanged.filter((entry) => entry.name.startsWith(WORKFLOW_PREFIX)).map((entry) => entry.name.slice(WORKFLOW_PREFIX.length)));
11955
- const [tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, secretManager] = await Promise.all([
12285
+ const [tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, workflowExecutionPolicy, secretManager] = await Promise.all([
11956
12286
  withSpan("plan.tailorDB", () => planTailorDB(ctx)),
11957
12287
  withSpan("plan.staticWebsite", () => planStaticWebsite(ctx)),
11958
12288
  withSpan("plan.aiGateway", () => planAIGateway(ctx)),
@@ -11962,6 +12292,7 @@ async function planDeploymentTarget(params) {
11962
12292
  withSpan("plan.application", () => planApplication(ctx, httpAdapterBuildResult)),
11963
12293
  withSpan("plan.executor", () => planExecutor(ctx)),
11964
12294
  withSpan("plan.workflow", () => planWorkflow(client, workspaceId, application.name, application.id, workflowService?.workflows ?? {}, workflowBuildResult?.mainJobDeps ?? {}, unchangedWorkflowJobs)),
12295
+ withSpan("plan.workflowExecutionPolicy", () => planWorkflowJobFunctionExecutionPolicy(client, workspaceId, application.name, application.id, config.workflow?.executionPolicies ?? {})),
11965
12296
  withSpan("plan.secretManager", () => planSecretManager(ctx))
11966
12297
  ]);
11967
12298
  return {
@@ -11976,6 +12307,7 @@ async function planDeploymentTarget(params) {
11976
12307
  app,
11977
12308
  executor,
11978
12309
  workflow,
12310
+ workflowExecutionPolicy,
11979
12311
  secretManager
11980
12312
  };
11981
12313
  });
@@ -11992,47 +12324,25 @@ function deploymentPlanResults(deployment) {
11992
12324
  const { application: _application, ...results } = deployment;
11993
12325
  return results;
11994
12326
  }
12327
+ /**
12328
+ * Every `PlanResults` entry except `app` carries ownership-tracking fields;
12329
+ * deriving the list from `results` itself (instead of naming each key) keeps
12330
+ * these collectors in sync with `PlannedDeployment` as resource types are added.
12331
+ * @param results - Plan results for a single deployment
12332
+ * @returns The ownership-tracking plan entries, `app` excluded
12333
+ */
12334
+ function ownershipTrackedPlans(results) {
12335
+ const { app: _app, ...rest } = results;
12336
+ return Object.values(rest);
12337
+ }
11995
12338
  function collectOwnerConflicts(results) {
11996
- return [
11997
- ...results.functionRegistry.conflicts,
11998
- ...results.tailorDB.conflicts,
11999
- ...results.staticWebsite.conflicts,
12000
- ...results.aiGateway.conflicts,
12001
- ...results.idp.conflicts,
12002
- ...results.auth.conflicts,
12003
- ...results.pipeline.conflicts,
12004
- ...results.executor.conflicts,
12005
- ...results.workflow.conflicts,
12006
- ...results.secretManager.conflicts
12007
- ];
12339
+ return ownershipTrackedPlans(results).flatMap((plan) => plan.conflicts);
12008
12340
  }
12009
12341
  function collectUnmanagedResources(results) {
12010
- return [
12011
- ...results.functionRegistry.unmanaged,
12012
- ...results.tailorDB.unmanaged,
12013
- ...results.staticWebsite.unmanaged,
12014
- ...results.aiGateway.unmanaged,
12015
- ...results.idp.unmanaged,
12016
- ...results.auth.unmanaged,
12017
- ...results.pipeline.unmanaged,
12018
- ...results.executor.unmanaged,
12019
- ...results.workflow.unmanaged,
12020
- ...results.secretManager.unmanaged
12021
- ];
12342
+ return ownershipTrackedPlans(results).flatMap((plan) => plan.unmanaged);
12022
12343
  }
12023
12344
  function collectResourceOwners(results) {
12024
- return /* @__PURE__ */ new Set([
12025
- ...results.functionRegistry.resourceOwners,
12026
- ...results.tailorDB.resourceOwners,
12027
- ...results.staticWebsite.resourceOwners,
12028
- ...results.aiGateway.resourceOwners,
12029
- ...results.idp.resourceOwners,
12030
- ...results.auth.resourceOwners,
12031
- ...results.pipeline.resourceOwners,
12032
- ...results.executor.resourceOwners,
12033
- ...results.workflow.resourceOwners,
12034
- ...results.secretManager.resourceOwners
12035
- ]);
12345
+ return new Set(ownershipTrackedPlans(results).flatMap((plan) => [...plan.resourceOwners]));
12036
12346
  }
12037
12347
  function collectImportantResourceDeletions(results) {
12038
12348
  const importantDeletions = [];
@@ -12176,6 +12486,12 @@ const DEPLOY_MANAGED_RESOURCE_DEFINITIONS = [
12176
12486
  namesOf: (target) => Object.values(target.application.workflowService?.workflows ?? {}).map((workflow) => workflow.name),
12177
12487
  changeSetOf: (results) => results.workflow.changeSet
12178
12488
  },
12489
+ {
12490
+ resourceLabel: "Workflow execution policy",
12491
+ resourceType: "workflow_job_function_execution_policy",
12492
+ namesOf: (target) => Object.values(target.config.workflow?.executionPolicies ?? {}).map((policy) => policy.name),
12493
+ changeSetOf: (results) => results.workflowExecutionPolicy.changeSet
12494
+ },
12179
12495
  {
12180
12496
  resourceLabel: "Auth connection",
12181
12497
  resourceType: "auth.connection",
@@ -13723,6 +14039,7 @@ async function resolveApplicationAuthNamespace(options) {
13723
14039
  async function startWorkflowByName(options) {
13724
14040
  const machineUser = await loadMachineUserName({
13725
14041
  machineUser: options.machineUser,
14042
+ machineUserSource: options.machineUserSource,
13726
14043
  profile: options.profile
13727
14044
  });
13728
14045
  if (!machineUser) throw new Error("Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.");
@@ -13793,6 +14110,7 @@ const startCommand = defineAppCommand({
13793
14110
  const { executionId, wait } = await startWorkflowByName({
13794
14111
  name: args.name,
13795
14112
  machineUser: args["machine-user"],
14113
+ machineUserSource: resolveMachineUserInputSource(args["machine-user"]),
13796
14114
  arg: args.arg,
13797
14115
  workspaceId: args["workspace-id"],
13798
14116
  profile: args.profile,
@@ -15578,14 +15896,10 @@ const listCommand$7 = defineAppCommand({
15578
15896
 
15579
15897
  //#endregion
15580
15898
  //#region src/cli/commands/machineuser/token.ts
15581
- /**
15582
- * Get a machine user access token for the current application.
15583
- * @param options - Token retrieval options
15584
- * @returns Machine user token info
15585
- */
15586
- async function getMachineUserToken(options) {
15899
+ async function getMachineUserTokenInternal(options) {
15587
15900
  const name = await loadMachineUserName({
15588
15901
  machineUser: options.name,
15902
+ machineUserSource: options.nameSource,
15589
15903
  profile: options.profile
15590
15904
  });
15591
15905
  if (!name) throw new Error("Machine user is required. Provide the NAME positional argument, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.");
@@ -15615,6 +15929,14 @@ async function getMachineUserToken(options) {
15615
15929
  expiresAt: expiresAt.toISOString()
15616
15930
  };
15617
15931
  }
15932
+ /**
15933
+ * Get a machine user access token for the current application.
15934
+ * @param options - Token retrieval options
15935
+ * @returns Machine user token info
15936
+ */
15937
+ async function getMachineUserToken(options) {
15938
+ return await getMachineUserTokenInternal(options);
15939
+ }
15618
15940
  const tokenCommand = defineAppCommand({
15619
15941
  name: "token",
15620
15942
  description: "Get an access token for a machine user.",
@@ -15622,13 +15944,13 @@ const tokenCommand = defineAppCommand({
15622
15944
  ...deploymentArgs,
15623
15945
  name: arg(z.string().optional(), {
15624
15946
  positional: true,
15625
- description: "Machine user name. Falls back to the active profile's default machine user.",
15626
- env: "TAILOR_PLATFORM_MACHINE_USER_NAME"
15947
+ description: "Machine user name. Falls back to TAILOR_PLATFORM_MACHINE_USER_NAME, then the active profile's default machine user."
15627
15948
  })
15628
15949
  }),
15629
15950
  run: async (args) => {
15630
- const token = await getMachineUserToken({
15951
+ const token = await getMachineUserTokenInternal({
15631
15952
  name: args.name,
15953
+ nameSource: resolveMachineUserInputSource(args.name, process.argv.slice(2), { valueIsExplicit: args.name !== void 0 }),
15632
15954
  workspaceId: args["workspace-id"],
15633
15955
  profile: args.profile,
15634
15956
  configPath: args.config
@@ -16298,62 +16620,67 @@ async function execRemove(client, workspaceId, application, config, confirm) {
16298
16620
  forRemoval: true,
16299
16621
  config
16300
16622
  };
16301
- const tailorDB = await planTailorDB(ctx);
16302
- const staticWebsite = await planStaticWebsite(ctx);
16303
- const aiGateway = await planAIGateway(ctx);
16304
- const idp = await planIdP(ctx);
16305
- const auth = await planAuth(ctx);
16306
- const pipeline = await planPipeline(ctx);
16307
- const app = await planApplication(ctx);
16308
- const executor = await planExecutor(ctx);
16309
- const workflow = await planWorkflow(client, workspaceId, application.name, application.id, {}, {});
16310
- const functionRegistry = await planFunctionRegistry(client, workspaceId, application.name, application.id, []);
16311
- const secretManager = await planSecretManager(ctx);
16623
+ const plans = {
16624
+ tailorDB: await planTailorDB(ctx),
16625
+ staticWebsite: await planStaticWebsite(ctx),
16626
+ aiGateway: await planAIGateway(ctx),
16627
+ idp: await planIdP(ctx),
16628
+ auth: await planAuth(ctx),
16629
+ pipeline: await planPipeline(ctx),
16630
+ app: await planApplication(ctx),
16631
+ executor: await planExecutor(ctx),
16632
+ workflow: await planWorkflow(client, workspaceId, application.name, application.id, {}, {}),
16633
+ workflowExecutionPolicy: await planWorkflowJobFunctionExecutionPolicy(client, workspaceId, application.name, application.id, {}),
16634
+ functionRegistry: await planFunctionRegistry(client, workspaceId, application.name, application.id, []),
16635
+ secretManager: await planSecretManager(ctx)
16636
+ };
16312
16637
  const removeLines = [
16313
- ...functionRegistry.changeSet.lines(),
16314
- ...staticWebsite.changeSet.lines(),
16315
- ...aiGateway.changeSet.lines(),
16316
- ...app.lines(),
16317
- ...tailorDB.changeSet.service.lines(),
16318
- ...tailorDB.changeSet.type.lines(),
16319
- ...tailorDB.changeSet.gqlPermission.lines(),
16320
- ...pipeline.changeSet.service.lines(),
16321
- ...pipeline.changeSet.resolver.lines(),
16322
- ...executor.changeSet.lines(),
16323
- ...workflow.changeSet.lines(),
16324
- ...idp.changeSet.service.lines(),
16325
- ...idp.changeSet.client.lines(),
16326
- ...auth.changeSet.service.lines(),
16327
- ...auth.changeSet.idpConfig.lines(),
16328
- ...auth.changeSet.userProfileConfig.lines(),
16329
- ...auth.changeSet.tenantConfig.lines(),
16330
- ...auth.changeSet.machineUser.lines(),
16331
- ...auth.changeSet.oauth2Client.lines(),
16332
- ...auth.changeSet.authHook.lines(),
16333
- ...auth.changeSet.scim.lines(),
16334
- ...auth.changeSet.scimResource.lines(),
16335
- ...auth.changeSet.connection.lines(),
16336
- ...secretManager.vaultChangeSet.lines(),
16337
- ...secretManager.secretChangeSet.lines()
16638
+ ...plans.functionRegistry.changeSet.lines(),
16639
+ ...plans.staticWebsite.changeSet.lines(),
16640
+ ...plans.aiGateway.changeSet.lines(),
16641
+ ...plans.app.lines(),
16642
+ ...plans.tailorDB.changeSet.service.lines(),
16643
+ ...plans.tailorDB.changeSet.type.lines(),
16644
+ ...plans.tailorDB.changeSet.gqlPermission.lines(),
16645
+ ...plans.pipeline.changeSet.service.lines(),
16646
+ ...plans.pipeline.changeSet.resolver.lines(),
16647
+ ...plans.executor.changeSet.lines(),
16648
+ ...plans.workflow.changeSet.lines(),
16649
+ ...plans.workflowExecutionPolicy.changeSet.lines(),
16650
+ ...plans.idp.changeSet.service.lines(),
16651
+ ...plans.idp.changeSet.client.lines(),
16652
+ ...plans.auth.changeSet.service.lines(),
16653
+ ...plans.auth.changeSet.idpConfig.lines(),
16654
+ ...plans.auth.changeSet.userProfileConfig.lines(),
16655
+ ...plans.auth.changeSet.tenantConfig.lines(),
16656
+ ...plans.auth.changeSet.machineUser.lines(),
16657
+ ...plans.auth.changeSet.oauth2Client.lines(),
16658
+ ...plans.auth.changeSet.authHook.lines(),
16659
+ ...plans.auth.changeSet.scim.lines(),
16660
+ ...plans.auth.changeSet.scimResource.lines(),
16661
+ ...plans.auth.changeSet.connection.lines(),
16662
+ ...plans.secretManager.vaultChangeSet.lines(),
16663
+ ...plans.secretManager.secretChangeSet.lines()
16338
16664
  ];
16339
16665
  if (removeLines.length > 0) logger.log(removeLines.join("\n"));
16340
- if (tailorDB.changeSet.service.deletes.length === 0 && staticWebsite.changeSet.deletes.length === 0 && aiGateway.changeSet.deletes.length === 0 && idp.changeSet.service.deletes.length === 0 && auth.changeSet.service.deletes.length === 0 && pipeline.changeSet.service.deletes.length === 0 && app.deletes.length === 0 && executor.changeSet.deletes.length === 0 && workflow.changeSet.deletes.length === 0 && functionRegistry.changeSet.deletes.length === 0 && secretManager.vaultChangeSet.deletes.length === 0 && secretManager.secretChangeSet.deletes.length === 0) return;
16666
+ if (plans.tailorDB.changeSet.service.deletes.length === 0 && plans.staticWebsite.changeSet.deletes.length === 0 && plans.aiGateway.changeSet.deletes.length === 0 && plans.idp.changeSet.service.deletes.length === 0 && plans.auth.changeSet.service.deletes.length === 0 && plans.pipeline.changeSet.service.deletes.length === 0 && plans.app.deletes.length === 0 && plans.executor.changeSet.deletes.length === 0 && plans.workflow.changeSet.deletes.length === 0 && plans.workflowExecutionPolicy.changeSet.deletes.length === 0 && plans.functionRegistry.changeSet.deletes.length === 0 && plans.secretManager.vaultChangeSet.deletes.length === 0 && plans.secretManager.secretChangeSet.deletes.length === 0) return;
16341
16667
  if (confirm) await confirm();
16342
- await applyWorkflow(client, workflow, "delete");
16343
- await applyExecutor(client, executor, "delete");
16344
- await applyStaticWebsite(client, staticWebsite, "delete");
16345
- await applyAIGateway(client, aiGateway, "delete");
16346
- await applyApplication(client, app, "delete");
16347
- await applyPipeline(client, pipeline, "delete-resources");
16348
- await applyPipeline(client, pipeline, "delete-services");
16349
- await applyAuth(client, auth, "delete-resources");
16350
- await applyAuth(client, auth, "delete-services");
16351
- await applyIdP(client, idp, "delete-resources");
16352
- await applyIdP(client, idp, "delete-services");
16353
- await applyTailorDB(client, tailorDB, "delete-resources");
16354
- await applyTailorDB(client, tailorDB, "delete-services");
16355
- await applyFunctionRegistry(client, workspaceId, functionRegistry, "delete");
16356
- await applySecretManager(client, secretManager, "delete");
16668
+ await applyWorkflow(client, plans.workflow, "delete");
16669
+ await applyWorkflowJobFunctionExecutionPolicy(client, plans.workflowExecutionPolicy, "delete");
16670
+ await applyExecutor(client, plans.executor, "delete");
16671
+ await applyStaticWebsite(client, plans.staticWebsite, "delete");
16672
+ await applyAIGateway(client, plans.aiGateway, "delete");
16673
+ await applyApplication(client, plans.app, "delete");
16674
+ await applyPipeline(client, plans.pipeline, "delete-resources");
16675
+ await applyPipeline(client, plans.pipeline, "delete-services");
16676
+ await applyAuth(client, plans.auth, "delete-resources");
16677
+ await applyAuth(client, plans.auth, "delete-services");
16678
+ await applyIdP(client, plans.idp, "delete-resources");
16679
+ await applyIdP(client, plans.idp, "delete-services");
16680
+ await applyTailorDB(client, plans.tailorDB, "delete-resources");
16681
+ await applyTailorDB(client, plans.tailorDB, "delete-services");
16682
+ await applyFunctionRegistry(client, workspaceId, plans.functionRegistry, "delete");
16683
+ await applySecretManager(client, plans.secretManager, "delete");
16357
16684
  }
16358
16685
  /**
16359
16686
  * Remove all resources managed by the current application.
@@ -16529,10 +16856,27 @@ function applicationInfo(app) {
16529
16856
  updatedAt: app.updateTime ? timestampDate(app.updateTime) : null
16530
16857
  };
16531
16858
  }
16859
+ async function fetchAIGateways(client, workspaceId, names) {
16860
+ return (await Promise.all(names.map(async (name) => {
16861
+ try {
16862
+ const { aigateway } = await client.getAIGateway({
16863
+ workspaceId,
16864
+ aigatewayName: name
16865
+ });
16866
+ return aigateway ? {
16867
+ name: aigateway.name,
16868
+ url: aigateway.url
16869
+ } : void 0;
16870
+ } catch (error) {
16871
+ if (error instanceof ConnectError && error.code === Code.NotFound) return;
16872
+ throw error;
16873
+ }
16874
+ }))).filter((gateway) => gateway !== void 0);
16875
+ }
16532
16876
  /**
16533
16877
  * Show applied application information for the current workspace.
16534
16878
  * @param options - Show options
16535
- * @returns Application information
16879
+ * @returns Deployed application, workspace, and AI Gateway information
16536
16880
  */
16537
16881
  async function show(options) {
16538
16882
  const client = await initOperatorClient(await loadAccessToken({ profile: options?.profile }));
@@ -16541,10 +16885,15 @@ async function show(options) {
16541
16885
  profile: options?.profile
16542
16886
  });
16543
16887
  const { config } = await loadConfig(options?.configPath);
16544
- const [workspaceResp, resp] = await Promise.all([client.getWorkspace({ workspaceId }), client.getApplication({
16545
- workspaceId,
16546
- applicationName: config.name
16547
- })]);
16888
+ const aiGatewayNames = config.aiGateways?.length ? [...new Set(config.aiGateways.map((gateway) => gateway.name))] : [];
16889
+ const [workspaceResp, resp, aiGateways] = await Promise.all([
16890
+ client.getWorkspace({ workspaceId }),
16891
+ client.getApplication({
16892
+ workspaceId,
16893
+ applicationName: config.name
16894
+ }),
16895
+ fetchAIGateways(client, workspaceId, aiGatewayNames)
16896
+ ]);
16548
16897
  const { name, ...appInfo } = applicationInfo(assertDefined(resp.application, `application "${config.name}" not found in workspace`));
16549
16898
  const workspace = workspaceResp.workspace;
16550
16899
  const workspaceFolderName = workspace ? await resolveWorkspaceFolderName(client, workspace) : "";
@@ -16554,7 +16903,8 @@ async function show(options) {
16554
16903
  workspaceName: workspace?.name ?? "",
16555
16904
  ...workspaceFolderName ? { workspaceFolderName } : {},
16556
16905
  workspaceRegion: workspace?.region ?? "",
16557
- ...appInfo
16906
+ ...appInfo,
16907
+ aiGateways
16558
16908
  };
16559
16909
  }
16560
16910
  const showWorkspaceNameTransformer = createWorkspaceNameTransformer("workspaceName", "workspaceFolderName");
@@ -17181,7 +17531,7 @@ async function generate(options) {
17181
17531
  if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
17182
17532
  let pluginManager;
17183
17533
  if (plugins.length > 0) pluginManager = new PluginManager(plugins);
17184
- const { defineApplication } = await import("./application-D2hSK1ZL.mjs");
17534
+ const { defineApplication } = await import("./application-CUkjzfij.mjs");
17185
17535
  const application = defineApplication({
17186
17536
  config,
17187
17537
  pluginManager
@@ -18869,7 +19219,8 @@ const queryBaseOptionsSchema = z.object({
18869
19219
  profile: z.string().optional(),
18870
19220
  configPath: z.string().optional(),
18871
19221
  engine: queryEngineSchema,
18872
- machineUser: z.string().optional()
19222
+ machineUser: z.string().optional(),
19223
+ machineUserSource: z.enum(["option", "env"]).optional()
18873
19224
  });
18874
19225
  const queryOptionsSchema = queryBaseOptionsSchema.extend({ query: z.string() });
18875
19226
  async function getNamespaceFromSqlQuery(workspaceId, query, client, namespaces) {
@@ -18894,6 +19245,7 @@ async function loadOptions(options) {
18894
19245
  if (!result.success) throw new Error(assertDefined(result.error.issues[0], "validation error missing issues").message);
18895
19246
  const machineUser = await loadMachineUserName({
18896
19247
  machineUser: result.data.machineUser,
19248
+ machineUserSource: result.data.machineUserSource,
18897
19249
  profile: result.data.profile
18898
19250
  });
18899
19251
  if (!machineUser) throw new Error("Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.");
@@ -19313,7 +19665,8 @@ const queryCommand = defineAppCommand({
19313
19665
  profile: args.profile,
19314
19666
  configPath: args.config,
19315
19667
  engine: args.engine,
19316
- machineUser: args["machine-user"]
19668
+ machineUser: args["machine-user"],
19669
+ machineUserSource: resolveMachineUserInputSource(args["machine-user"])
19317
19670
  };
19318
19671
  if (mode.mode === "abort") {
19319
19672
  logger.info("Editor closed without a query. Nothing was executed.");
@@ -19456,5 +19809,5 @@ async function registerTsHook(tsHookUrl) {
19456
19809
  }
19457
19810
 
19458
19811
  //#endregion
19459
- export { getOrganization as $, compareSnapshotWithRemote as $t, listCommand$3 as A, apiCommand as An, getExecutorWaitFailureMessage as At, show as B, pagedLogArgs as Bn, listWorkflowExecutions as Bt, listCommand$2 as C, hasChanges as Cn, listWebhookExecutors as Ct, waitWorkflowExecution as D, PluginManager as Dn, listCommand$9 as Dt, waitCommand as E, sdkNameLabelKey as En, triggerExecutor as Et, generateCommand as F, configArg as Fn, startWorkflow as Ft, removeCommand$1 as G, deploy as Gt, extractOwnedNamespaces as H, toPageDirection as Hn, formatKeyValueTable as Ht, generateMigrationScript as I, confirmationArgs as In, getCommand$5 as It, organizationTree as J, waitForExecution as Jt, updateCommand$1 as K, ensureConfigId as Kt, writeDbTypesFile as L, deploymentArgs as Ln, getWorkflow as Lt, truncate as M, assertWritable as Mn, listExecutorJobs as Mt, truncateCommand as N, defineAppCommand as Nn, watchExecutorJob as Nt, resumeCommand as O, generateUserTypes as On, listExecutors as Ot, generate as P, commonArgs as Pn, startCommand as Pt, getCommand$1 as Q, parseMigrationLabelNumber as Qt, getConfiguredEditorCommand as R, isVerbose as Rn, executionsCommand as Rt, listApps as S, formatMigrationDiff as Sn, getFunctionRegistry as St, healthCommand as T, resourceTrn as Tn, triggerCommand as Tt, logBetaWarning as U, workspaceArgs as Un, getCommand$6 as Ut, showCommand as V, paginationArgs as Vn, functionExecutionStatusToString as Vt, remove as W, getExecutor as Wt, listCommand$4 as X, MIGRATION_LABEL_KEY as Xt, treeCommand as Y, bundleMigrationScript as Yt, listOrganizations as Z, handleOptionalToRequiredError as Zt, getWorkspace as _, loadDiff as _n, listMachineUsers as _t, updateUser as a, MIGRATE_FILE_NAME as an, getFolder as at, createCommand as b, parseMigrationNumberArg as bn, listFunctionRegistries as bt, listCommand as c, compareLocalTypesWithSnapshot as cn, createCommand$1 as ct, inviteUser as d, getLatestMigrationNumber as dn, listOAuth2Clients as dt, generateAllTypeManifestsFromSnapshot as en, updateCommand$2 as et, restoreCommand as f, getMigrationDirPath as fn, getCommand$3 as ft, getCommand as g, isValidMigrationNumber as gn, listCommand$7 as gt, listWorkspaces as h, getNextMigrationNumber as hn, tokenCommand as ht, updateCommand as i, INITIAL_SCHEMA_NUMBER as in, getCommand$2 as it, listWorkflows as j, apiCall as jn, jobsCommand as jt, resumeWorkflow as k, prompt as kn, getExecutorJob as kt, listUsers as l, compareSnapshots as ln, createFolder as lt, listCommand$1 as m, getMigrationFiles as mn, getMachineUserToken as mt, query as n, DB_TYPES_FILE_NAME as nn, listCommand$5 as nt, removeCommand as o, SCHEMA_FILE_NAME as on, deleteCommand$1 as ot, restoreWorkspace as p, getMigrationFilePath as pn, getOAuth2Client as pt, updateOrganization as q, executeScript as qt, queryCommand as r, DIFF_FILE_NAME as rn, listFolders as rt, removeUser as s, assertValidMigrationFiles as sn, deleteFolder as st, registerTsHook as t, protoGqlPermission as tn, updateFolder as tt, inviteCommand as u, createSnapshotFromLocalTypes as un, listCommand$6 as ut, deleteCommand as v, reconstructSnapshotFromMigrations as vn, generate$1 as vt, getAppHealth as w, getNamespacesWithMigrations as wn, webhookCommand as wt, createWorkspace as x, formatDiffSummary as xn, getCommand$4 as xt, deleteWorkspace as y, formatMigrationNumber as yn, listCommand$8 as yt, openInConfiguredEditor as z, multiConfigArg as zn, getWorkflowExecution as zt };
19460
- //# sourceMappingURL=register-ts-hook-ZpBacA07.mjs.map
19812
+ export { getOrganization as $, compareSnapshotWithRemote as $t, listCommand$3 as A, apiCommand as An, getExecutorWaitFailureMessage as At, show as B, listWorkflowExecutions as Bt, listCommand$2 as C, hasChanges as Cn, listWebhookExecutors as Ct, waitWorkflowExecution as D, PluginManager as Dn, listCommand$9 as Dt, waitCommand as E, sdkNameLabelKey as En, triggerExecutor as Et, generateCommand as F, startWorkflow as Ft, removeCommand$1 as G, deploy as Gt, extractOwnedNamespaces as H, formatKeyValueTable as Ht, generateMigrationScript as I, getCommand$5 as It, organizationTree as J, waitForExecution as Jt, updateCommand$1 as K, ensureConfigId as Kt, writeDbTypesFile as L, getWorkflow as Lt, truncate as M, assertWritable as Mn, listExecutorJobs as Mt, truncateCommand as N, defineAppCommand as Nn, watchExecutorJob as Nt, resumeCommand as O, generateUserTypes as On, listExecutors as Ot, generate as P, startCommand as Pt, getCommand$1 as Q, parseMigrationLabelNumber as Qt, getConfiguredEditorCommand as R, executionsCommand as Rt, listApps as S, formatMigrationDiff as Sn, getFunctionRegistry as St, healthCommand as T, resourceTrn as Tn, triggerCommand as Tt, logBetaWarning as U, getCommand$6 as Ut, showCommand as V, functionExecutionStatusToString as Vt, remove as W, getExecutor as Wt, listCommand$4 as X, MIGRATION_LABEL_KEY as Xt, treeCommand as Y, bundleMigrationScript as Yt, listOrganizations as Z, handleOptionalToRequiredError as Zt, getWorkspace as _, loadDiff as _n, listMachineUsers as _t, updateUser as a, MIGRATE_FILE_NAME as an, getFolder as at, createCommand as b, parseMigrationNumberArg as bn, listFunctionRegistries as bt, listCommand as c, compareLocalTypesWithSnapshot as cn, createCommand$1 as ct, inviteUser as d, getLatestMigrationNumber as dn, listOAuth2Clients as dt, generateAllTypeManifestsFromSnapshot as en, updateCommand$2 as et, restoreCommand as f, getMigrationDirPath as fn, getCommand$3 as ft, getCommand as g, isValidMigrationNumber as gn, listCommand$7 as gt, listWorkspaces as h, getNextMigrationNumber as hn, tokenCommand as ht, updateCommand as i, INITIAL_SCHEMA_NUMBER as in, getCommand$2 as it, listWorkflows as j, apiCall as jn, jobsCommand as jt, resumeWorkflow as k, prompt as kn, getExecutorJob as kt, listUsers as l, compareSnapshots as ln, createFolder as lt, listCommand$1 as m, getMigrationFiles as mn, getMachineUserToken as mt, query as n, DB_TYPES_FILE_NAME as nn, listCommand$5 as nt, removeCommand as o, SCHEMA_FILE_NAME as on, deleteCommand$1 as ot, restoreWorkspace as p, getMigrationFilePath as pn, getOAuth2Client as pt, updateOrganization as q, executeScript as qt, queryCommand as r, DIFF_FILE_NAME as rn, listFolders as rt, removeUser as s, assertValidMigrationFiles as sn, deleteFolder as st, registerTsHook as t, protoGqlPermission as tn, updateFolder as tt, inviteCommand as u, createSnapshotFromLocalTypes as un, listCommand$6 as ut, deleteCommand as v, reconstructSnapshotFromMigrations as vn, generate$1 as vt, getAppHealth as w, getNamespacesWithMigrations as wn, webhookCommand as wt, createWorkspace as x, formatDiffSummary as xn, getCommand$4 as xt, deleteWorkspace as y, formatMigrationNumber as yn, listCommand$8 as yt, openInConfiguredEditor as z, getWorkflowExecution as zt };
19813
+ //# sourceMappingURL=register-ts-hook-BhzVkej0.mjs.map