@tailor-platform/sdk 1.76.1 → 1.76.2

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 (273) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/application-6zsDLGKv.mjs +3 -0
  3. package/dist/{application-BUfYmf0O.mjs → application-CqjCcZ2n.mjs} +372 -1673
  4. package/dist/application-CqjCcZ2n.mjs.map +1 -0
  5. package/dist/cli/cache/bundle-cache.d.mts +2 -1
  6. package/dist/cli/cache/store.d.mts +1 -1
  7. package/dist/cli/commands/api/index.d.mts +1 -0
  8. package/dist/cli/commands/deploy/aigateway.d.mts +5 -1
  9. package/dist/cli/commands/deploy/application.d.mts +7 -1
  10. package/dist/cli/commands/deploy/apply-phases.d.mts +14 -1
  11. package/dist/cli/commands/deploy/auth.d.mts +5 -1
  12. package/dist/cli/commands/deploy/deploy.d.mts +5 -0
  13. package/dist/cli/commands/deploy/executor.d.mts +7 -1
  14. package/dist/cli/commands/deploy/function-registry.d.mts +5 -0
  15. package/dist/cli/commands/deploy/idp.d.mts +5 -1
  16. package/dist/cli/commands/deploy/resolver.d.mts +5 -1
  17. package/dist/cli/commands/deploy/secret-manager.d.mts +5 -1
  18. package/dist/cli/commands/deploy/staticwebsite.d.mts +5 -1
  19. package/dist/cli/commands/deploy/tailordb/index.d.mts +8 -1
  20. package/dist/cli/commands/deploy/types.d.mts +3 -1
  21. package/dist/cli/commands/deploy/workflow-execution-policy.d.mts +3 -1
  22. package/dist/cli/commands/deploy/workflow.d.mts +4 -1
  23. package/dist/cli/commands/executor/get.d.mts +0 -1
  24. package/dist/cli/commands/executor/jobs.d.mts +0 -1
  25. package/dist/cli/commands/executor/list.d.mts +0 -1
  26. package/dist/cli/commands/executor/transform.d.mts +1 -0
  27. package/dist/cli/commands/executor/trigger.d.mts +0 -1
  28. package/dist/cli/commands/executor/webhook.d.mts +0 -1
  29. package/dist/cli/commands/function/get.d.mts +0 -1
  30. package/dist/cli/commands/function/list.d.mts +0 -1
  31. package/dist/cli/commands/function/transform.d.mts +1 -0
  32. package/dist/cli/commands/generate/service.d.mts +5 -1
  33. package/dist/cli/commands/generate/types.d.mts +3 -1
  34. package/dist/cli/commands/machineuser/list.d.mts +0 -1
  35. package/dist/cli/commands/machineuser/token.d.mts +0 -1
  36. package/dist/cli/commands/oauth2client/get.d.mts +0 -1
  37. package/dist/cli/commands/oauth2client/list.d.mts +0 -1
  38. package/dist/cli/commands/oauth2client/transform.d.mts +1 -0
  39. package/dist/cli/commands/organization/folder/create.d.mts +0 -1
  40. package/dist/cli/commands/organization/folder/delete.d.mts +0 -1
  41. package/dist/cli/commands/organization/folder/get.d.mts +0 -1
  42. package/dist/cli/commands/organization/folder/list.d.mts +0 -1
  43. package/dist/cli/commands/organization/folder/update.d.mts +0 -1
  44. package/dist/cli/commands/organization/get.d.mts +0 -1
  45. package/dist/cli/commands/organization/list.d.mts +0 -1
  46. package/dist/cli/commands/organization/transform.d.mts +2 -0
  47. package/dist/cli/commands/organization/tree.d.mts +0 -1
  48. package/dist/cli/commands/organization/update.d.mts +0 -1
  49. package/dist/cli/commands/remove.d.mts +0 -1
  50. package/dist/cli/commands/show.d.mts +0 -1
  51. package/dist/cli/commands/tailordb/migrate/config.d.mts +0 -1
  52. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +0 -1
  53. package/dist/cli/commands/tailordb/migrate/generate.d.mts +0 -1
  54. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +1 -1
  55. package/dist/cli/commands/tailordb/truncate.d.mts +0 -1
  56. package/dist/cli/commands/workflow/executions.d.mts +0 -1
  57. package/dist/cli/commands/workflow/get.d.mts +2 -1
  58. package/dist/cli/commands/workflow/list.d.mts +0 -1
  59. package/dist/cli/commands/workflow/resume.d.mts +0 -1
  60. package/dist/cli/commands/workflow/start.d.mts +0 -1
  61. package/dist/cli/commands/workflow/status.d.mts +1 -0
  62. package/dist/cli/commands/workflow/transform.d.mts +1 -0
  63. package/dist/cli/commands/workflow/wait.d.mts +0 -1
  64. package/dist/cli/commands/workflow/waiter.d.mts +1 -1
  65. package/dist/cli/commands/workspace/app/health.d.mts +0 -1
  66. package/dist/cli/commands/workspace/app/list.d.mts +0 -1
  67. package/dist/cli/commands/workspace/app/transform.d.mts +2 -0
  68. package/dist/cli/commands/workspace/create.d.mts +0 -1
  69. package/dist/cli/commands/workspace/delete.d.mts +0 -1
  70. package/dist/cli/commands/workspace/get.d.mts +0 -1
  71. package/dist/cli/commands/workspace/list.d.mts +0 -1
  72. package/dist/cli/commands/workspace/restore.d.mts +0 -1
  73. package/dist/cli/commands/workspace/transform.d.mts +2 -0
  74. package/dist/cli/commands/workspace/user/invite.d.mts +0 -1
  75. package/dist/cli/commands/workspace/user/list.d.mts +0 -1
  76. package/dist/cli/commands/workspace/user/remove.d.mts +0 -1
  77. package/dist/cli/commands/workspace/user/transform.d.mts +1 -0
  78. package/dist/cli/commands/workspace/user/update.d.mts +0 -1
  79. package/dist/cli/index.d.mts +3 -1
  80. package/dist/cli/index.mjs +599 -42
  81. package/dist/cli/index.mjs.map +1 -1
  82. package/dist/cli/lib.d.mts +2 -0
  83. package/dist/cli/lib.mjs +3 -3
  84. package/dist/cli/query/index.d.mts +0 -1
  85. package/dist/cli/services/application.d.mts +12 -1
  86. package/dist/cli/services/auth/service.d.mts +2 -0
  87. package/dist/cli/services/executor/service.d.mts +1 -1
  88. package/dist/cli/services/http-adapter/bundler.d.mts +3 -1
  89. package/dist/cli/services/http-adapter/service.d.mts +2 -1
  90. package/dist/cli/services/resolver/service.d.mts +1 -1
  91. package/dist/cli/services/tailordb/service.d.mts +3 -1
  92. package/dist/cli/services/workflow/bundler.d.mts +2 -1
  93. package/dist/cli/services/workflow/service.d.mts +1 -1
  94. package/dist/cli/shared/args.d.mts +1 -1
  95. package/dist/cli/shared/client.d.mts +1 -1
  96. package/dist/cli/shared/config-loader.d.mts +0 -1
  97. package/dist/cli/shared/context.d.mts +2 -1
  98. package/dist/cli/shared/script-executor.d.mts +0 -1
  99. package/dist/cli/shared/seed-chunker.d.mts +7 -3
  100. package/dist/cli/shared/type-generator.d.mts +0 -1
  101. package/dist/completion/zsh-worker.zsh +1 -1
  102. package/dist/configure/config/index.d.mts +0 -1
  103. package/dist/configure/config/types.d.mts +2 -2
  104. package/dist/configure/index.d.mts +2 -1
  105. package/dist/configure/index.mjs +54 -4
  106. package/dist/configure/index.mjs.map +1 -1
  107. package/dist/configure/services/aigateway/index.d.mts +0 -1
  108. package/dist/configure/services/aigateway/types.d.mts +0 -1
  109. package/dist/configure/services/auth/index.d.mts +0 -1
  110. package/dist/configure/services/auth/types.d.mts +14 -13
  111. package/dist/configure/services/executor/executor.d.mts +0 -1
  112. package/dist/configure/services/executor/index.d.mts +1 -0
  113. package/dist/configure/services/executor/operation.d.mts +1 -2
  114. package/dist/configure/services/executor/trigger/event.d.mts +0 -1
  115. package/dist/configure/services/executor/trigger/index.d.mts +0 -1
  116. package/dist/configure/services/executor/trigger/schedule.d.mts +0 -1
  117. package/dist/configure/services/executor/trigger/webhook.d.mts +0 -1
  118. package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -2
  119. package/dist/configure/services/idp/index.d.mts +0 -1
  120. package/dist/configure/services/idp/permission.d.mts +4 -5
  121. package/dist/configure/services/idp/types.d.mts +0 -1
  122. package/dist/configure/services/index.d.mts +5 -0
  123. package/dist/configure/services/resolver/resolver.d.mts +0 -1
  124. package/dist/configure/services/resolver/types.d.mts +0 -1
  125. package/dist/configure/services/secrets/index.d.mts +0 -1
  126. package/dist/configure/services/secrets/types.d.mts +0 -1
  127. package/dist/configure/services/staticwebsite/index.d.mts +0 -1
  128. package/dist/configure/services/staticwebsite/types.d.mts +0 -1
  129. package/dist/configure/services/tailordb/permission.d.mts +4 -5
  130. package/dist/configure/services/tailordb/schema.d.mts +21 -8
  131. package/dist/configure/services/tailordb/types.d.mts +4 -5
  132. package/dist/configure/services/workflow/execution-policy.d.mts +0 -1
  133. package/dist/configure/services/workflow/execution-policy.types.d.mts +0 -1
  134. package/dist/configure/services/workflow/index.d.mts +1 -0
  135. package/dist/configure/services/workflow/job.d.mts +0 -1
  136. package/dist/configure/services/workflow/wait-point.d.mts +0 -1
  137. package/dist/configure/services/workflow/workflow.d.mts +0 -1
  138. package/dist/configure/types/field-runtime.d.mts +1 -1
  139. package/dist/configure/types/field.d.mts +1 -2
  140. package/dist/configure/types/field.types.d.mts +1 -2
  141. package/dist/configure/types/type.d.mts +1 -1
  142. package/dist/configure/user.d.mts +0 -1
  143. package/dist/{crashreport-ayWANEZ6.mjs → crashreport-DZDr-TvH.mjs} +3 -2
  144. package/dist/{crashreport-ayWANEZ6.mjs.map → crashreport-DZDr-TvH.mjs.map} +1 -1
  145. package/dist/{crashreport-Dy4ZzSkd.mjs → crashreport-np4-_DX2.mjs} +1 -1
  146. package/dist/{field-runtime-9bfXBAOK.mjs → field-runtime-D4QWRiB1.mjs} +66 -46
  147. package/dist/field-runtime-D4QWRiB1.mjs.map +1 -0
  148. package/dist/{globals-CcU1ONiK.mjs → globals-z6zYMjlr.mjs} +2 -2
  149. package/dist/{globals-CcU1ONiK.mjs.map → globals-z6zYMjlr.mjs.map} +1 -1
  150. package/dist/kysely/index.d.mts +3 -4
  151. package/dist/parser/service/auth/index.d.mts +1 -1
  152. package/dist/parser/service/auth/schema.d.mts +1 -0
  153. package/dist/parser/service/http-adapter/index.d.mts +1 -1
  154. package/dist/parser/service/idp/types.d.mts +1 -0
  155. package/dist/parser/service/tailordb/types.d.mts +0 -1
  156. package/dist/plugin/builtin/enum-constants/index.d.mts +0 -1
  157. package/dist/plugin/builtin/file-utils/index.d.mts +0 -1
  158. package/dist/plugin/builtin/kysely-type/index.d.mts +0 -1
  159. package/dist/plugin/builtin/seed/index.d.mts +0 -1
  160. package/dist/plugin/builtin/seed/index.mjs +1 -1
  161. package/dist/plugin/get-generated-type.d.mts +0 -1
  162. package/dist/plugin/manager.d.mts +3 -1
  163. package/dist/plugin/types.d.mts +0 -1
  164. package/dist/plugin/with-context.d.mts +0 -1
  165. package/dist/{registry-NfSW0BRo.mjs → registry-CTgoVWc_.mjs} +4 -49
  166. package/dist/registry-CTgoVWc_.mjs.map +1 -0
  167. package/dist/runtime/aigateway.d.mts +0 -2
  168. package/dist/runtime/authconnection.d.mts +0 -2
  169. package/dist/runtime/globals.d.mts +0 -1
  170. package/dist/runtime/index.d.mts +0 -1
  171. package/dist/runtime/types.d.mts +16 -7
  172. package/dist/{runtime-_vUgjiqT.mjs → runtime-DlklyuHN.mjs} +1301 -716
  173. package/dist/runtime-DlklyuHN.mjs.map +1 -0
  174. package/dist/{schema-DrVyN-LP.mjs → schema-DbTR1c6M.mjs} +3 -2
  175. package/dist/schema-DbTR1c6M.mjs.map +1 -0
  176. package/dist/{secret-file-VSVGy1V0.mjs → secret-file-DBqZhjFQ.mjs} +2 -27
  177. package/dist/{secret-file-VSVGy1V0.mjs.map → secret-file-DBqZhjFQ.mjs.map} +1 -1
  178. package/dist/seed/index.d.mts +3 -2
  179. package/dist/{seed-fm0LeYP2.mjs → seed-DFFigL8V.mjs} +3 -13
  180. package/dist/seed-DFFigL8V.mjs.map +1 -0
  181. package/dist/service_pb-BoLM0X4K.mjs +167 -0
  182. package/dist/service_pb-BoLM0X4K.mjs.map +1 -0
  183. package/dist/{service_pb-B2FF59sP.mjs → service_pb-r1T7kpJc.mjs} +1 -1
  184. package/dist/tailor-proto/src/tailor/v1/aigateway_pb.d.mts +0 -1
  185. package/dist/tailor-proto/src/tailor/v1/aigateway_resource_pb.d.mts +0 -1
  186. package/dist/tailor-proto/src/tailor/v1/application_pb.d.mts +0 -1
  187. package/dist/tailor-proto/src/tailor/v1/application_resource_pb.d.mts +0 -1
  188. package/dist/tailor-proto/src/tailor/v1/auth_pb.d.mts +0 -1
  189. package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +0 -1
  190. package/dist/tailor-proto/src/tailor/v1/events_pb.d.mts +0 -1
  191. package/dist/tailor-proto/src/tailor/v1/events_resource_pb.d.mts +0 -1
  192. package/dist/tailor-proto/src/tailor/v1/executor_pb.d.mts +0 -1
  193. package/dist/tailor-proto/src/tailor/v1/executor_resource_pb.d.mts +0 -1
  194. package/dist/tailor-proto/src/tailor/v1/function_pb.d.mts +0 -1
  195. package/dist/tailor-proto/src/tailor/v1/function_registry_pb.d.mts +0 -1
  196. package/dist/tailor-proto/src/tailor/v1/function_resource_pb.d.mts +0 -1
  197. package/dist/tailor-proto/src/tailor/v1/http_adapter_resource_pb.d.mts +0 -1
  198. package/dist/tailor-proto/src/tailor/v1/idp_pb.d.mts +0 -1
  199. package/dist/tailor-proto/src/tailor/v1/idp_resource_pb.d.mts +0 -1
  200. package/dist/tailor-proto/src/tailor/v1/metadata_pb.d.mts +0 -1
  201. package/dist/tailor-proto/src/tailor/v1/metadata_resource_pb.d.mts +0 -1
  202. package/dist/tailor-proto/src/tailor/v1/meter_pb.d.mts +0 -1
  203. package/dist/tailor-proto/src/tailor/v1/pipeline_pb.d.mts +0 -1
  204. package/dist/tailor-proto/src/tailor/v1/pipeline_resource_pb.d.mts +0 -1
  205. package/dist/tailor-proto/src/tailor/v1/resource_pb.d.mts +0 -1
  206. package/dist/tailor-proto/src/tailor/v1/secret_manager_pb.d.mts +0 -1
  207. package/dist/tailor-proto/src/tailor/v1/secret_manager_resource_pb.d.mts +0 -1
  208. package/dist/tailor-proto/src/tailor/v1/service_pb.d.mts +0 -1
  209. package/dist/tailor-proto/src/tailor/v1/stateflow_pb.d.mts +0 -1
  210. package/dist/tailor-proto/src/tailor/v1/stateflow_resource_pb.d.mts +0 -1
  211. package/dist/tailor-proto/src/tailor/v1/staticwebsite_pb.d.mts +0 -1
  212. package/dist/tailor-proto/src/tailor/v1/staticwebsite_resource_pb.d.mts +0 -1
  213. package/dist/tailor-proto/src/tailor/v1/tailordb_pb.d.mts +0 -1
  214. package/dist/tailor-proto/src/tailor/v1/tailordb_resource_pb.d.mts +0 -1
  215. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_pb.d.mts +0 -1
  216. package/dist/tailor-proto/src/tailor/v1/telemetryrouter_resource_pb.d.mts +0 -1
  217. package/dist/tailor-proto/src/tailor/v1/workflow_pb.d.mts +0 -1
  218. package/dist/tailor-proto/src/tailor/v1/workflow_resource_pb.d.mts +0 -1
  219. package/dist/tailor-proto/src/tailor/v1/workspace_pb.d.mts +0 -1
  220. package/dist/tailor-proto/src/tailor/v1/workspace_resource_pb.d.mts +0 -1
  221. package/dist/test-env-key-IPapa1KJ.mjs +49 -0
  222. package/dist/test-env-key-IPapa1KJ.mjs.map +1 -0
  223. package/dist/type-source-DH_LH20p.mjs +13 -0
  224. package/dist/type-source-DH_LH20p.mjs.map +1 -0
  225. package/dist/types/aigateway.generated.d.mts +5 -2
  226. package/dist/types/auth-connection.generated.d.mts +11 -5
  227. package/dist/types/auth.generated.d.mts +111 -51
  228. package/dist/types/executor.generated.d.mts +59 -27
  229. package/dist/types/helpers.d.mts +5 -5
  230. package/dist/types/http-adapter.generated.d.mts +11 -5
  231. package/dist/types/idp.generated.d.mts +20 -9
  232. package/dist/types/resolver.generated.d.mts +19 -9
  233. package/dist/types/staticwebsite.generated.d.mts +7 -3
  234. package/dist/types/tailordb.generated.d.mts +47 -22
  235. package/dist/types/workflow.generated.d.mts +9 -4
  236. package/dist/{types-BwzB2okW.mjs → types-BzJ7A_fn.mjs} +2 -2
  237. package/dist/{types-BwzB2okW.mjs.map → types-BzJ7A_fn.mjs.map} +1 -1
  238. package/dist/types-CG9H7HuE.mjs +4 -0
  239. package/dist/user-agent-DX2Jnw0-.mjs +28 -0
  240. package/dist/user-agent-DX2Jnw0-.mjs.map +1 -0
  241. package/dist/utils/test/index.d.mts +0 -1
  242. package/dist/utils/test/index.mjs +1 -1
  243. package/dist/utils/test/mock.d.mts +0 -1
  244. package/dist/vitest/environment.mjs +1 -1
  245. package/dist/vitest/index.d.mts +1 -1
  246. package/dist/vitest/index.mjs +2 -1
  247. package/dist/vitest/index.mjs.map +1 -1
  248. package/dist/vitest/mock-kysely.d.mts +0 -1
  249. package/dist/vitest/mocks/aigateway.d.mts +2 -2
  250. package/dist/vitest/mocks/authconnection.d.mts +2 -2
  251. package/dist/vitest/mocks/idp.d.mts +2 -2
  252. package/dist/vitest/mocks/secretmanager.d.mts +3 -1
  253. package/dist/vitest/mocks/tailordb.d.mts +6 -3
  254. package/dist/vitest/mocks/workflow.d.mts +11 -6
  255. package/dist/vitest/setup.mjs +1 -1
  256. package/dist/{service_pb-B5w9rjPY.mjs → workspace_resource_pb-Db3fv68L.mjs} +57 -165
  257. package/dist/workspace_resource_pb-Db3fv68L.mjs.map +1 -0
  258. package/docs/services/tailordb.md +10 -1
  259. package/package.json +11 -11
  260. package/dist/application-BUfYmf0O.mjs.map +0 -1
  261. package/dist/application-DbvD5UUz.mjs +0 -3
  262. package/dist/cli/shared/trigger-context.d.mts +0 -1
  263. package/dist/field-runtime-9bfXBAOK.mjs.map +0 -1
  264. package/dist/job-D-PbD1P3.mjs +0 -55
  265. package/dist/job-D-PbD1P3.mjs.map +0 -1
  266. package/dist/registry-NfSW0BRo.mjs.map +0 -1
  267. package/dist/resource_pb-BRv7AMXK.mjs +0 -49
  268. package/dist/resource_pb-BRv7AMXK.mjs.map +0 -1
  269. package/dist/runtime-_vUgjiqT.mjs.map +0 -1
  270. package/dist/schema-DrVyN-LP.mjs.map +0 -1
  271. package/dist/seed-fm0LeYP2.mjs.map +0 -1
  272. package/dist/service_pb-B5w9rjPY.mjs.map +0 -1
  273. package/dist/types-KlawuVKa.mjs +0 -4
@@ -1,27 +1,35 @@
1
- import { t as db } from "./schema-DrVyN-LP.mjs";
2
- import { i as PageDirection, n as Condition_Operator, r as FilterSchema, t as ConditionSchema } from "./resource_pb-BRv7AMXK.mjs";
1
+ import { t as db } from "./schema-DbTR1c6M.mjs";
2
+ import { $ as CreateAuthIDPConfigRequestSchema, A as CreatePipelineResolverRequestSchema, At as TenantProviderConfig_TenantProviderType, B as IdPPermissionOperator, Bt as CreateAIGatewayRequestSchema, C as UpdateStaticWebsiteRequestSchema, Ct as AuthOAuth2Client_ClientType, D as CreateSecretManagerVaultRequestSchema, Dt as AuthSCIMAttribute_Uniqueness, E as CreateSecretManagerSecretRequestSchema, Et as AuthSCIMAttribute_Type, F as PipelineResolver_OperationType, Ft as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, G as CreateExecutorExecutorRequestSchema, Gt as ConditionSchema, H as FunctionExecution_Status, I as CreateIdPServiceRequestSchema, It as UpdateApplicationRequestSchema, J as ExecutorJobStatus, Jt as PageDirection, K as UpdateExecutorExecutorRequestSchema, Kt as Condition_Operator, L as UpdateIdPServiceRequestSchema, M as UpdatePipelineResolverRequestSchema, N as UpdatePipelineServiceRequestSchema, O as UpdateSecretManagerSecretRequestSchema, Ot as AuthSCIMConfig_AuthorizationType, Pt as CreateApplicationRequestSchema, Q as CreateAuthHookRequestSchema, Rt as ApplicationSchemaUpdateAttemptStatus, S as CreateStaticWebsiteRequestSchema, St as AuthInvokerSchema, Tt as AuthSCIMAttribute_Mutability, V as IdPPermissionPermit, Vt as UpdateAIGatewayRequestSchema, X as ExecutorTriggerType, Y as ExecutorTargetType, Z as CreateAuthConnectionRequestSchema, _ as TailorDBGQLPermission_Permit, a as CreateWorkflowRequestSchema, at as CreateTenantConfigRequestSchema, b as TailorDBType_PermitAction, bt as AuthHookPoint, ct as UpdateAuthHookRequestSchema, d as CreateTailorDBServiceRequestSchema, dt as UpdateAuthOAuth2ClientRequestSchema, et as CreateAuthMachineUserRequestSchema, f as CreateTailorDBTypeRequestSchema, ft as UpdateAuthSCIMConfigRequestSchema, g as TailorDBGQLPermission_Operator, gt as UpdateUserProfileConfigRequestSchema, h as TailorDBGQLPermission_Action, ht as UpdateTenantConfigRequestSchema, i as CreateWorkflowJobFunctionRequestSchema, it as CreateAuthServiceRequestSchema, j as CreatePipelineServiceRequestSchema, jt as UserProfileProviderConfig_UserProfileProviderType, l as WorkflowExecution_Status, lt as UpdateAuthIDPConfigRequestSchema, mt as UpdateAuthServiceRequestSchema, nt as CreateAuthSCIMConfigRequestSchema, o as UpdateWorkflowJobFunctionExecutionPolicyRequestSchema, ot as CreateUserProfileConfigRequestSchema, p as UpdateTailorDBTypeRequestSchema, pt as UpdateAuthSCIMResourceRequestSchema, qt as FilterSchema, r as CreateWorkflowJobFunctionExecutionPolicyRequestSchema, rt as CreateAuthSCIMResourceRequestSchema, s as UpdateWorkflowRequestSchema, st as UpdateAuthConnectionRequestSchema, t as WorkspacePlatformUserRole, tt as CreateAuthOAuth2ClientRequestSchema, u as WorkflowJobExecution_Status, ut as UpdateAuthMachineUserRequestSchema, v as TailorDBType_Permission_Operator, vt as AuthConnection_Status, wt as AuthOAuth2Client_GrantType, x as AddCustomDomainRequestSchema, xt as AuthIDPConfig_AuthType, y as TailorDBType_Permission_Permit, yt as AuthConnection_Type, z as IdPLang, zt as Subgraph_ServiceType } from "./workspace_resource_pb-Db3fv68L.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 getOAuth2ClientId, B as readPlatformConfig, C as createBundleCache, Ct as toPageDirection, D as loadConfig, E as hashFile, F as loadMachineUserName, I as loadPlatformClientConfig, J as fetchMachineUserToken, K as fetchAll, M as loadAccessToken, N as loadConfigPath, Q as getConsoleBaseUrl, R as loadWorkspaceId, S as hasGenerationHooks, St as resolveMachineUserInputSource, T as hashContent, U as writePlatformConfig, Y as fetchPaged, _ as platformBundleDefinePlugin, _t as organizationArgs, at as resolveStaticWebsiteUrls, bt as parseDuration, ct as configArg, d as buildExecutorArgsExpr, dt as durationArg, et as getOrNull, f as buildResolverOperationHookExpr, ft as folderArgs, g as stringifyFunction, gt as orderArg, h as TailorDBTypeSchema, ht as nonNegativeIntArg, i as resolverBundleKey, it as isDefaultPlatform, j as hasUserTokenEntry, l as HTTP_METHODS, lt as confirmationArgs, m as assertUniqueTailorDBTypeNamesWithExternal, n as generatePluginFilesIfNeeded, o as WorkflowJobFunctionExecutionPolicySchema, ot as byName, p as assertUniqueLocalTailorDBTypeNames, q as fetchAllTolerant, r as loadApplication, rt as initOperatorClient, t as defineApplication, tt as getPlatformBaseUrl, ut as deploymentArgs, vt as pagedLogArgs, w as getDistDir, wt as workspaceArgs, x as getPluginGenerationDependencies, xt as positiveIntArg, yt as paginationArgs, z as platformConfigFromProfile } from "./application-BUfYmf0O.mjs";
6
- import { o as loadFilesWithIgnores, t as createExecutorService } from "./service-BCRJ-3NV.mjs";
5
+ import { A as fetchAllTolerant, B as initOperatorClient, C as createBundleCache, E as hashFile, F as getConsoleBaseUrl, G as byName, H as normalizeBaseUrl, I as getOAuth2ClientId, K as LOG_LEVELS, L as getOrNull, M as fetchPaged, O as defaultPlatformBaseUrl, R as getPlatformBaseUrl, S as hasGenerationHooks, T as hashContent, U as rememberPlatformConfigForToken, V as isDefaultPlatform, W as resolveStaticWebsiteUrls, _ as platformBundleDefinePlugin, d as buildExecutorArgsExpr, f as buildResolverOperationHookExpr, g as stringifyFunction, h as TailorDBTypeSchema, i as resolverBundleKey, j as fetchMachineUserToken, k as fetchAll, l as HTTP_METHODS, m as assertUniqueTailorDBTypeNamesWithExternal, n as generatePluginFilesIfNeeded, o as WorkflowJobFunctionExecutionPolicySchema, p as assertUniqueLocalTailorDBTypeNames, r as loadApplication, t as defineApplication, w as getDistDir, x as getPluginGenerationDependencies, z as initOAuth2Client } from "./application-CqjCcZ2n.mjs";
6
+ import { o as loadFilesWithIgnores, s as functionSchema, t as createExecutorService } from "./service-BCRJ-3NV.mjs";
7
+ import { n as enumConstantsPlugin, t as EnumConstantsGeneratorID } from "./enum-constants-j9QBF0cB.mjs";
7
8
  import { t as multiline } from "./multiline-sfHpTZZK.mjs";
9
+ import { n as fileUtilsPlugin, t as FileUtilsGeneratorID } from "./file-utils-DcyIPFQh.mjs";
10
+ import { n as kyselyTypePlugin, t as KyselyGeneratorID } from "./kysely-type-D-zflMGf.mjs";
11
+ import { n as seedPlugin, t as SeedGeneratorID } from "./seed-DFFigL8V.mjs";
8
12
  import { t as readPackageJson } from "./package-json-8b0O9TlX.mjs";
9
- import { i as userAgent } from "./secret-file-VSVGy1V0.mjs";
13
+ import { t as userAgent } from "./user-agent-DX2Jnw0-.mjs";
10
14
  import { n as isCLIError, t as createCLIError } from "./errors-Dtf2WPaW.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, 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, 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-B5w9rjPY.mjs";
15
+ import { n as tightenSecretFilePermissions, r as writeSecretFile } from "./secret-file-DBqZhjFQ.mjs";
12
16
  import { r as withSpan } from "./telemetry-CdqJEzkj.mjs";
13
17
  import { arg, createDefineCommand, defineCommand, runCommand } from "politty";
14
18
  import { z } from "zod";
15
- import { ScalarType, create, fromJson, toJson } from "@bufbuild/protobuf";
19
+ import { create, fromJson, toJson } from "@bufbuild/protobuf";
16
20
  import * as fs$1 from "node:fs";
17
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
21
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
22
+ import { parseEnv } from "node:util";
18
23
  import { ValueSchema, timestampDate } from "@bufbuild/protobuf/wkt";
19
24
  import * as path from "pathe";
20
25
  import { formatDistanceToNowStrict } from "date-fns";
21
26
  import { getBorderCharacters, table } from "table";
22
27
  import { pathToFileURL } from "node:url";
28
+ import * as os from "node:os";
23
29
  import { tmpdir } from "node:os";
30
+ import { parseTOML, parseYAML, stringifyYAML } from "confbox";
24
31
  import { findUpSync } from "find-up-simple";
32
+ import { lt } from "semver";
25
33
  import { xdgConfig } from "xdg-basedir";
26
34
  import { Code, ConnectError } from "@connectrpc/connect";
27
35
  import pLimit from "p-limit";
@@ -47,6 +55,256 @@ import { createPrompt } from "@toiroakr/read-multiline";
47
55
  import { astVisitor, parse } from "pgsql-ast-parser";
48
56
  import { parse as parse$1 } from "@0no-co/graphql.web";
49
57
 
58
+ //#region src/cli/shared/args.ts
59
+ const unitToMs = {
60
+ ms: 1,
61
+ s: 1e3,
62
+ m: 60 * 1e3
63
+ };
64
+ const durationPattern = /^(\d+)(ms|s|m)$/;
65
+ /**
66
+ * Schema for duration string validation (e.g., "3s", "500ms", "1m")
67
+ * Only validates format; use parseDuration() to convert to milliseconds
68
+ */
69
+ const durationArg = z.string().refine((val) => durationPattern.test(val), { message: "Invalid duration format. Expected format: '3s', '500ms', '1m'" }).refine((val) => {
70
+ const match = val.match(durationPattern);
71
+ if (!match) return false;
72
+ const digits = match[1];
73
+ return digits !== void 0 && parseInt(digits, 10) > 0;
74
+ }, { message: "Duration must be greater than 0" });
75
+ /**
76
+ * Parse a validated duration string into milliseconds
77
+ * @param duration - Duration string (e.g., "3s", "500ms", "1m")
78
+ * @returns Duration in milliseconds
79
+ */
80
+ function parseDuration(duration) {
81
+ const match = assertDefined(duration.match(durationPattern), `invalid duration format: ${duration}`);
82
+ const value = parseInt(assertDefined(match[1], "duration digits group missing"), 10);
83
+ const unit = assertDefined(match[2], "duration unit group missing");
84
+ return value * unitToMs[unit];
85
+ }
86
+ /**
87
+ * Schema for positive integer validation (from string input)
88
+ * Transforms the string to a number
89
+ */
90
+ const positiveIntArg = z.coerce.number().int().positive();
91
+ /**
92
+ * Schema for non-negative integer validation (from string input).
93
+ * Accepts 0 (used for `--limit 0` to disable the limit).
94
+ */
95
+ const nonNegativeIntArg = z.coerce.number().int().nonnegative();
96
+ /**
97
+ * Schema for sort order (`asc` or `desc`).
98
+ */
99
+ const orderArg = z.enum(["asc", "desc"]);
100
+ /**
101
+ * Translate a CLI `--order` value into the proto `PageDirection` enum.
102
+ * Returns `undefined` when the user did not specify an order so that
103
+ * callers can omit the field and fall back to the server default.
104
+ * @param order - Order string from CLI args (`"asc"` | `"desc"` | undefined)
105
+ * @returns PageDirection, or undefined when `order` is undefined
106
+ */
107
+ function toPageDirection(order) {
108
+ if (order === void 0) return void 0;
109
+ return order === "asc" ? PageDirection.ASC : PageDirection.DESC;
110
+ }
111
+ function hasMachineUserFlag(argv) {
112
+ return argv.slice(0, argv.indexOf("--") === -1 ? argv.length : argv.indexOf("--")).some((token) => token === "-m" || token.startsWith("-m=") || token === "--machine-user" || token.startsWith("--machine-user=") || token === "--machineUser" || token.startsWith("--machineUser=") || token === "--machineuser" || token.startsWith("--machineuser="));
113
+ }
114
+ /**
115
+ * Resolve whether a parsed machine user value came from an explicit CLI option or env fallback.
116
+ * @param machineUser - Parsed machine user value
117
+ * @param argv - Raw CLI argv, excluding the executable and script path
118
+ * @param options - Source resolution options
119
+ * @returns Machine user input source, or undefined when no value was parsed
120
+ */
121
+ function resolveMachineUserInputSource(machineUser, argv = process.argv.slice(2), options = {}) {
122
+ if (machineUser === void 0) return void 0;
123
+ if (options.valueIsExplicit) return "option";
124
+ if (hasMachineUserFlag(argv)) return "option";
125
+ return process.env.TAILOR_PLATFORM_MACHINE_USER_NAME === machineUser ? "env" : "option";
126
+ }
127
+ /**
128
+ * Load env files from parsed arguments.
129
+ * Processes --env-file first, then --env-file-if-exists.
130
+ *
131
+ * Follows Node.js --env-file behavior:
132
+ * - Variables already set in the environment are NOT overwritten
133
+ * - Variables from later files override those from earlier files
134
+ * @param envFiles - Required env file path(s) that must exist
135
+ * @param envFilesIfExists - Optional env file path(s) that are loaded if they exist
136
+ */
137
+ function loadEnvFiles(envFiles, envFilesIfExists) {
138
+ const originalEnvKeys = new Set(Object.keys(process.env));
139
+ const load = (files, required) => {
140
+ for (const file of [files ?? []].flat()) {
141
+ const envPath = path.resolve(process.cwd(), file);
142
+ if (!fs$1.existsSync(envPath)) {
143
+ if (required) throw new Error(`Environment file not found: ${envPath}`);
144
+ continue;
145
+ }
146
+ const parsed = parseEnv(fs$1.readFileSync(envPath, "utf-8"));
147
+ for (const [key, value] of Object.entries(parsed)) {
148
+ if (originalEnvKeys.has(key)) continue;
149
+ process.env[key] = value;
150
+ }
151
+ }
152
+ };
153
+ load(envFiles, true);
154
+ load(envFilesIfExists, false);
155
+ }
156
+ /**
157
+ * Common arguments for all CLI commands
158
+ *
159
+ * NOTE: --env-file and --env-file-if-exists collide with Node.js flags due to a bug
160
+ * (https://github.com/nodejs/node/issues/54232). Node.js parses these even after the
161
+ * script path, causing warnings (twice due to tsx loader).
162
+ */
163
+ const commonArgs = {
164
+ "env-file": arg(z.string().optional(), {
165
+ alias: "e",
166
+ description: "Path to the environment file (error if not found)",
167
+ completion: {
168
+ type: "file",
169
+ matcher: [".env.*", ".env"]
170
+ }
171
+ }),
172
+ "env-file-if-exists": arg(z.string().optional(), {
173
+ description: "Path to the environment file (ignored if not found)",
174
+ completion: {
175
+ type: "file",
176
+ matcher: [".env.*", ".env"]
177
+ },
178
+ effect: (_value, { args }) => {
179
+ loadEnvFiles(args["env-file"], args["env-file-if-exists"]);
180
+ }
181
+ }),
182
+ verbose: arg(z.boolean().default(false), {
183
+ description: "Enable verbose logging",
184
+ effect: (value) => {
185
+ verboseMode = value;
186
+ }
187
+ }),
188
+ json: arg(z.boolean().default(false), {
189
+ alias: "j",
190
+ description: "Output as JSON",
191
+ effect: (value) => {
192
+ logger.jsonMode = value;
193
+ }
194
+ })
195
+ };
196
+ /**
197
+ * Arguments for commands that require workspace context
198
+ */
199
+ const workspaceArgs = {
200
+ "workspace-id": arg(z.string().optional(), {
201
+ alias: "w",
202
+ description: "Workspace ID",
203
+ env: "TAILOR_PLATFORM_WORKSPACE_ID",
204
+ completion: { type: "none" }
205
+ }),
206
+ profile: arg(z.string().optional(), {
207
+ alias: "p",
208
+ description: "Workspace profile",
209
+ env: "TAILOR_PLATFORM_PROFILE",
210
+ completion: { type: "none" }
211
+ })
212
+ };
213
+ /**
214
+ * Shared config arg for commands that accept a config file path
215
+ */
216
+ const configArg = { config: arg(z.string().default("tailor.config.ts"), {
217
+ alias: "c",
218
+ description: "Path to SDK config file",
219
+ env: "TAILOR_PLATFORM_SDK_CONFIG_PATH",
220
+ completion: {
221
+ type: "file",
222
+ extensions: ["ts"]
223
+ }
224
+ }) };
225
+ /**
226
+ * Shared config arg for commands that accept one or more comma-separated config file paths
227
+ */
228
+ const multiConfigArg = { config: arg(z.string().default("tailor.config.ts"), {
229
+ alias: "c",
230
+ description: "Path to SDK config file. Use comma-separated paths to deploy multiple apps together.",
231
+ env: "TAILOR_PLATFORM_SDK_CONFIG_PATH",
232
+ completion: {
233
+ type: "file",
234
+ extensions: ["ts"]
235
+ }
236
+ }) };
237
+ /**
238
+ * Arguments for commands that interact with deployed resources (includes config)
239
+ */
240
+ const deploymentArgs = {
241
+ ...workspaceArgs,
242
+ ...configArg
243
+ };
244
+ /**
245
+ * Arguments for commands that require confirmation
246
+ */
247
+ const confirmationArgs = { yes: arg(z.boolean().default(false), {
248
+ alias: "y",
249
+ description: "Skip confirmation prompts"
250
+ }) };
251
+ /**
252
+ * Arguments for commands that require organization context
253
+ */
254
+ const organizationArgs = { "organization-id": arg(z.string(), {
255
+ alias: "o",
256
+ description: "Organization ID",
257
+ env: "TAILOR_PLATFORM_ORGANIZATION_ID",
258
+ completion: { type: "none" }
259
+ }) };
260
+ /**
261
+ * Arguments for list commands that accept `--order` / `--limit`. Sort
262
+ * order defaults to `desc` (newest first) because most callers want the
263
+ * latest items; pass `--order asc` to opt in to ascending order. The
264
+ * limit is unbounded by default so existing invocations keep returning
265
+ * every item; pass `--limit N` to cap the result size.
266
+ * @param defaultOrder - Default value for `--order` (defaults to `"desc"`)
267
+ * @returns Argument shape suitable for spreading into a command schema
268
+ */
269
+ const paginationArgs = (defaultOrder = "desc") => ({
270
+ order: arg(orderArg.default(defaultOrder), { description: "Sort order (asc or desc)" }),
271
+ limit: arg(nonNegativeIntArg.optional(), {
272
+ alias: "l",
273
+ description: "Maximum number of items to return (0 or omit: unlimited)"
274
+ })
275
+ });
276
+ /**
277
+ * Arguments for time-series log list commands. Defaults to newest-first
278
+ * (`desc`) and a 50-item cap so that listing stays responsive on busy
279
+ * workspaces. Pass `--limit 0` to disable the cap and fetch all entries.
280
+ */
281
+ const pagedLogArgs = {
282
+ order: arg(orderArg.default("desc"), { description: "Sort order (asc or desc)" }),
283
+ limit: arg(nonNegativeIntArg.default(50), {
284
+ alias: "l",
285
+ description: "Maximum number of items to return (0: unlimited)"
286
+ })
287
+ };
288
+ /**
289
+ * Arguments for commands that require folder context
290
+ */
291
+ const folderArgs = { "folder-id": arg(z.string(), {
292
+ alias: "f",
293
+ description: "Folder ID",
294
+ env: "TAILOR_PLATFORM_FOLDER_ID",
295
+ completion: { type: "none" }
296
+ }) };
297
+ let verboseMode = false;
298
+ /**
299
+ * Returns whether verbose mode is enabled.
300
+ * Used by the global cleanup handler which doesn't have access to parsed args.
301
+ * @returns Whether verbose mode is enabled
302
+ */
303
+ function isVerbose() {
304
+ return verboseMode;
305
+ }
306
+
307
+ //#endregion
50
308
  //#region src/cli/shared/command.ts
51
309
  /**
52
310
  * defineCommand with global args type (CommonArgsType).
@@ -55,6 +313,846 @@ import { parse as parse$1 } from "@0no-co/graphql.web";
55
313
  */
56
314
  const defineAppCommand = createDefineCommand();
57
315
 
316
+ //#endregion
317
+ //#region src/parser/app-config/schema.ts
318
+ const envValueSchema = z.union([
319
+ z.string(),
320
+ z.number(),
321
+ z.boolean()
322
+ ]);
323
+ const LogLevelSchema = z.enum(LOG_LEVELS);
324
+ const logLevelSchema = z.string().refine((value) => LogLevelSchema.safeParse(value.trim().toUpperCase()).success, { message: `'logLevel' must be one of: ${LOG_LEVELS.join(", ")}.` });
325
+ /**
326
+ * Structural validation schema for `defineConfig({...})`. Validates only
327
+ * top-level fields with platform-side constraints (notably `id`); fields
328
+ * that carry SDK builder objects (`auth`, `idp`, `db`, ...) are accepted
329
+ * as opaque values, since their internal shapes are validated by their
330
+ * own factory functions and parser-level schemas.
331
+ *
332
+ * The `id` is auto-managed by `deploy` and stored as a plain UUID. A
333
+ * label-compatible prefix is added at the metadata boundary, so user-facing
334
+ * configs only need to carry a UUID.
335
+ */
336
+ const AppConfigSchema = z.object({
337
+ id: z.uuid({ message: "'id' must be a UUID." }).optional(),
338
+ name: z.string().min(1, { message: "'name' must be a non-empty string." }),
339
+ env: z.record(z.string(), envValueSchema).optional(),
340
+ cors: z.array(z.string()).optional(),
341
+ allowedIpAddresses: z.array(z.string()).optional(),
342
+ disableIntrospection: z.boolean().optional(),
343
+ inlineSourcemap: z.boolean().optional(),
344
+ logLevel: logLevelSchema.optional(),
345
+ db: z.unknown().optional(),
346
+ resolver: z.unknown().optional(),
347
+ idp: z.unknown().optional(),
348
+ auth: z.unknown().optional(),
349
+ executor: z.unknown().optional(),
350
+ workflow: z.unknown().optional(),
351
+ httpAdapter: z.unknown().optional(),
352
+ staticWebsites: z.unknown().optional(),
353
+ aiGateways: z.unknown().optional(),
354
+ secrets: z.unknown().optional()
355
+ });
356
+
357
+ //#endregion
358
+ //#region src/parser/generator-config/schema.ts
359
+ const DependencyKindSchema = z.enum([
360
+ "tailordb",
361
+ "resolver",
362
+ "executor"
363
+ ]);
364
+ const KyselyTypeConfigSchema = z.tuple([z.literal("@tailor-platform/kysely-type"), z.object({ distPath: z.string() })]);
365
+ const SeedConfigSchema = z.tuple([z.literal("@tailor-platform/seed"), z.object({
366
+ distPath: z.string(),
367
+ machineUserName: z.string().optional(),
368
+ disableIdpUserSync: z.object({
369
+ userToIdp: z.boolean().optional(),
370
+ idpToUser: z.boolean().optional()
371
+ }).optional()
372
+ })]);
373
+ const EnumConstantsConfigSchema = z.tuple([z.literal("@tailor-platform/enum-constants"), z.object({ distPath: z.string() })]);
374
+ const FileUtilsConfigSchema = z.tuple([z.literal("@tailor-platform/file-utils"), z.object({ distPath: z.string() })]);
375
+ const CodeGeneratorSchema = z.object({
376
+ id: z.string(),
377
+ description: z.string(),
378
+ dependencies: z.array(DependencyKindSchema),
379
+ processType: z.function().optional(),
380
+ processResolver: z.function().optional(),
381
+ processExecutor: z.function().optional(),
382
+ processTailorDBNamespace: z.function().optional(),
383
+ processResolverNamespace: z.function().optional(),
384
+ aggregate: z.function({ output: z.any() })
385
+ });
386
+ const BaseGeneratorConfigSchema = z.union([
387
+ KyselyTypeConfigSchema,
388
+ SeedConfigSchema,
389
+ EnumConstantsConfigSchema,
390
+ FileUtilsConfigSchema,
391
+ CodeGeneratorSchema
392
+ ]);
393
+
394
+ //#endregion
395
+ //#region src/parser/plugin-config/schema.ts
396
+ const PluginConfigSchema = z.object({
397
+ id: z.string(),
398
+ description: z.string(),
399
+ importPath: z.string().optional(),
400
+ pluginConfig: z.unknown().optional(),
401
+ typeConfigRequired: z.union([z.boolean(), functionSchema]).optional(),
402
+ onTypeLoaded: functionSchema.optional(),
403
+ onNamespaceLoaded: functionSchema.optional(),
404
+ onTailorDBReady: functionSchema.optional(),
405
+ onResolverReady: functionSchema.optional(),
406
+ onExecutorReady: functionSchema.optional()
407
+ }).passthrough().refine((p) => {
408
+ return !(p.onTypeLoaded || p.onNamespaceLoaded) || !!p.importPath;
409
+ }, { message: "importPath is required when plugin has definition-time hooks (onTypeLoaded/onNamespaceLoaded)" }).transform((plugin) => plugin);
410
+
411
+ //#endregion
412
+ //#region src/plugin/builtin/registry.ts
413
+ const builtinPlugins = /* @__PURE__ */ new Map([
414
+ [KyselyGeneratorID, (options) => kyselyTypePlugin(options)],
415
+ [SeedGeneratorID, (options) => seedPlugin(options)],
416
+ [EnumConstantsGeneratorID, (options) => enumConstantsPlugin(options)],
417
+ [FileUtilsGeneratorID, (options) => fileUtilsPlugin(options)]
418
+ ]);
419
+
420
+ //#endregion
421
+ //#region src/cli/shared/token-store.ts
422
+ const SERVICE_NAME = "tailor-platform-cli";
423
+ let entryClass;
424
+ async function getEntryClass() {
425
+ if (entryClass !== void 0) return entryClass;
426
+ try {
427
+ const mod = await import("@napi-rs/keyring");
428
+ const probe = new mod.Entry(SERVICE_NAME, "__probe__");
429
+ probe.setPassword("probe");
430
+ probe.deletePassword();
431
+ entryClass = mod.Entry;
432
+ } catch {
433
+ logger.warn("System keyring is not available. Tokens will be stored in the config file. Set TAILOR_PLATFORM_TOKEN environment variable for CI environments.");
434
+ entryClass = false;
435
+ }
436
+ return entryClass;
437
+ }
438
+ /**
439
+ * Check whether the OS keyring is available and functional.
440
+ * @returns true if keyring is available
441
+ */
442
+ async function isKeyringAvailable() {
443
+ return await getEntryClass() !== false;
444
+ }
445
+ /**
446
+ * Load tokens from the OS keyring for a given account.
447
+ * @param account - User identifier (e.g. email or client ID)
448
+ * @returns Token data or undefined if not found or keyring unavailable
449
+ */
450
+ async function loadKeyringTokens(account) {
451
+ const Entry = await getEntryClass();
452
+ if (!Entry) return void 0;
453
+ try {
454
+ const raw = new Entry(SERVICE_NAME, account).getPassword();
455
+ if (raw === null) return void 0;
456
+ return JSON.parse(raw);
457
+ } catch {
458
+ return;
459
+ }
460
+ }
461
+ /**
462
+ * Save tokens to the OS keyring for a given account.
463
+ * @param account - User identifier (e.g. email or client ID)
464
+ * @param tokens - Token data to store
465
+ */
466
+ async function saveKeyringTokens(account, tokens) {
467
+ const Entry = await getEntryClass();
468
+ if (!Entry) return;
469
+ new Entry(SERVICE_NAME, account).setPassword(JSON.stringify(tokens));
470
+ }
471
+ /**
472
+ * Delete tokens from the OS keyring for a given account.
473
+ * @param account - User identifier (e.g. email or client ID)
474
+ */
475
+ async function deleteKeyringTokens(account) {
476
+ const Entry = await getEntryClass();
477
+ if (!Entry) return;
478
+ try {
479
+ new Entry(SERVICE_NAME, account).deletePassword();
480
+ } catch {}
481
+ }
482
+
483
+ //#endregion
484
+ //#region src/cli/shared/context.ts
485
+ const pfProfileSchema = z.object({
486
+ user: z.string(),
487
+ workspace_id: z.string(),
488
+ readonly: z.boolean().optional(),
489
+ machine_user: z.string().optional(),
490
+ machine_user_override: z.enum(["allow", "deny"]).optional(),
491
+ platform_url: z.url().optional(),
492
+ oauth2_client_id: z.string().optional(),
493
+ console_url: z.url().optional()
494
+ });
495
+ const pfUserSchemaV1 = z.object({
496
+ access_token: z.string(),
497
+ refresh_token: z.string().optional(),
498
+ token_expires_at: z.string()
499
+ });
500
+ const pfUserKeyringSchema = z.object({
501
+ storage: z.literal("keyring"),
502
+ token_expires_at: z.string()
503
+ });
504
+ const pfUserFileSchema = z.object({
505
+ storage: z.literal("file"),
506
+ token_expires_at: z.string(),
507
+ access_token: z.string(),
508
+ refresh_token: z.string().optional()
509
+ });
510
+ const pfUserSchemaV2 = z.discriminatedUnion("storage", [pfUserKeyringSchema, pfUserFileSchema]);
511
+ const pfConfigSchemaV1 = z.object({
512
+ version: z.literal(1),
513
+ users: z.partialRecord(z.string(), pfUserSchemaV1),
514
+ profiles: z.partialRecord(z.string(), pfProfileSchema),
515
+ current_user: z.string().nullable()
516
+ });
517
+ const V2_CONFIG_VERSION = 2;
518
+ const LATEST_CONFIG_VERSION = 3;
519
+ const V2_MIN_SDK_VERSION = "1.29.0";
520
+ const V3_MIN_SDK_VERSION = "1.70.0";
521
+ const semverSchema = z.templateLiteral([
522
+ z.number().int(),
523
+ ".",
524
+ z.number().int(),
525
+ ".",
526
+ z.number().int()
527
+ ]);
528
+ const pfConfigSchema = z.object({
529
+ version: z.union([z.literal(V2_CONFIG_VERSION), z.literal(LATEST_CONFIG_VERSION)]),
530
+ min_sdk_version: semverSchema,
531
+ latest_version: z.number().int().optional(),
532
+ latest_min_sdk_version: semverSchema.optional(),
533
+ users: z.partialRecord(z.string(), pfUserSchemaV2),
534
+ profiles: z.partialRecord(z.string(), pfProfileSchema),
535
+ current_user: z.string().nullable()
536
+ });
537
+ function platformConfigPath() {
538
+ if (!xdgConfig) throw new Error("User home directory not found");
539
+ return path.join(xdgConfig, "tailor-platform", "config.yaml");
540
+ }
541
+ /**
542
+ * Convert stored profile platform fields to platform client settings.
543
+ * @param profile - Profile platform settings
544
+ * @returns Platform client settings
545
+ */
546
+ function platformConfigFromProfile(profile) {
547
+ const config = {
548
+ ...profile?.platform_url ? { platformUrl: profile.platform_url } : {},
549
+ ...profile?.oauth2_client_id ? { oauth2ClientId: profile.oauth2_client_id } : {},
550
+ ...profile?.console_url ? { consoleUrl: profile.console_url } : {}
551
+ };
552
+ return Object.keys(config).length > 0 ? config : void 0;
553
+ }
554
+ function platformUserKey(user, config) {
555
+ const platformUrl = getPlatformBaseUrl(config);
556
+ if (platformUrl === normalizeBaseUrl("https://api.tailor.tech")) return user;
557
+ return `${platformUrl}|${user}`;
558
+ }
559
+ function canUseLegacyUserKey(platformUrl) {
560
+ try {
561
+ return getPlatformBaseUrl() === platformUrl;
562
+ } catch {
563
+ return false;
564
+ }
565
+ }
566
+ function findUserEntry(config, user, platformConfig, opts = {}) {
567
+ const userKey = platformUserKey(user, platformConfig);
568
+ const userEntry = config.users[userKey];
569
+ if (userEntry) return {
570
+ userKey,
571
+ userEntry
572
+ };
573
+ const platformUrl = getPlatformBaseUrl(platformConfig);
574
+ if (userKey !== user && (opts.allowLegacyUserKey === false || !canUseLegacyUserKey(platformUrl))) return {
575
+ userKey,
576
+ userEntry
577
+ };
578
+ const legacyEntry = config.users[user];
579
+ return legacyEntry ? {
580
+ userKey: user,
581
+ userEntry: legacyEntry
582
+ } : {
583
+ userKey,
584
+ userEntry
585
+ };
586
+ }
587
+ /**
588
+ * Resolve the config user key that would be used for a user on the selected platform.
589
+ * @param config - Platform config
590
+ * @param user - User name
591
+ * @param platformConfig - Optional platform connection settings
592
+ * @param opts - Token lookup options
593
+ * @returns Resolved config user key
594
+ */
595
+ function resolveUserTokenKey(config, user, platformConfig, opts) {
596
+ return findUserEntry(config, user, platformConfig, opts).userKey;
597
+ }
598
+ /**
599
+ * Check whether tokens are registered for a user on the selected platform.
600
+ * @param config - Platform config
601
+ * @param user - User name
602
+ * @param platformConfig - Optional platform connection settings
603
+ * @param opts - Token lookup options
604
+ * @returns True when the user has a registered token entry
605
+ */
606
+ function hasUserTokenEntry(config, user, platformConfig, opts) {
607
+ return findUserEntry(config, user, platformConfig, opts).userEntry !== void 0;
608
+ }
609
+ function hasUserKeyForName(users, user) {
610
+ return users[user] !== void 0 || Object.keys(users).some((key) => key.endsWith(`|${user}`));
611
+ }
612
+ /**
613
+ * Check whether any platform has tokens registered for a user.
614
+ * @param config - Platform config
615
+ * @param user - User name
616
+ * @returns True when the user has a token entry for any platform
617
+ */
618
+ function hasAnyUserTokenEntry(config, user) {
619
+ return hasUserKeyForName(config.users, user);
620
+ }
621
+ function hasCurrentUserEntry(users, currentUser) {
622
+ return hasUserKeyForName(users, currentUser);
623
+ }
624
+ /**
625
+ * Migrate a v1 config to v2.
626
+ * Tokens are kept in the config file (storage: "file") during migration.
627
+ * They will be moved to the OS keyring on next login or token refresh.
628
+ * @param v1Config - v1 configuration to migrate
629
+ * @returns Migrated v2 configuration
630
+ */
631
+ function migrateV1ToV2(v1Config) {
632
+ const users = {};
633
+ for (const [name, v1User] of Object.entries(v1Config.users)) {
634
+ if (!v1User) continue;
635
+ users[name] = {
636
+ access_token: v1User.access_token,
637
+ refresh_token: v1User.refresh_token,
638
+ token_expires_at: v1User.token_expires_at,
639
+ storage: "file"
640
+ };
641
+ }
642
+ return {
643
+ version: V2_CONFIG_VERSION,
644
+ min_sdk_version: V2_MIN_SDK_VERSION,
645
+ users,
646
+ profiles: v1Config.profiles,
647
+ current_user: v1Config.current_user
648
+ };
649
+ }
650
+ async function warnIfNewerConfigAvailable(config) {
651
+ if (!config.latest_min_sdk_version) return;
652
+ if (lt((await readPackageJson()).version ?? "0.0.0", config.latest_min_sdk_version)) logger.warn(multiline`
653
+ A newer config version (${String(config.latest_version)}) is available.
654
+ Please update your SDK to >= ${config.latest_min_sdk_version}: pnpm update @tailor-platform/sdk
655
+ `);
656
+ }
657
+ /**
658
+ * Read Tailor Platform CLI configuration, migrating from tailorctl or v1 if necessary.
659
+ * @returns Parsed platform configuration
660
+ */
661
+ async function readPlatformConfig() {
662
+ const configPath = platformConfigPath();
663
+ if (!fs$1.existsSync(configPath)) {
664
+ logger.warn(`Config not found at ${configPath}, migrating from tailorctl config...`);
665
+ const tcConfig = readTailorctlConfig();
666
+ const v1Config = tcConfig ? fromTailorctlConfig(tcConfig) : {
667
+ version: 1,
668
+ users: {},
669
+ profiles: {},
670
+ current_user: null
671
+ };
672
+ writePlatformConfig(v1Config);
673
+ return migrateV1ToV2(v1Config);
674
+ }
675
+ const rawConfig = parseYAML(fs$1.readFileSync(configPath, "utf-8"));
676
+ tightenSecretFilePermissions(configPath);
677
+ const version = rawConfig != null && typeof rawConfig === "object" && "version" in rawConfig ? rawConfig.version : void 0;
678
+ if (typeof version === "number" && version > LATEST_CONFIG_VERSION) {
679
+ const minSdk = "min_sdk_version" in rawConfig ? String(rawConfig.min_sdk_version) : void 0;
680
+ const updateHint = minSdk ? `Please update your SDK to >= ${minSdk}: pnpm update @tailor-platform/sdk` : "Please update your SDK: pnpm update @tailor-platform/sdk";
681
+ throw new Error(multiline`
682
+ Config file uses version ${String(version)}, but this SDK only supports up to version ${String(LATEST_CONFIG_VERSION)}.
683
+ ${updateHint}
684
+ `);
685
+ }
686
+ const configResult = pfConfigSchema.safeParse(rawConfig);
687
+ if (configResult.success) {
688
+ await warnIfNewerConfigAvailable(configResult.data);
689
+ return configResult.data;
690
+ }
691
+ const v1Result = pfConfigSchemaV1.safeParse(rawConfig);
692
+ if (v1Result.success) return migrateV1ToV2(v1Result.data);
693
+ throw new Error(multiline`
694
+ Failed to parse config file at ${configPath}.
695
+ The file may be corrupted or created by an incompatible SDK version.
696
+ `);
697
+ }
698
+ function toV1ForDisk(config) {
699
+ const users = {};
700
+ for (const [name, entry] of Object.entries(config.users)) {
701
+ if (!entry || entry.storage === "keyring") continue;
702
+ users[name] = {
703
+ access_token: entry.access_token,
704
+ refresh_token: entry.refresh_token,
705
+ token_expires_at: entry.token_expires_at
706
+ };
707
+ }
708
+ const currentUser = config.current_user && hasCurrentUserEntry(users, config.current_user) ? config.current_user : null;
709
+ return {
710
+ version: 1,
711
+ users,
712
+ profiles: config.profiles,
713
+ current_user: currentUser
714
+ };
715
+ }
716
+ function hasProfilePlatformSettings(config) {
717
+ return Object.values(config.profiles).some((profile) => profile?.platform_url !== void 0 || profile?.oauth2_client_id !== void 0 || profile?.console_url !== void 0);
718
+ }
719
+ function hasScopedUserKeys(config) {
720
+ return Object.keys(config.users).some((userKey) => userKey.includes("|"));
721
+ }
722
+ function toLatestForDisk(config) {
723
+ return {
724
+ ...config.version === 1 ? migrateV1ToV2(config) : config,
725
+ version: LATEST_CONFIG_VERSION,
726
+ min_sdk_version: V3_MIN_SDK_VERSION
727
+ };
728
+ }
729
+ /**
730
+ * Write Tailor Platform CLI configuration to disk.
731
+ * By default, file-backed configs without newer fields are converted to V1 for
732
+ * backward compatibility, so an older SDK can still read the file. Configs
733
+ * containing a keyring user are kept in V2 or later because the keyring storage
734
+ * variant is not representable in V1. Configs containing profile-level Platform
735
+ * settings or platform-scoped user tokens are written in the latest
736
+ * min-SDK-gated format because older SDKs would silently drop or misread those
737
+ * settings.
738
+ * Set TAILOR_USE_KEYRING to write the current in-memory format unconditionally.
739
+ *
740
+ * The config file may contain access/refresh tokens when the OS keyring is
741
+ * unavailable, so it is written via {@link writeSecretFile} so other users
742
+ * on the host cannot read it.
743
+ * @param config - Platform configuration to write
744
+ */
745
+ function writePlatformConfig(config) {
746
+ const configPath = platformConfigPath();
747
+ const hasKeyringUser = config.version !== 1 && Object.values(config.users).some((u) => u?.storage === "keyring");
748
+ writeSecretFile(configPath, stringifyYAML(hasProfilePlatformSettings(config) || hasScopedUserKeys(config) ? toLatestForDisk(config) : config.version !== 1 && !process.env.TAILOR_USE_KEYRING && !hasKeyringUser ? toV1ForDisk(config) : config));
749
+ }
750
+ const tcContextConfigSchema = z.object({
751
+ username: z.string().optional(),
752
+ controlplaneaccesstoken: z.string().optional(),
753
+ controlplanerefreshtoken: z.string().optional(),
754
+ controlplanetokenexpiresat: z.string().optional(),
755
+ workspaceid: z.string().optional()
756
+ });
757
+ const tcConfigSchema = z.object({ global: z.object({ context: z.string().optional() }).optional() }).catchall(tcContextConfigSchema.optional());
758
+ function readTailorctlConfig() {
759
+ const configPath = path.join(os.homedir(), ".tailorctl", "config");
760
+ if (!fs$1.existsSync(configPath)) return;
761
+ const rawConfig = parseTOML(fs$1.readFileSync(configPath, "utf-8"));
762
+ return tcConfigSchema.parse(rawConfig);
763
+ }
764
+ function fromTailorctlConfig(config) {
765
+ const users = {};
766
+ const profiles = {};
767
+ let currentUser = null;
768
+ const currentContext = config.global?.context || "default";
769
+ for (const [key, val] of Object.entries(config)) {
770
+ if (key === "global") continue;
771
+ const context = val;
772
+ if (!context.username || !context.controlplaneaccesstoken || !context.controlplanerefreshtoken || !context.controlplanetokenexpiresat || !context.workspaceid) continue;
773
+ if (key === currentContext) currentUser = context.username;
774
+ profiles[key] = {
775
+ user: context.username,
776
+ workspace_id: context.workspaceid
777
+ };
778
+ const user = users[context.username];
779
+ if (!user || new Date(user.token_expires_at) < new Date(context.controlplanetokenexpiresat)) users[context.username] = {
780
+ access_token: context.controlplaneaccesstoken,
781
+ refresh_token: context.controlplanerefreshtoken,
782
+ token_expires_at: context.controlplanetokenexpiresat
783
+ };
784
+ }
785
+ return {
786
+ version: 1,
787
+ users,
788
+ profiles,
789
+ current_user: currentUser
790
+ };
791
+ }
792
+ function validateUUID(value, source) {
793
+ const result = z.uuid().safeParse(value);
794
+ if (!result.success) throw new Error(`Invalid value from ${source}: must be a valid UUID`);
795
+ return result.data;
796
+ }
797
+ /**
798
+ * Load workspace ID from command options, environment variables, or platform config.
799
+ * In CLI context, env fallback is also handled by politty's arg env option.
800
+ * Priority: opts/workspaceId > env/workspaceId > opts/profile > error
801
+ * @param opts - Workspace and profile options
802
+ * @returns Resolved workspace ID
803
+ */
804
+ async function loadWorkspaceId(opts) {
805
+ const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
806
+ if (opts?.workspaceId) return validateUUID(opts.workspaceId, "--workspace-id option");
807
+ if (process.env.TAILOR_PLATFORM_WORKSPACE_ID) return validateUUID(process.env.TAILOR_PLATFORM_WORKSPACE_ID, "TAILOR_PLATFORM_WORKSPACE_ID environment variable");
808
+ if (profile) {
809
+ const wsId = (await readPlatformConfig()).profiles[profile]?.workspace_id;
810
+ if (!wsId) throw new Error(`Profile "${profile}" not found`);
811
+ return validateUUID(wsId, `profile "${profile}"`);
812
+ }
813
+ throw new Error(multiline`
814
+ Workspace ID not found.
815
+ Please specify workspace ID via --workspace-id option or TAILOR_PLATFORM_WORKSPACE_ID environment variable.
816
+ `);
817
+ }
818
+ /**
819
+ * Load machine user name from command options, environment variables, or platform config.
820
+ * In CLI context, env fallback is also handled by politty's arg env option.
821
+ * Priority: opts/machineUser > env/TAILOR_PLATFORM_MACHINE_USER_NAME > opts/profile (profile default) > undefined.
822
+ * An explicitly empty `opts.machineUser` is rejected with a CLIError (`MACHINE_USER_NAME_EMPTY`) rather than falling back to the env var or profile default.
823
+ * When the active profile has `machine_user_override: "deny"`, an explicit value that differs from the profile's machine user throws a CLIError with code `PROFILE_MACHINE_USER_OVERRIDE_DENIED`.
824
+ * @param opts - Machine user and profile options
825
+ * @returns Resolved machine user name, or undefined if not set
826
+ */
827
+ async function loadMachineUserName(opts) {
828
+ if (opts?.machineUser === "") throw createCLIError({
829
+ code: "MACHINE_USER_NAME_EMPTY",
830
+ message: "Machine user name cannot be empty.",
831
+ suggestion: "Pass a non-empty machine user name, or omit the option to use the environment variable or profile default."
832
+ });
833
+ const envMachineUser = process.env.TAILOR_PLATFORM_MACHINE_USER_NAME || void 0;
834
+ const explicitMachineUser = opts?.machineUser ? {
835
+ source: opts.machineUserSource ?? "option",
836
+ value: opts.machineUser
837
+ } : envMachineUser ? {
838
+ source: "env",
839
+ value: envMachineUser
840
+ } : void 0;
841
+ const explicit = explicitMachineUser?.value;
842
+ const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
843
+ if (!profile) return explicit;
844
+ const entry = (await readPlatformConfig()).profiles[profile];
845
+ if (!entry) {
846
+ if (explicit) return explicit;
847
+ throw new Error(`Profile "${profile}" not found`);
848
+ }
849
+ if (entry.machine_user && entry.machine_user_override === "deny") {
850
+ if (explicit && explicit !== entry.machine_user) {
851
+ const details = explicitMachineUser.source === "env" ? `The machine user is being set to "${explicit}" via the TAILOR_PLATFORM_MACHINE_USER_NAME environment variable, which conflicts with this profile's pinned machine user "${entry.machine_user}".` : `This profile fixes the machine user to "${entry.machine_user}" for application-data commands.`;
852
+ throw createCLIError({
853
+ code: "PROFILE_MACHINE_USER_OVERRIDE_DENIED",
854
+ message: `Profile "${profile}" denies overriding the machine user.`,
855
+ details,
856
+ suggestion: `Omit the machine user option, unset TAILOR_PLATFORM_MACHINE_USER_NAME, or run 'tailor-sdk profile update ${profile} --machine-user-override allow'.`
857
+ });
858
+ }
859
+ return entry.machine_user;
860
+ }
861
+ return explicit || entry.machine_user;
862
+ }
863
+ /**
864
+ * Load access token from environment variables, command options, or platform config.
865
+ * In CLI context, profile env fallback is also handled by politty's arg env option.
866
+ * Priority: env/TAILOR_PLATFORM_TOKEN > env/TAILOR_TOKEN (deprecated) > opts/profile > env/profile > config/currentUser > error
867
+ * @param opts - Profile options
868
+ * @returns Resolved access token
869
+ */
870
+ async function loadAccessToken(opts) {
871
+ const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
872
+ const envToken = process.env.TAILOR_PLATFORM_TOKEN ?? process.env.TAILOR_TOKEN;
873
+ if (envToken && !process.env.TAILOR_PLATFORM_TOKEN) logger.warn("TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.");
874
+ if (envToken) {
875
+ rememberPlatformConfigForToken(envToken, await loadPlatformClientConfig({
876
+ profile,
877
+ allowMissingProfile: true
878
+ }));
879
+ return envToken;
880
+ }
881
+ const pfConfig = await readPlatformConfig();
882
+ const profileEntry = profile ? pfConfig.profiles[profile] : void 0;
883
+ if (profile && !profileEntry) throw new Error(`Profile "${profile}" not found`);
884
+ const user = profileEntry?.user ?? pfConfig.current_user;
885
+ if (!user) throw new Error(multiline`
886
+ Tailor Platform token not found.
887
+ Please specify token via TAILOR_PLATFORM_TOKEN environment variable or login using 'tailor-sdk login' command.
888
+ `);
889
+ return await fetchLatestToken(pfConfig, user, profileEntry ? platformConfigFromProfile(profileEntry) : void 0);
890
+ }
891
+ /**
892
+ * Load platform connection settings from the active profile.
893
+ * @param opts - Profile options
894
+ * @returns Resolved platform connection settings, or undefined for the default environment
895
+ */
896
+ async function loadPlatformClientConfig(opts) {
897
+ const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;
898
+ if (!profile) return;
899
+ let pfConfig;
900
+ try {
901
+ pfConfig = await readPlatformConfig();
902
+ } catch (error) {
903
+ if (opts?.allowMissingProfile) return;
904
+ throw error;
905
+ }
906
+ const profileEntry = pfConfig.profiles[profile];
907
+ if (!profileEntry) {
908
+ if (opts?.allowMissingProfile) return;
909
+ throw new Error(`Profile "${profile}" not found`);
910
+ }
911
+ return platformConfigFromProfile(profileEntry);
912
+ }
913
+ /**
914
+ * Load the Tailor Platform Console base URL from environment variables or the active profile.
915
+ * @param opts - Profile options
916
+ * @returns Resolved Console base URL
917
+ */
918
+ async function loadConsoleBaseUrl(opts) {
919
+ return getConsoleBaseUrl(await loadPlatformClientConfig(opts));
920
+ }
921
+ /**
922
+ * Resolve the actual token values for a user, reading from keyring or config as appropriate.
923
+ * @param userEntry - User entry from the config
924
+ * @param user - User identifier
925
+ * @param label - User-facing identifier used in error messages
926
+ * @returns Access token and optional refresh token
927
+ */
928
+ async function resolveTokens(userEntry, user, label = user) {
929
+ if (userEntry.storage === "keyring") {
930
+ const tokens = await loadKeyringTokens(user);
931
+ if (!tokens) throw new Error(multiline`
932
+ Credentials not found in OS keyring for "${label}".
933
+ Please run 'tailor-sdk login' and try again.
934
+ `);
935
+ return tokens;
936
+ }
937
+ return {
938
+ accessToken: userEntry.access_token,
939
+ refreshToken: userEntry.refresh_token
940
+ };
941
+ }
942
+ /**
943
+ * Save tokens for a user, writing to keyring or config as appropriate.
944
+ * @param config - Platform config
945
+ * @param user - User identifier
946
+ * @param tokens - Token data to save
947
+ * @param tokens.accessToken - Access token to persist
948
+ * @param tokens.refreshToken - Refresh token to persist when available
949
+ * @param expiresAt - Token expiration date
950
+ * @param platformConfig - Optional platform connection settings
951
+ */
952
+ async function saveUserTokens(config, user, tokens, expiresAt, platformConfig) {
953
+ const userKey = platformUserKey(user, platformConfig);
954
+ if (process.env.TAILOR_USE_KEYRING && await isKeyringAvailable()) {
955
+ await saveKeyringTokens(userKey, tokens);
956
+ config.users[userKey] = {
957
+ token_expires_at: expiresAt,
958
+ storage: "keyring"
959
+ };
960
+ } else config.users[userKey] = {
961
+ access_token: tokens.accessToken,
962
+ refresh_token: tokens.refreshToken,
963
+ token_expires_at: expiresAt,
964
+ storage: "file"
965
+ };
966
+ }
967
+ /**
968
+ * Delete tokens for a user from keyring if applicable.
969
+ * @param config - Platform config
970
+ * @param user - User identifier
971
+ * @param platformConfig - Optional platform connection settings
972
+ * @param opts - Token lookup options
973
+ */
974
+ async function deleteUserTokens(config, user, platformConfig, opts) {
975
+ const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);
976
+ if (userEntry?.storage === "keyring") await deleteKeyringTokens(userKey);
977
+ delete config.users[userKey];
978
+ }
979
+ /**
980
+ * Resolve stored tokens for a user on the selected platform.
981
+ * @param config - Platform config
982
+ * @param user - User name
983
+ * @param platformConfig - Optional platform connection settings
984
+ * @param opts - Token lookup options
985
+ * @returns Stored user entry and token values, or undefined when the user is not logged in
986
+ */
987
+ async function loadStoredUserTokens(config, user, platformConfig, opts) {
988
+ const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);
989
+ if (!userEntry) return void 0;
990
+ return {
991
+ userEntry,
992
+ ...await resolveTokens(userEntry, userKey, user)
993
+ };
994
+ }
995
+ /**
996
+ * Fetch the latest access token, refreshing if necessary.
997
+ * @param config - Platform config
998
+ * @param user - User name
999
+ * @param platformConfig - Optional platform connection settings
1000
+ * @returns Latest access token
1001
+ */
1002
+ async function fetchLatestToken(config, user, platformConfig) {
1003
+ const { userKey, userEntry } = findUserEntry(config, user, platformConfig);
1004
+ if (!userEntry) throw new Error(multiline`
1005
+ User "${user}" not found.
1006
+ Please verify your user name and login using 'tailor-sdk login' command.
1007
+ `);
1008
+ const tokens = await resolveTokens(userEntry, userKey, user);
1009
+ if (new Date(userEntry.token_expires_at) > /* @__PURE__ */ new Date()) {
1010
+ rememberPlatformConfigForToken(tokens.accessToken, platformConfig);
1011
+ return tokens.accessToken;
1012
+ }
1013
+ if (!tokens.refreshToken) throw new Error(multiline`
1014
+ Token expired.
1015
+ Please run 'tailor-sdk login' and try again.
1016
+ `);
1017
+ const client = initOAuth2Client(platformConfig);
1018
+ let resp;
1019
+ try {
1020
+ resp = await client.refreshToken({
1021
+ accessToken: tokens.accessToken,
1022
+ refreshToken: tokens.refreshToken,
1023
+ expiresAt: Date.parse(userEntry.token_expires_at)
1024
+ });
1025
+ } catch {
1026
+ throw new Error(multiline`
1027
+ Failed to refresh token. Your session may have expired.
1028
+ Please run 'tailor-sdk login' and try again.
1029
+ `);
1030
+ }
1031
+ const newExpiresAt = new Date(assertDefined(resp.expiresAt, "token refresh response missing expiresAt")).toISOString();
1032
+ await saveUserTokens(config, user, {
1033
+ accessToken: resp.accessToken,
1034
+ refreshToken: resp.refreshToken ?? void 0
1035
+ }, newExpiresAt, platformConfig);
1036
+ if (userKey !== platformUserKey(user, platformConfig)) {
1037
+ if (userEntry.storage === "keyring") await deleteKeyringTokens(userKey);
1038
+ delete config.users[userKey];
1039
+ }
1040
+ writePlatformConfig(config);
1041
+ rememberPlatformConfigForToken(resp.accessToken, platformConfig);
1042
+ return resp.accessToken;
1043
+ }
1044
+ const DEFAULT_CONFIG_FILENAME = "tailor.config.ts";
1045
+ /**
1046
+ * Load config path from command options, environment variables, or search parent directories.
1047
+ * In CLI context, env fallback is also handled by politty's arg env option.
1048
+ * Priority: opts/config > env/config > search parent directories
1049
+ * @param configPath - Optional explicit config path
1050
+ * @returns Resolved config path or undefined
1051
+ */
1052
+ function loadConfigPath(configPath) {
1053
+ if (configPath) return configPath;
1054
+ if (process.env.TAILOR_PLATFORM_SDK_CONFIG_PATH) return process.env.TAILOR_PLATFORM_SDK_CONFIG_PATH;
1055
+ return findUpSync(DEFAULT_CONFIG_FILENAME);
1056
+ }
1057
+
1058
+ //#endregion
1059
+ //#region src/cli/shared/mock.ts
1060
+ /**
1061
+ * Install a stub `globalThis.tailordb` so that user code loaded by the CLI
1062
+ * (e.g. via `createGetDB` in `@tailor-platform/sdk/kysely`) can reference
1063
+ * `tailordb.Client` without hitting a `ReferenceError`. The CLI never
1064
+ * actually executes the user code paths that issue queries, so a no-op
1065
+ * client suffices.
1066
+ *
1067
+ * Exposed as a function (rather than a top-level statement) so that
1068
+ * `package.json#sideEffects` can keep the file marked side-effect-free
1069
+ * without bundlers eliminating the install step.
1070
+ */
1071
+ function installCliTailordbStub() {
1072
+ globalThis.tailordb = { Client: class {
1073
+ constructor(_config) {}
1074
+ async connect() {}
1075
+ async end() {}
1076
+ async queryObject() {
1077
+ return {};
1078
+ }
1079
+ } };
1080
+ }
1081
+
1082
+ //#endregion
1083
+ //#region src/cli/shared/config-loader.ts
1084
+ const GeneratorConfigSchema = CodeGeneratorSchema.brand("CodeGenerator");
1085
+ /**
1086
+ * Load Tailor configuration file and associated generators and plugins.
1087
+ * @param configPath - Optional explicit config path
1088
+ * @param options - Optional module import behavior.
1089
+ * @returns Loaded config, generators, plugins, and config path
1090
+ */
1091
+ async function loadConfig(configPath, options = {}) {
1092
+ installCliTailordbStub();
1093
+ const foundPath = loadConfigPath(configPath);
1094
+ if (!foundPath) throw new Error("Configuration file not found: tailor.config.ts not found in current or parent directories");
1095
+ const resolvedPath = path.resolve(process.cwd(), foundPath);
1096
+ if (!fs$1.existsSync(resolvedPath)) throw new Error(`Configuration file not found: ${configPath}`);
1097
+ const configUrl = pathToFileURL(resolvedPath);
1098
+ if (options.importNonce) configUrl.searchParams.set("tailorImportNonce", options.importNonce);
1099
+ const configModule = await import(configUrl.href);
1100
+ if (!configModule || !configModule.default) throw new Error("Invalid Tailor config module: default export not found");
1101
+ const validated = AppConfigSchema.safeParse(configModule.default);
1102
+ if (!validated.success) {
1103
+ const issues = validated.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
1104
+ throw new Error(`Invalid Tailor config in ${resolvedPath}:\n${issues}`);
1105
+ }
1106
+ const allGenerators = [];
1107
+ const allPlugins = [];
1108
+ for (const value of Object.values(configModule)) if (Array.isArray(value)) {
1109
+ const generatorParsed = value.reduce((acc, item) => {
1110
+ if (!acc.success) return acc;
1111
+ const baseResult = BaseGeneratorConfigSchema.safeParse(item);
1112
+ if (baseResult.success && Array.isArray(baseResult.data)) {
1113
+ const [id, options] = baseResult.data;
1114
+ const pluginFactory = builtinPlugins.get(id);
1115
+ if (pluginFactory) {
1116
+ acc.convertedPlugins.push(pluginFactory(options));
1117
+ return acc;
1118
+ }
1119
+ }
1120
+ const result = GeneratorConfigSchema.safeParse(item);
1121
+ if (result.success) acc.items.push(result.data);
1122
+ else acc.success = false;
1123
+ return acc;
1124
+ }, {
1125
+ success: true,
1126
+ items: [],
1127
+ convertedPlugins: []
1128
+ });
1129
+ if (generatorParsed.success && (generatorParsed.items.length > 0 || generatorParsed.convertedPlugins.length > 0)) {
1130
+ allGenerators.push(...generatorParsed.items);
1131
+ allPlugins.push(...generatorParsed.convertedPlugins);
1132
+ continue;
1133
+ }
1134
+ const pluginParsed = value.reduce((acc, item) => {
1135
+ if (!acc.success) return acc;
1136
+ const result = PluginConfigSchema.safeParse(item);
1137
+ if (result.success) acc.items.push(result.data);
1138
+ else acc.success = false;
1139
+ return acc;
1140
+ }, {
1141
+ success: true,
1142
+ items: []
1143
+ });
1144
+ if (pluginParsed.success && pluginParsed.items.length > 0) allPlugins.push(...pluginParsed.items);
1145
+ }
1146
+ return {
1147
+ config: {
1148
+ ...configModule.default,
1149
+ path: resolvedPath
1150
+ },
1151
+ generators: allGenerators,
1152
+ plugins: allPlugins
1153
+ };
1154
+ }
1155
+
58
1156
  //#endregion
59
1157
  //#region src/cli/shared/readonly-guard.ts
60
1158
  /**
@@ -128,561 +1226,6 @@ async function apiCall(options) {
128
1226
  };
129
1227
  }
130
1228
 
131
- //#endregion
132
- //#region src/cli/commands/api/proto-reflect.ts
133
- const UNARY_METHODS = OperatorService.methods.filter((m) => m.methodKind === "unary");
134
- function listMethodNames() {
135
- return UNARY_METHODS.map((m) => m.name).toSorted();
136
- }
137
- /**
138
- * Returns every accepted form of the `endpoint` positional — bare method name
139
- * and fully-qualified `service/Method`. politty's expand completion keys its
140
- * static table by the literal endpoint string, so both forms must appear in
141
- * `choices` or the user typing the fully-qualified name gets no `--field`
142
- * completion candidates back at TAB time.
143
- * @returns Sorted list of accepted endpoint values
144
- */
145
- function listMethodChoices() {
146
- return UNARY_METHODS.flatMap((m) => [m.name, `${OperatorService.typeName}/${m.name}`]).toSorted();
147
- }
148
- function getMethodDescriptor(methodName) {
149
- return UNARY_METHODS.find((m) => m.name === methodName);
150
- }
151
- function extractMethodName(endpoint) {
152
- if (!endpoint.includes("/")) return endpoint;
153
- return endpoint.split("/").pop() ?? endpoint;
154
- }
155
- /**
156
- * Returns the nested message descriptor when the field is a message, a list of
157
- * messages, or a map with message values. Otherwise returns undefined.
158
- * @param field - The proto field descriptor to inspect
159
- * @returns The nested message descriptor, or undefined when the field isn't message-shaped
160
- */
161
- function nestedMessage(field) {
162
- if (field.fieldKind === "message") return field.message;
163
- if (field.fieldKind === "list" && field.listKind === "message") return field.message;
164
- if (field.fieldKind === "map" && field.mapKind === "message") return field.message;
165
- }
166
- /**
167
- * Most `google.protobuf.*` well-known types serialize as scalars in proto JSON
168
- * (Timestamp/Duration → RFC3339/duration string, FieldMask → comma-joined
169
- * string, *Value wrappers → underlying primitive, etc.), so we must not let
170
- * `--field` drill into their internal fields. Treating them as leaves keeps
171
- * the completion and the body shape consistent with what the server expects.
172
- * @param message - The proto message descriptor to inspect
173
- * @returns True when the message is a well-known type
174
- */
175
- function isWellKnownType(message) {
176
- return message.typeName.startsWith("google.protobuf.");
177
- }
178
- const UNREPRESENTABLE_WELL_KNOWN_TYPES = /* @__PURE__ */ new Set([
179
- "google.protobuf.Struct",
180
- "google.protobuf.Value",
181
- "google.protobuf.ListValue",
182
- "google.protobuf.NullValue",
183
- "google.protobuf.Any",
184
- "google.protobuf.Empty"
185
- ]);
186
- /**
187
- * @param message - The proto message descriptor to inspect
188
- * @returns True when the message is a well-known type that `--field` cannot represent
189
- */
190
- function isUnrepresentableWellKnownType(message) {
191
- return UNREPRESENTABLE_WELL_KNOWN_TYPES.has(message.typeName);
192
- }
193
- /**
194
- * Pre-enumerates every `--field` completion candidate for `methodName`,
195
- * walking the input message tree to produce a flat list that the shell can
196
- * prefix-filter at TAB time. Used by the `expand` completion variant so no
197
- * Node process is spawned per keystroke.
198
- *
199
- * For each leaf field, emits `key=` (key completion). Enum leaves additionally
200
- * emit `key=ENUM_VALUE` per value, bool leaves emit `key=true` and
201
- * `key=false`. For nested messages, emits `key.` (drill-down) and recurses.
202
- *
203
- * Returns an empty array when `methodName` is unknown so the `expand`
204
- * generator stays exception-free at script-generation time.
205
- * @param methodName - Name of the unary RPC whose input message is being walked
206
- * @returns Flat list of `{ value, description }` candidates
207
- */
208
- function enumerateAllFieldCompletions(methodName) {
209
- const method = getMethodDescriptor(methodName);
210
- if (!method) return [];
211
- const candidates = [];
212
- const visited = /* @__PURE__ */ new Set();
213
- function walk(message, prefix) {
214
- visited.add(message);
215
- for (const field of message.fields) {
216
- if (field.fieldKind === "list" || field.fieldKind === "map") continue;
217
- const fullKey = prefix + field.localName;
218
- if (field.fieldKind === "message") {
219
- if (isUnrepresentableWellKnownType(field.message)) continue;
220
- if (!isWellKnownType(field.message)) {
221
- const nested = field.message;
222
- candidates.push({
223
- value: `${fullKey}.`,
224
- description: `${fullKey} (message)`
225
- });
226
- if (!visited.has(nested)) walk(nested, `${fullKey}.`);
227
- continue;
228
- }
229
- }
230
- candidates.push({
231
- value: `${fullKey}=`,
232
- description: `Set ${fullKey}`
233
- });
234
- if (field.fieldKind === "enum") for (const v of field.enum.values) candidates.push({
235
- value: `${fullKey}=${v.name}`,
236
- description: v.name
237
- });
238
- else if (field.fieldKind === "scalar" && field.scalar === ScalarType.BOOL) {
239
- candidates.push({
240
- value: `${fullKey}=true`,
241
- description: "true"
242
- });
243
- candidates.push({
244
- value: `${fullKey}=false`,
245
- description: "false"
246
- });
247
- }
248
- }
249
- visited.delete(message);
250
- }
251
- walk(method.input, "");
252
- return candidates;
253
- }
254
- /**
255
- * Resolves the leaf `DescField` at a dotted `--field` path within an input
256
- * message tree. Returns undefined when any segment is missing or when a
257
- * non-leaf segment isn't a singular message — callers fall back to treating
258
- * the value as a string in that case.
259
- * @param input - The RPC input message descriptor
260
- * @param path - Dot-split path segments to follow (e.g. ["application", "name"])
261
- * @returns The leaf field descriptor, or undefined when the path doesn't resolve
262
- */
263
- function resolveLeafField(input, path) {
264
- let message = input;
265
- for (let i = 0; i < path.length; i++) {
266
- const field = message.fields.find((f) => f.localName === path[i]);
267
- if (!field) return void 0;
268
- if (i === path.length - 1) {
269
- if (field.fieldKind === "message" && isUnrepresentableWellKnownType(field.message)) return;
270
- return field;
271
- }
272
- if (field.fieldKind !== "message") return void 0;
273
- if (isWellKnownType(field.message)) return void 0;
274
- message = field.message;
275
- }
276
- }
277
-
278
- //#endregion
279
- //#region src/cli/commands/api/render.ts
280
- const SCALAR_LABEL = {
281
- [ScalarType.DOUBLE]: "double",
282
- [ScalarType.FLOAT]: "float",
283
- [ScalarType.INT64]: "int64",
284
- [ScalarType.UINT64]: "uint64",
285
- [ScalarType.INT32]: "int32",
286
- [ScalarType.FIXED64]: "fixed64",
287
- [ScalarType.FIXED32]: "fixed32",
288
- [ScalarType.BOOL]: "bool",
289
- [ScalarType.STRING]: "string",
290
- [ScalarType.BYTES]: "bytes",
291
- [ScalarType.UINT32]: "uint32",
292
- [ScalarType.SFIXED32]: "sfixed32",
293
- [ScalarType.SFIXED64]: "sfixed64",
294
- [ScalarType.SINT32]: "sint32",
295
- [ScalarType.SINT64]: "sint64"
296
- };
297
- function shortName(typeName) {
298
- const dot = typeName.lastIndexOf(".");
299
- return dot < 0 ? typeName : typeName.slice(dot + 1);
300
- }
301
- function scalarLabel(scalar) {
302
- return SCALAR_LABEL[scalar] ?? `scalar(${scalar})`;
303
- }
304
- function enumLabel(enumDesc) {
305
- return `enum ${shortName(enumDesc.typeName)}`;
306
- }
307
- function enumOf(field) {
308
- if (field.fieldKind === "enum") return field.enum;
309
- if (field.fieldKind === "list" && field.listKind === "enum") return field.enum;
310
- }
311
- function describeFieldType(field) {
312
- switch (field.fieldKind) {
313
- case "scalar": return scalarLabel(field.scalar);
314
- case "enum": return enumLabel(field.enum);
315
- case "message": return shortName(field.message.typeName);
316
- case "list": {
317
- let inner;
318
- if (field.listKind === "scalar") inner = scalarLabel(field.scalar);
319
- else if (field.listKind === "enum") inner = enumLabel(field.enum);
320
- else inner = shortName(field.message.typeName);
321
- return `repeated ${inner}`;
322
- }
323
- case "map": {
324
- const keyType = scalarLabel(field.mapKey);
325
- let valType;
326
- if (field.mapKind === "scalar") valType = scalarLabel(field.scalar);
327
- else if (field.mapKind === "enum") valType = enumLabel(field.enum);
328
- else valType = shortName(field.message.typeName);
329
- return `map<${keyType}, ${valType}>`;
330
- }
331
- default: return "<unknown>";
332
- }
333
- }
334
- function fieldToJson(field, visited) {
335
- const json = {
336
- name: field.localName,
337
- protoName: field.name,
338
- type: describeFieldType(field),
339
- fieldKind: field.fieldKind,
340
- repeated: field.fieldKind === "list"
341
- };
342
- if (field.oneof) json.oneof = field.oneof.name;
343
- const fieldEnum = enumOf(field);
344
- if (fieldEnum) json.enumValues = fieldEnum.values.map((v) => v.name);
345
- const nested = nestedMessage(field);
346
- if (nested && !visited.has(nested)) {
347
- visited.add(nested);
348
- json.message = {
349
- typeName: nested.typeName,
350
- fields: nested.fields.map((f) => fieldToJson(f, visited))
351
- };
352
- visited.delete(nested);
353
- } else if (nested) json.message = {
354
- typeName: nested.typeName,
355
- fields: [],
356
- recursive: true
357
- };
358
- return json;
359
- }
360
- function renderInspectJson(method) {
361
- const visited = /* @__PURE__ */ new Set([method.input]);
362
- return {
363
- method: method.name,
364
- input: {
365
- typeName: method.input.typeName,
366
- fields: method.input.fields.map((f) => fieldToJson(f, visited))
367
- },
368
- output: { typeName: method.output.typeName }
369
- };
370
- }
371
- function renderFieldText(field, indent, visited) {
372
- const lines = [];
373
- const oneofTag = field.oneof ? ` (oneof ${field.oneof.name})` : "";
374
- lines.push(`${indent}${field.localName}: ${describeFieldType(field)}${oneofTag}`);
375
- const fieldEnum = enumOf(field);
376
- if (fieldEnum) {
377
- const values = fieldEnum.values.map((v) => v.name).join(", ");
378
- lines.push(`${indent} values: ${values}`);
379
- }
380
- const nested = nestedMessage(field);
381
- if (nested && !visited.has(nested)) {
382
- visited.add(nested);
383
- for (const sub of nested.fields) lines.push(...renderFieldText(sub, `${indent} `, visited));
384
- visited.delete(nested);
385
- } else if (nested) lines.push(`${indent} …(recursive ${nested.typeName})`);
386
- return lines;
387
- }
388
- function renderInspectText(method) {
389
- const lines = [];
390
- lines.push(`${method.name}`);
391
- lines.push(` request: ${method.input.typeName}`);
392
- const visited = /* @__PURE__ */ new Set([method.input]);
393
- for (const f of method.input.fields) lines.push(...renderFieldText(f, " ", visited));
394
- lines.push(` response: ${method.output.typeName}`);
395
- return lines.join("\n");
396
- }
397
-
398
- //#endregion
399
- //#region src/cli/commands/api/inspect.ts
400
- const inspectCommand = defineAppCommand({
401
- name: "inspect",
402
- description: "Print the input message tree of an OperatorService endpoint.",
403
- notes: "Combine with the global `--json` flag for a machine-readable descriptor. Recursive type references and `oneof` membership are annotated. Use `tailor-sdk api list` to discover endpoint names.",
404
- examples: [{
405
- cmd: "GetApplication",
406
- desc: "Show fields of GetApplicationRequest."
407
- }, {
408
- cmd: "CreateExecutorExecutor",
409
- desc: "Inspect a deeply nested input with `(oneof config)` annotations."
410
- }],
411
- args: z.object({ endpoint: arg(z.string(), {
412
- positional: true,
413
- description: "API endpoint to inspect (e.g., 'GetApplication' or 'tailor.v1.OperatorService/GetApplication').",
414
- completion: { custom: { choices: listMethodNames() } }
415
- }) }).strict(),
416
- run: (args) => {
417
- const methodName = extractMethodName(args.endpoint);
418
- const method = getMethodDescriptor(methodName);
419
- if (!method) throw createCLIError({
420
- message: `unknown method: ${methodName}`,
421
- suggestion: "Run `tailor-sdk api list` to see available methods.",
422
- command: "api inspect"
423
- });
424
- if (logger.jsonMode) logger.out(renderInspectJson(method));
425
- else logger.out(renderInspectText(method));
426
- }
427
- });
428
-
429
- //#endregion
430
- //#region src/cli/commands/api/list.ts
431
- const listCommand$10 = defineAppCommand({
432
- name: "list",
433
- description: "List all invocable OperatorService methods.",
434
- notes: "Only single-request (non-streaming) methods are listed, because the CLI issues a single JSON request and reads one JSON response.",
435
- args: z.object({}).strict(),
436
- run: () => {
437
- const names = listMethodNames();
438
- if (logger.jsonMode) logger.out(names);
439
- else for (const name of names) logger.out(name);
440
- }
441
- });
442
-
443
- //#endregion
444
- //#region src/cli/commands/api/index.ts
445
- function resolveNamespaceName(methodName, config) {
446
- if (/Auth|Tenant|UserProfile/.test(methodName)) return config.auth?.name;
447
- if (/IdP/.test(methodName)) {
448
- if (config.idp?.length === 1) return assertDefined(config.idp[0], "idp config missing").name;
449
- return;
450
- }
451
- if (/TailorDB/.test(methodName)) {
452
- const keys = Object.keys(config.db ?? {});
453
- if (keys.length === 1) return keys[0];
454
- return;
455
- }
456
- if (/Pipeline/.test(methodName)) {
457
- const keys = Object.keys(config.resolver ?? {});
458
- if (keys.length === 1) return keys[0];
459
- return;
460
- }
461
- }
462
- /**
463
- * Parse a JSON body string as a plain object for field injection.
464
- * Returns undefined for invalid JSON or non-object values (null, arrays, primitives),
465
- * so callers can fall back to sending the raw string unchanged.
466
- * @param body - Raw body string
467
- * @returns Parsed object or undefined
468
- */
469
- function parseBodyAsObject(body) {
470
- let parsed;
471
- try {
472
- parsed = JSON.parse(body);
473
- } catch {
474
- return;
475
- }
476
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return;
477
- return parsed;
478
- }
479
- /**
480
- * Set a dotted path on a body object, replacing non-object intermediates as
481
- * needed. `--field` takes precedence over `--body`, so collisions overwrite.
482
- * @param obj - The body object to mutate
483
- * @param path - Dot-split path segments (e.g. ["application", "name"])
484
- * @param value - Value to assign at the leaf
485
- */
486
- function setNestedPath(obj, path, value) {
487
- let cursor = obj;
488
- for (let i = 0; i < path.length - 1; i++) {
489
- const key = assertDefined(path[i], "path segment missing");
490
- const next = cursor[key];
491
- if (typeof next !== "object" || next === null || Array.isArray(next)) cursor[key] = {};
492
- cursor = cursor[key];
493
- }
494
- cursor[assertDefined(path[path.length - 1], "path last segment missing")] = value;
495
- }
496
- /**
497
- * Coerces a raw `--field` string value to match the leaf proto type so the
498
- * JSON body sends a properly typed value. Today we only coerce bool — the
499
- * completion candidates explicitly suggest `=true`/`=false`, so sending the
500
- * literal string "true" would be a visible mismatch. Other scalars are left
501
- * as strings: proto JSON accepts string forms for ints/floats/int64/etc.,
502
- * and we'd rather pass through what the user typed than silently coerce.
503
- * @param field - The resolved leaf field descriptor, or undefined when the path didn't resolve
504
- * @param raw - The raw string value after `=`
505
- * @returns The value to write into the body object
506
- */
507
- function coerceFieldValue(field, raw) {
508
- if (field && field.fieldKind === "scalar" && field.scalar === ScalarType.BOOL) {
509
- if (raw === "true") return true;
510
- if (raw === "false") return false;
511
- throw new Error(`Invalid value for bool field: '${raw}'. Expected 'true' or 'false'.`);
512
- }
513
- return raw;
514
- }
515
- /**
516
- * Collapse top-level body keys that address a known input field by its
517
- * protobuf name (snake_case) or JSON name to the field's `localName`. protojson
518
- * accepts every alias, so converging them here lets the presence checks below
519
- * reason in a single namespace — otherwise a `--body` written as
520
- * `{"workspace_id": ...}` slips past the camelCase check and we inject a second
521
- * `workspaceId`, which the server rejects as a duplicate field. When both forms
522
- * are present the canonical key wins and the alias is dropped.
523
- * @param body - The parsed body object to mutate
524
- * @param fields - The target endpoint's input fields
525
- * @returns Whether any key was rewritten
526
- */
527
- function normalizeBodyFieldKeys(body, fields) {
528
- const aliasToLocal = /* @__PURE__ */ new Map();
529
- for (const f of fields) {
530
- aliasToLocal.set(f.name, f.localName);
531
- aliasToLocal.set(f.jsonName, f.localName);
532
- }
533
- let changed = false;
534
- for (const key of Object.keys(body)) {
535
- const local = aliasToLocal.get(key);
536
- if (!local || local === key) continue;
537
- if (!Object.hasOwn(body, local)) body[local] = body[key];
538
- delete body[key];
539
- changed = true;
540
- }
541
- return changed;
542
- }
543
- const FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set([
544
- "__proto__",
545
- "constructor",
546
- "prototype"
547
- ]);
548
- const fieldArg = z.string().transform((val, ctx) => {
549
- const eq = val.indexOf("=");
550
- if (eq < 0) {
551
- ctx.addIssue({
552
- code: z.ZodIssueCode.custom,
553
- message: `Invalid field format: '${val}'. Expected format: 'key=value' or 'a.b.c=value'`
554
- });
555
- return z.NEVER;
556
- }
557
- const key = val.slice(0, eq);
558
- if (key.length === 0) {
559
- ctx.addIssue({
560
- code: z.ZodIssueCode.custom,
561
- message: "Field key cannot be empty"
562
- });
563
- return z.NEVER;
564
- }
565
- const segments = key.split(".");
566
- if (segments.some((seg) => seg.length === 0)) {
567
- ctx.addIssue({
568
- code: z.ZodIssueCode.custom,
569
- message: `Invalid field key: '${key}'. Dotted segments cannot be empty`
570
- });
571
- return z.NEVER;
572
- }
573
- const forbidden = segments.find((seg) => FORBIDDEN_SEGMENTS.has(seg));
574
- if (forbidden) {
575
- ctx.addIssue({
576
- code: z.ZodIssueCode.custom,
577
- message: `Invalid field key: '${key}'. Segment '${forbidden}' is not allowed.`
578
- });
579
- return z.NEVER;
580
- }
581
- return {
582
- path: segments,
583
- value: val.slice(eq + 1)
584
- };
585
- });
586
- const apiCommand = defineAppCommand({
587
- name: "api",
588
- description: "Call Tailor Platform API endpoints directly.",
589
- notes: `Use \`tailor-sdk api list\` to enumerate invocable methods and \`tailor-sdk api inspect <endpoint>\` to print an endpoint's input message tree (combine with \`--json\` for machine-readable output).
590
-
591
- The request body is inferred from the target endpoint's request schema, and commonly required fields are auto-injected so they can be omitted from \`--body\`:
592
-
593
- - \`workspaceId\` — resolved from \`-w\` / \`TAILOR_PLATFORM_WORKSPACE_ID\` / the selected profile.
594
- - \`namespaceName\` — resolved from \`tailor.config.ts\` based on the endpoint's service:
595
- - Auth / Tenant / UserProfile endpoints use \`auth.name\`.
596
- - IdP / TailorDB / Pipeline endpoints use the sole configured namespace when exactly one is defined.
597
-
598
- Values already present in \`--body\` are never overridden. If a value cannot be resolved (e.g. no config found), injection is silently skipped and the server-side validation error takes precedence.
599
-
600
- Use \`--field key=value\` (repeatable) to set request body fields without writing JSON. Dotted keys (e.g. \`application.name=foo\`) build nested objects. \`--field\` overrides matching fields in \`--body\` and tab-completes from the endpoint's request schema.`,
601
- examples: [
602
- {
603
- cmd: "GetApplication -b '{\"applicationName\":\"app-1\"}'",
604
- desc: "Call an endpoint; workspaceId is auto-injected."
605
- },
606
- {
607
- cmd: "GetApplication -f applicationName=app-1",
608
- desc: "Same as above, using --field instead of --body."
609
- },
610
- {
611
- cmd: "list",
612
- desc: "List all invocable OperatorService methods."
613
- },
614
- {
615
- cmd: "inspect GetApplication",
616
- desc: "Show the input message tree for an endpoint."
617
- }
618
- ],
619
- subCommands: {
620
- list: listCommand$10,
621
- inspect: inspectCommand
622
- },
623
- args: z.object({
624
- ...workspaceArgs,
625
- ...configArg,
626
- body: arg(z.string().default("{}"), {
627
- alias: "b",
628
- description: "Request body as JSON."
629
- }),
630
- field: arg(fieldArg.array().optional(), {
631
- alias: "f",
632
- description: "Set a body field as `key=value` (repeatable; dotted keys nest). Overrides --body.",
633
- completion: { custom: { expand: {
634
- dependsOn: ["endpoint"],
635
- enumerate: ({ endpoint }) => enumerateAllFieldCompletions(extractMethodName(endpoint ?? ""))
636
- } } }
637
- }),
638
- endpoint: arg(z.string(), {
639
- positional: true,
640
- description: "API endpoint to call (e.g., 'GetApplication' or 'tailor.v1.OperatorService/GetApplication').",
641
- completion: { custom: { choices: listMethodChoices() } }
642
- })
643
- }).strict(),
644
- run: async (args) => {
645
- await assertWritable({ profile: args.profile });
646
- const methodName = extractMethodName(args.endpoint);
647
- const method = getMethodDescriptor(methodName);
648
- const parsedBody = parseBodyAsObject(args.body);
649
- let mutated = false;
650
- if (args.field && args.field.length > 0) {
651
- if (!parsedBody) throw new Error("--field requires --body to be a JSON object (or omitted).");
652
- for (const f of args.field) {
653
- const leaf = method ? resolveLeafField(method.input, f.path) : void 0;
654
- setNestedPath(parsedBody, f.path, coerceFieldValue(leaf, f.value));
655
- }
656
- mutated = true;
657
- }
658
- if (parsedBody && method) {
659
- if (normalizeBodyFieldKeys(parsedBody, method.input.fields)) mutated = true;
660
- const fieldNames = method.input.fields.map((f) => f.localName);
661
- if (fieldNames.includes("workspaceId") && !Object.hasOwn(parsedBody, "workspaceId")) try {
662
- parsedBody.workspaceId = await loadWorkspaceId({
663
- workspaceId: args["workspace-id"],
664
- profile: args.profile
665
- });
666
- mutated = true;
667
- } catch {}
668
- if (fieldNames.includes("namespaceName") && !Object.hasOwn(parsedBody, "namespaceName")) try {
669
- const { config } = await loadConfig(args.config);
670
- const ns = resolveNamespaceName(methodName, config);
671
- if (ns) {
672
- parsedBody.namespaceName = ns;
673
- mutated = true;
674
- }
675
- } catch {}
676
- }
677
- const result = await apiCall({
678
- profile: args.profile,
679
- endpoint: args.endpoint,
680
- body: mutated && parsedBody ? JSON.stringify(parsedBody) : args.body
681
- });
682
- logger.out(JSON.stringify(result.data, null, 2));
683
- }
684
- });
685
-
686
1229
  //#endregion
687
1230
  //#region src/cli/shared/prompt.ts
688
1231
  /**
@@ -2296,35 +2839,59 @@ const SecretsStateSchema = z.object({
2296
2839
  vaults: z.record(z.string(), z.record(z.string(), z.string())),
2297
2840
  connections: z.record(z.string(), z.string()).optional()
2298
2841
  });
2842
+ const PersistedSecretsStateSchema = z.object({
2843
+ version: z.literal(1),
2844
+ workspaceId: z.string(),
2845
+ applicationKey: z.string(),
2846
+ state: SecretsStateSchema
2847
+ });
2299
2848
  /**
2300
- * Get the file path for the secrets state JSON.
2301
- * @returns Absolute path to secrets-state.json
2849
+ * Get the file path for one workspace and application's secrets state JSON.
2850
+ * @param scope - Workspace and application identity for the deployment
2851
+ * @returns Absolute path to the scoped state file
2302
2852
  */
2303
- function getSecretsStatePath() {
2304
- return path.join(getDistDir(), "secrets-state.json");
2853
+ function getSecretsStatePath(scope) {
2854
+ const scopeHash = hashValue(JSON.stringify([scope.workspaceId, applicationStateKey(scope)]));
2855
+ return path.join(getDistDir(), "secrets-state", `${scopeHash}.json`);
2305
2856
  }
2306
- /**
2307
- * Load secrets hash state from disk.
2308
- * @returns Persisted state, or empty state if file is missing or corrupted
2309
- */
2310
- function loadSecretsState() {
2311
- const filePath = getSecretsStatePath();
2312
- if (!existsSync(filePath)) return { vaults: {} };
2857
+ function loadPersistedSecretsState(scope) {
2313
2858
  try {
2314
- const raw = readFileSync(filePath, "utf-8");
2315
- return SecretsStateSchema.parse(JSON.parse(raw));
2859
+ const raw = readFileSync(getSecretsStatePath(scope), "utf-8");
2860
+ const persistedState = PersistedSecretsStateSchema.parse(JSON.parse(raw));
2861
+ if (persistedState.workspaceId !== scope.workspaceId || persistedState.applicationKey !== applicationStateKey(scope)) return;
2862
+ return persistedState;
2316
2863
  } catch {
2317
- return { vaults: {} };
2864
+ return;
2318
2865
  }
2319
2866
  }
2867
+ function applicationStateKey(scope) {
2868
+ if (!scope.applicationId) throw new Error(`Application "${scope.applicationName}" has no stable id for secrets state`);
2869
+ return `id:${scope.applicationId}`;
2870
+ }
2320
2871
  /**
2321
- * Save secrets hash state to disk.
2872
+ * Load secrets hash state for one workspace and application from disk.
2873
+ * @param scope - Workspace and application identity for the deployment
2874
+ * @returns Persisted state, or empty state if the scope is missing or the file is invalid
2875
+ */
2876
+ function loadSecretsState(scope) {
2877
+ if (!scope.applicationId) return { vaults: {} };
2878
+ return loadPersistedSecretsState(scope)?.state ?? { vaults: {} };
2879
+ }
2880
+ /**
2881
+ * Save secrets hash state for one workspace and application to disk.
2882
+ * @param scope - Workspace and application identity for the deployment
2322
2883
  * @param state - The secrets state to persist
2323
2884
  */
2324
- function saveSecretsState(state) {
2325
- const filePath = getSecretsStatePath();
2885
+ function saveSecretsState(scope, state) {
2886
+ if (!scope.applicationId) return;
2887
+ const filePath = getSecretsStatePath(scope);
2326
2888
  mkdirSync(path.dirname(filePath), { recursive: true });
2327
- writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
2889
+ writeFileSync(filePath, JSON.stringify({
2890
+ version: 1,
2891
+ workspaceId: scope.workspaceId,
2892
+ applicationKey: applicationStateKey(scope),
2893
+ state
2894
+ }, null, 2), "utf-8");
2328
2895
  }
2329
2896
  /**
2330
2897
  * Compute SHA-256 hex digest of a value.
@@ -2390,6 +2957,11 @@ function buildUpdateMask(existing, desired, secretChanged) {
2390
2957
  * @returns Planned changes for auth connections
2391
2958
  */
2392
2959
  async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2960
+ const stateScope = {
2961
+ workspaceId,
2962
+ applicationId: appId,
2963
+ applicationName: appName
2964
+ };
2393
2965
  const changeSet = createChangeSet("Auth connections");
2394
2966
  const conflicts = [];
2395
2967
  const unmanaged = [];
@@ -2413,7 +2985,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2413
2985
  allLabels: metadata?.labels
2414
2986
  };
2415
2987
  }));
2416
- const state = loadSecretsState();
2988
+ const state = loadSecretsState(stateScope);
2417
2989
  for (const [name, config] of Object.entries(desiredConnections)) {
2418
2990
  const existing = existingConnections[name];
2419
2991
  const metaRequest = await buildMetaRequest({
@@ -2474,7 +3046,8 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2474
3046
  changeSet,
2475
3047
  conflicts,
2476
3048
  unmanaged,
2477
- resourceOwners
3049
+ resourceOwners,
3050
+ stateScope
2478
3051
  };
2479
3052
  }
2480
3053
  /**
@@ -2484,7 +3057,7 @@ async function planAuthConnections(client, workspaceId, appName, appId, auths) {
2484
3057
  * @param phase - Apply phase
2485
3058
  */
2486
3059
  async function applyAuthConnections(client, result, phase) {
2487
- const { changeSet } = result;
3060
+ const { changeSet, stateScope } = result;
2488
3061
  if (phase === "create-update") {
2489
3062
  await Promise.all(changeSet.creates.map(async (create) => {
2490
3063
  await client.createAuthConnection(create.request);
@@ -2498,26 +3071,29 @@ async function applyAuthConnections(client, result, phase) {
2498
3071
  await Promise.all(changeSet.updates.map(async (update) => {
2499
3072
  await client.setMetadata(update.metaRequest);
2500
3073
  }));
2501
- const state = loadSecretsState();
2502
- if (!state.connections) state.connections = {};
2503
- for (const create of changeSet.creates) {
2504
- const conn = create.request.connection;
2505
- if (conn?.config?.case === "oauth2") state.connections[create.name] = hashValue(conn.config.value.clientSecret ?? "");
2506
- }
2507
- for (const replace of changeSet.replaces) {
2508
- const conn = replace.updateRequest.connection;
2509
- if (conn?.config?.case === "oauth2" && replace.updateRequest.updateMask?.paths?.includes("oauth2.client_secret")) state.connections[replace.name] = hashValue(conn.config.value.clientSecret ?? "");
3074
+ const secretReplaces = changeSet.replaces.filter((replace) => replace.updateRequest.updateMask?.paths?.includes("oauth2.client_secret"));
3075
+ if (changeSet.creates.length > 0 || secretReplaces.length > 0) {
3076
+ const state = loadSecretsState(stateScope);
3077
+ if (!state.connections) state.connections = {};
3078
+ for (const create of changeSet.creates) {
3079
+ const conn = create.request.connection;
3080
+ if (conn?.config?.case === "oauth2") state.connections[create.name] = hashValue(conn.config.value.clientSecret ?? "");
3081
+ }
3082
+ for (const replace of secretReplaces) {
3083
+ const conn = replace.updateRequest.connection;
3084
+ if (conn?.config?.case === "oauth2") state.connections[replace.name] = hashValue(conn.config.value.clientSecret ?? "");
3085
+ }
3086
+ saveSecretsState(stateScope, state);
2510
3087
  }
2511
- saveSecretsState(state);
2512
3088
  } else {
2513
3089
  await Promise.all(changeSet.deletes.map(async (del) => {
2514
3090
  await client.deleteAuthConnection(del.request);
2515
3091
  }));
2516
3092
  if (changeSet.deletes.length > 0) {
2517
- const state = loadSecretsState();
3093
+ const state = loadSecretsState(stateScope);
2518
3094
  if (state.connections) {
2519
3095
  for (const del of changeSet.deletes) delete state.connections[del.name];
2520
- saveSecretsState(state);
3096
+ saveSecretsState(stateScope, state);
2521
3097
  }
2522
3098
  }
2523
3099
  }
@@ -3680,7 +4256,10 @@ async function applyAuth(client, result, phase = "create-update") {
3680
4256
  await Promise.all([...changeSet.machineUser.creates.map((create) => client.createAuthMachineUser(create.request)), ...changeSet.machineUser.updates.map((update) => client.updateAuthMachineUser(update.request))]);
3681
4257
  };
3682
4258
  const applyCreateUpdateDependents = async () => {
3683
- await applyAuthConnections(client, { changeSet: changeSet.connection }, "create-update");
4259
+ await applyAuthConnections(client, {
4260
+ changeSet: changeSet.connection,
4261
+ stateScope: result.connectionStateScope
4262
+ }, "create-update");
3684
4263
  await Promise.all([...changeSet.idpConfig.creates.map(async (create) => {
3685
4264
  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);
3686
4265
  return client.createAuthIDPConfig(create.request);
@@ -3723,7 +4302,10 @@ async function applyAuth(client, result, phase = "create-update") {
3723
4302
  await Promise.all(changeSet.tenantConfig.deletes.map((del) => client.deleteTenantConfig(del.request)));
3724
4303
  await Promise.all(changeSet.userProfileConfig.deletes.map((del) => client.deleteUserProfileConfig(del.request)));
3725
4304
  await Promise.all(changeSet.idpConfig.deletes.map((del) => client.deleteAuthIDPConfig(del.request)));
3726
- await applyAuthConnections(client, { changeSet: changeSet.connection }, "delete-resources");
4305
+ await applyAuthConnections(client, {
4306
+ changeSet: changeSet.connection,
4307
+ stateScope: result.connectionStateScope
4308
+ }, "delete-resources");
3727
4309
  } else if (phase === "delete-services") await Promise.all(changeSet.service.deletes.map((del) => client.deleteAuthService(del.request)));
3728
4310
  }
3729
4311
  /**
@@ -3767,7 +4349,8 @@ async function planAuth(context) {
3767
4349
  },
3768
4350
  conflicts: [...conflicts, ...connectionResult.conflicts],
3769
4351
  unmanaged: [...unmanaged, ...connectionResult.unmanaged],
3770
- resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners])
4352
+ resourceOwners: /* @__PURE__ */ new Set([...resourceOwners, ...connectionResult.resourceOwners]),
4353
+ connectionStateScope: connectionResult.stateScope
3771
4354
  };
3772
4355
  }
3773
4356
  async function planServices$2(client, workspaceId, appName, appId, auths, forceApplyAll = false) {
@@ -5643,7 +6226,12 @@ async function planSecretManager(context) {
5643
6226
  getName: (resource) => resource.name,
5644
6227
  getTrn: (name) => resourceTrn(workspaceId, "vault", name)
5645
6228
  });
5646
- const state = loadSecretsState();
6229
+ const stateScope = {
6230
+ workspaceId,
6231
+ applicationId: application.id,
6232
+ applicationName: application.name
6233
+ };
6234
+ const state = loadSecretsState(stateScope);
5647
6235
  const skippedSecrets = [];
5648
6236
  await Promise.all(secretVaults.map(async (vault) => {
5649
6237
  const vaultName = vault.vaultName;
@@ -5752,7 +6340,8 @@ async function planSecretManager(context) {
5752
6340
  skippedSecrets,
5753
6341
  conflicts,
5754
6342
  unmanaged,
5755
- resourceOwners
6343
+ resourceOwners,
6344
+ stateScope
5756
6345
  };
5757
6346
  }
5758
6347
  /**
@@ -5760,11 +6349,11 @@ async function planSecretManager(context) {
5760
6349
  * @param client - Operator client instance
5761
6350
  * @param result - Planned secret changes
5762
6351
  * @param phase - Apply phase
5763
- * @param application - Application to read secrets from for hash state persistence
6352
+ * @param application - Application used for ownership metadata and hash state persistence
5764
6353
  * @returns Promise that resolves when secret changes are applied
5765
6354
  */
5766
6355
  async function applySecretManager(client, result, phase = "create-update", application) {
5767
- const { vaultChangeSet, secretChangeSet } = result;
6356
+ const { vaultChangeSet, secretChangeSet, stateScope } = result;
5768
6357
  if (phase === "create-update") {
5769
6358
  await Promise.all(vaultChangeSet.creates.map(async (create) => {
5770
6359
  await client.createSecretManagerVault(vaultCreateRequest(create));
@@ -5787,13 +6376,14 @@ async function applySecretManager(client, result, phase = "create-update", appli
5787
6376
  }));
5788
6377
  await Promise.all(secretChangeSet.creates.map((create) => client.createSecretManagerSecret(secretCreateRequest(create))));
5789
6378
  await Promise.all(secretChangeSet.updates.map((update) => client.updateSecretManagerSecret(secretUpdateRequest(update))));
5790
- if (application) {
5791
- const state = loadSecretsState();
5792
- for (const vault of application.secrets) {
5793
- if (!Object.hasOwn(state.vaults, vault.vaultName)) state.vaults[vault.vaultName] = {};
5794
- for (const secret of vault.secrets) if (secret.value != null) assertDefined(state.vaults[vault.vaultName], "vault state entry missing")[secret.name] = hashValue(secret.value);
6379
+ const secretHashUpdates = [...secretChangeSet.creates, ...secretChangeSet.updates];
6380
+ if (application && secretHashUpdates.length > 0) {
6381
+ const state = loadSecretsState(stateScope);
6382
+ for (const secret of secretHashUpdates) {
6383
+ if (!Object.hasOwn(state.vaults, secret.vaultName)) state.vaults[secret.vaultName] = {};
6384
+ assertDefined(state.vaults[secret.vaultName], "vault state entry missing")[secret.secretName] = hashValue(secret.value);
5795
6385
  }
5796
- saveSecretsState(state);
6386
+ saveSecretsState(stateScope, state);
5797
6387
  }
5798
6388
  } else {
5799
6389
  await Promise.all(secretChangeSet.deletes.map((del) => client.deleteSecretManagerSecret({
@@ -5806,13 +6396,13 @@ async function applySecretManager(client, result, phase = "create-update", appli
5806
6396
  secretmanagerVaultName: del.name
5807
6397
  })));
5808
6398
  if (secretChangeSet.deletes.length > 0 || vaultChangeSet.deletes.length > 0) {
5809
- const state = loadSecretsState();
6399
+ const state = loadSecretsState(stateScope);
5810
6400
  for (const del of secretChangeSet.deletes) if (Object.hasOwn(state.vaults, del.vaultName)) {
5811
6401
  delete assertDefined(state.vaults[del.vaultName], "vault state entry missing")[del.secretName];
5812
6402
  if (Object.keys(assertDefined(state.vaults[del.vaultName], "vault state entry missing")).length === 0) delete state.vaults[del.vaultName];
5813
6403
  }
5814
6404
  for (const del of vaultChangeSet.deletes) delete state.vaults[del.name];
5815
- saveSecretsState(state);
6405
+ saveSecretsState(stateScope, state);
5816
6406
  }
5817
6407
  }
5818
6408
  }
@@ -10311,11 +10901,11 @@ async function registerJobFunctions(client, changeSet, appName, appId, unchanged
10311
10901
  const allUsedJobNames = /* @__PURE__ */ new Set();
10312
10902
  unchangedWorkflowJobNames.forEach((jobName) => allUsedJobNames.add(jobName));
10313
10903
  for (const item of [...changeSet.creates, ...changeSet.updates]) for (const jobName of item.usedJobNames) allUsedJobNames.add(jobName);
10314
- const existingJobFunctions = await fetchAll(async (pageToken, _maxPageSize) => {
10904
+ const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
10315
10905
  const response = await client.listWorkflowJobFunctions({
10316
10906
  workspaceId,
10317
10907
  pageToken,
10318
- pageSize: 100
10908
+ pageSize: maxPageSize
10319
10909
  });
10320
10910
  return [response.jobFunctions.map((j) => j.name), response.nextPageToken];
10321
10911
  });
@@ -10495,11 +11085,11 @@ async function planWorkflow(client, workspaceId, appName, appId, workflows, main
10495
11085
  }
10496
11086
  async function planWorkflowJobFunctionDeletes(params) {
10497
11087
  const { client, workspaceId, appName, appId, retainedWorkflowJobNames } = params;
10498
- const existingJobFunctions = await fetchAll(async (pageToken, _maxPageSize) => {
11088
+ const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {
10499
11089
  const response = await client.listWorkflowJobFunctions({
10500
11090
  workspaceId,
10501
11091
  pageToken,
10502
- pageSize: 100
11092
+ pageSize: maxPageSize
10503
11093
  });
10504
11094
  return [response.jobFunctions.map((jobFunction) => jobFunction.name), response.nextPageToken];
10505
11095
  });
@@ -11118,13 +11708,14 @@ function validateItems(params) {
11118
11708
  *
11119
11709
  * Collections not validated: idp client, tailorDB gqlPermission, functionRegistry — no
11120
11710
  * buf.validate annotations.
11121
- * Application cors and IdP userAuthPolicy.allowedReturnOrigins receive special
11122
- * handling: static-website URL placeholders are resolved at apply time, so the
11711
+ * Application cors, AIGateway cors, and IdP userAuthPolicy.allowedReturnOrigins receive
11712
+ * special handling: static-website URL placeholders are resolved at apply time, so the
11123
11713
  * relevant origin/URL constraints would false-positive on `<name>:url` entries
11124
- * here. Application cors is dropped entirely (no other constraint to lose); IdP
11125
- * `allowedReturnOrigins` substitutes placeholder entries with a dummy origin so
11126
- * the per-item regex and the cross-field `enable_mfa requires ≥1 origin` rule
11127
- * still get exercised on the rest of the payload.
11714
+ * here. Application cors and AIGateway cors are dropped entirely, forgoing their
11715
+ * per-item URL/origin constraints for the whole list rather than substituting
11716
+ * placeholders; IdP `allowedReturnOrigins` instead substitutes placeholder entries
11717
+ * with a dummy origin so the per-item regex and the cross-field `enable_mfa requires
11718
+ * ≥1 origin` rule still get exercised on the rest of the payload.
11128
11719
  * Workflow jobFunctions map excluded: versions are registered at apply time (registerJobFunctions)
11129
11720
  * and the map field carries no min_items constraint. Job names are validated separately via
11130
11721
  * CreateWorkflowJobFunctionRequestSchema using usedJobNames from the workflow change set.
@@ -11134,7 +11725,7 @@ function validateItems(params) {
11134
11725
  * @param input - Plan results from the plan phase
11135
11726
  */
11136
11727
  async function validatePlan(input) {
11137
- const { tailorDB, staticWebsite, idp, auth, pipeline, app, executor, workflow, workflowExecutionPolicy, secretManager } = input;
11728
+ const { tailorDB, staticWebsite, aiGateway, idp, auth, pipeline, app, executor, workflow, workflowExecutionPolicy, secretManager } = input;
11138
11729
  const validator = createValidator();
11139
11730
  const violations = [];
11140
11731
  function creates(schema, kind, items) {
@@ -11187,6 +11778,20 @@ async function validatePlan(input) {
11187
11778
  creates(CreateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.creates);
11188
11779
  updates(UpdateStaticWebsiteRequestSchema, "StaticWebsite", staticWebsite.changeSet.updates);
11189
11780
  creates(AddCustomDomainRequestSchema, "StaticWebsite custom domain", staticWebsite.customDomainChangeSet.creates);
11781
+ creates(CreateAIGatewayRequestSchema, "AIGateway", aiGateway.changeSet.creates.map((item) => ({
11782
+ name: item.name,
11783
+ request: {
11784
+ ...item.request,
11785
+ cors: void 0
11786
+ }
11787
+ })));
11788
+ updates(UpdateAIGatewayRequestSchema, "AIGateway", aiGateway.changeSet.updates.map((item) => ({
11789
+ name: item.name,
11790
+ request: {
11791
+ ...item.request,
11792
+ cors: void 0
11793
+ }
11794
+ })));
11190
11795
  const placeholderOriginReplacement = "https://placeholder.invalid";
11191
11796
  const substituteIdpReturnOrigins = (item) => {
11192
11797
  const request = item.request;
@@ -11972,50 +12577,25 @@ function deploymentPlanResults(deployment) {
11972
12577
  const { application: _application, ...results } = deployment;
11973
12578
  return results;
11974
12579
  }
12580
+ /**
12581
+ * Every `PlanResults` entry except `app` carries ownership-tracking fields;
12582
+ * deriving the list from `results` itself (instead of naming each key) keeps
12583
+ * these collectors in sync with `PlannedDeployment` as resource types are added.
12584
+ * @param results - Plan results for a single deployment
12585
+ * @returns The ownership-tracking plan entries, `app` excluded
12586
+ */
12587
+ function ownershipTrackedPlans(results) {
12588
+ const { app: _app, ...rest } = results;
12589
+ return Object.values(rest);
12590
+ }
11975
12591
  function collectOwnerConflicts(results) {
11976
- return [
11977
- ...results.functionRegistry.conflicts,
11978
- ...results.tailorDB.conflicts,
11979
- ...results.staticWebsite.conflicts,
11980
- ...results.aiGateway.conflicts,
11981
- ...results.idp.conflicts,
11982
- ...results.auth.conflicts,
11983
- ...results.pipeline.conflicts,
11984
- ...results.executor.conflicts,
11985
- ...results.workflow.conflicts,
11986
- ...results.workflowExecutionPolicy.conflicts,
11987
- ...results.secretManager.conflicts
11988
- ];
12592
+ return ownershipTrackedPlans(results).flatMap((plan) => plan.conflicts);
11989
12593
  }
11990
12594
  function collectUnmanagedResources(results) {
11991
- return [
11992
- ...results.functionRegistry.unmanaged,
11993
- ...results.tailorDB.unmanaged,
11994
- ...results.staticWebsite.unmanaged,
11995
- ...results.aiGateway.unmanaged,
11996
- ...results.idp.unmanaged,
11997
- ...results.auth.unmanaged,
11998
- ...results.pipeline.unmanaged,
11999
- ...results.executor.unmanaged,
12000
- ...results.workflow.unmanaged,
12001
- ...results.workflowExecutionPolicy.unmanaged,
12002
- ...results.secretManager.unmanaged
12003
- ];
12595
+ return ownershipTrackedPlans(results).flatMap((plan) => plan.unmanaged);
12004
12596
  }
12005
12597
  function collectResourceOwners(results) {
12006
- return /* @__PURE__ */ new Set([
12007
- ...results.functionRegistry.resourceOwners,
12008
- ...results.tailorDB.resourceOwners,
12009
- ...results.staticWebsite.resourceOwners,
12010
- ...results.aiGateway.resourceOwners,
12011
- ...results.idp.resourceOwners,
12012
- ...results.auth.resourceOwners,
12013
- ...results.pipeline.resourceOwners,
12014
- ...results.executor.resourceOwners,
12015
- ...results.workflow.resourceOwners,
12016
- ...results.workflowExecutionPolicy.resourceOwners,
12017
- ...results.secretManager.resourceOwners
12018
- ]);
12598
+ return new Set(ownershipTrackedPlans(results).flatMap((plan) => [...plan.resourceOwners]));
12019
12599
  }
12020
12600
  function collectImportantResourceDeletions(results) {
12021
12601
  const importantDeletions = [];
@@ -16430,62 +17010,67 @@ async function execRemove(client, workspaceId, application, config, confirm) {
16430
17010
  forRemoval: true,
16431
17011
  config
16432
17012
  };
16433
- const tailorDB = await planTailorDB(ctx);
16434
- const staticWebsite = await planStaticWebsite(ctx);
16435
- const aiGateway = await planAIGateway(ctx);
16436
- const idp = await planIdP(ctx);
16437
- const auth = await planAuth(ctx);
16438
- const pipeline = await planPipeline(ctx);
16439
- const app = await planApplication(ctx);
16440
- const executor = await planExecutor(ctx);
16441
- const workflow = await planWorkflow(client, workspaceId, application.name, application.id, {}, {});
16442
- const functionRegistry = await planFunctionRegistry(client, workspaceId, application.name, application.id, []);
16443
- const secretManager = await planSecretManager(ctx);
17013
+ const plans = {
17014
+ tailorDB: await planTailorDB(ctx),
17015
+ staticWebsite: await planStaticWebsite(ctx),
17016
+ aiGateway: await planAIGateway(ctx),
17017
+ idp: await planIdP(ctx),
17018
+ auth: await planAuth(ctx),
17019
+ pipeline: await planPipeline(ctx),
17020
+ app: await planApplication(ctx),
17021
+ executor: await planExecutor(ctx),
17022
+ workflow: await planWorkflow(client, workspaceId, application.name, application.id, {}, {}),
17023
+ workflowExecutionPolicy: await planWorkflowJobFunctionExecutionPolicy(client, workspaceId, application.name, application.id, {}),
17024
+ functionRegistry: await planFunctionRegistry(client, workspaceId, application.name, application.id, []),
17025
+ secretManager: await planSecretManager(ctx)
17026
+ };
16444
17027
  const removeLines = [
16445
- ...functionRegistry.changeSet.lines(),
16446
- ...staticWebsite.changeSet.lines(),
16447
- ...aiGateway.changeSet.lines(),
16448
- ...app.lines(),
16449
- ...tailorDB.changeSet.service.lines(),
16450
- ...tailorDB.changeSet.type.lines(),
16451
- ...tailorDB.changeSet.gqlPermission.lines(),
16452
- ...pipeline.changeSet.service.lines(),
16453
- ...pipeline.changeSet.resolver.lines(),
16454
- ...executor.changeSet.lines(),
16455
- ...workflow.changeSet.lines(),
16456
- ...idp.changeSet.service.lines(),
16457
- ...idp.changeSet.client.lines(),
16458
- ...auth.changeSet.service.lines(),
16459
- ...auth.changeSet.idpConfig.lines(),
16460
- ...auth.changeSet.userProfileConfig.lines(),
16461
- ...auth.changeSet.tenantConfig.lines(),
16462
- ...auth.changeSet.machineUser.lines(),
16463
- ...auth.changeSet.oauth2Client.lines(),
16464
- ...auth.changeSet.authHook.lines(),
16465
- ...auth.changeSet.scim.lines(),
16466
- ...auth.changeSet.scimResource.lines(),
16467
- ...auth.changeSet.connection.lines(),
16468
- ...secretManager.vaultChangeSet.lines(),
16469
- ...secretManager.secretChangeSet.lines()
17028
+ ...plans.functionRegistry.changeSet.lines(),
17029
+ ...plans.staticWebsite.changeSet.lines(),
17030
+ ...plans.aiGateway.changeSet.lines(),
17031
+ ...plans.app.lines(),
17032
+ ...plans.tailorDB.changeSet.service.lines(),
17033
+ ...plans.tailorDB.changeSet.type.lines(),
17034
+ ...plans.tailorDB.changeSet.gqlPermission.lines(),
17035
+ ...plans.pipeline.changeSet.service.lines(),
17036
+ ...plans.pipeline.changeSet.resolver.lines(),
17037
+ ...plans.executor.changeSet.lines(),
17038
+ ...plans.workflow.changeSet.lines(),
17039
+ ...plans.workflowExecutionPolicy.changeSet.lines(),
17040
+ ...plans.idp.changeSet.service.lines(),
17041
+ ...plans.idp.changeSet.client.lines(),
17042
+ ...plans.auth.changeSet.service.lines(),
17043
+ ...plans.auth.changeSet.idpConfig.lines(),
17044
+ ...plans.auth.changeSet.userProfileConfig.lines(),
17045
+ ...plans.auth.changeSet.tenantConfig.lines(),
17046
+ ...plans.auth.changeSet.machineUser.lines(),
17047
+ ...plans.auth.changeSet.oauth2Client.lines(),
17048
+ ...plans.auth.changeSet.authHook.lines(),
17049
+ ...plans.auth.changeSet.scim.lines(),
17050
+ ...plans.auth.changeSet.scimResource.lines(),
17051
+ ...plans.auth.changeSet.connection.lines(),
17052
+ ...plans.secretManager.vaultChangeSet.lines(),
17053
+ ...plans.secretManager.secretChangeSet.lines()
16470
17054
  ];
16471
17055
  if (removeLines.length > 0) logger.log(removeLines.join("\n"));
16472
- 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;
17056
+ 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;
16473
17057
  if (confirm) await confirm();
16474
- await applyWorkflow(client, workflow, "delete");
16475
- await applyExecutor(client, executor, "delete");
16476
- await applyStaticWebsite(client, staticWebsite, "delete");
16477
- await applyAIGateway(client, aiGateway, "delete");
16478
- await applyApplication(client, app, "delete");
16479
- await applyPipeline(client, pipeline, "delete-resources");
16480
- await applyPipeline(client, pipeline, "delete-services");
16481
- await applyAuth(client, auth, "delete-resources");
16482
- await applyAuth(client, auth, "delete-services");
16483
- await applyIdP(client, idp, "delete-resources");
16484
- await applyIdP(client, idp, "delete-services");
16485
- await applyTailorDB(client, tailorDB, "delete-resources");
16486
- await applyTailorDB(client, tailorDB, "delete-services");
16487
- await applyFunctionRegistry(client, workspaceId, functionRegistry, "delete");
16488
- await applySecretManager(client, secretManager, "delete");
17058
+ await applyWorkflow(client, plans.workflow, "delete");
17059
+ await applyWorkflowJobFunctionExecutionPolicy(client, plans.workflowExecutionPolicy, "delete");
17060
+ await applyExecutor(client, plans.executor, "delete");
17061
+ await applyStaticWebsite(client, plans.staticWebsite, "delete");
17062
+ await applyAIGateway(client, plans.aiGateway, "delete");
17063
+ await applyApplication(client, plans.app, "delete");
17064
+ await applyPipeline(client, plans.pipeline, "delete-resources");
17065
+ await applyPipeline(client, plans.pipeline, "delete-services");
17066
+ await applyAuth(client, plans.auth, "delete-resources");
17067
+ await applyAuth(client, plans.auth, "delete-services");
17068
+ await applyIdP(client, plans.idp, "delete-resources");
17069
+ await applyIdP(client, plans.idp, "delete-services");
17070
+ await applyTailorDB(client, plans.tailorDB, "delete-resources");
17071
+ await applyTailorDB(client, plans.tailorDB, "delete-services");
17072
+ await applyFunctionRegistry(client, workspaceId, plans.functionRegistry, "delete");
17073
+ await applySecretManager(client, plans.secretManager, "delete");
16489
17074
  }
16490
17075
  /**
16491
17076
  * Remove all resources managed by the current application.
@@ -17293,7 +17878,7 @@ async function generate(options) {
17293
17878
  if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
17294
17879
  let pluginManager;
17295
17880
  if (plugins.length > 0) pluginManager = new PluginManager(plugins);
17296
- const { defineApplication } = await import("./application-DbvD5UUz.mjs");
17881
+ const { defineApplication } = await import("./application-6zsDLGKv.mjs");
17297
17882
  const application = defineApplication({
17298
17883
  config,
17299
17884
  pluginManager
@@ -19560,5 +20145,5 @@ function isDeno() {
19560
20145
  }
19561
20146
 
19562
20147
  //#endregion
19563
- 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, isNativeTypeScriptRuntime 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 };
19564
- //# sourceMappingURL=runtime-_vUgjiqT.mjs.map
20148
+ export { getOrganization as $, multiConfigArg as $n, compareSnapshotWithRemote as $t, listCommand$3 as A, apiCall as An, getExecutorWaitFailureMessage as At, show as B, loadStoredUserTokens 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, hasAnyUserTokenEntry as Fn, startWorkflow as Ft, removeCommand$1 as G, saveUserTokens as Gn, deploy as Gt, extractOwnedNamespaces as H, platformConfigFromProfile as Hn, formatKeyValueTable as Ht, generateMigrationScript as I, hasUserTokenEntry as In, getCommand$5 as It, organizationTree as J, commonArgs as Jn, waitForExecution as Jt, updateCommand$1 as K, writePlatformConfig as Kn, ensureConfigId as Kt, writeDbTypesFile as L, loadAccessToken as Ln, getWorkflow as Lt, truncate as M, loadConfig as Mn, listExecutorJobs as Mt, truncateCommand as N, deleteUserTokens as Nn, watchExecutorJob as Nt, resumeCommand as O, generateUserTypes as On, listExecutors as Ot, generate as P, fetchLatestToken as Pn, startCommand as Pt, getCommand$1 as Q, isVerbose as Qn, parseMigrationLabelNumber as Qt, getConfiguredEditorCommand as R, loadConsoleBaseUrl 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, readPlatformConfig as Un, getCommand$6 as Ut, showCommand as V, loadWorkspaceId as Vn, functionExecutionStatusToString as Vt, remove as W, resolveUserTokenKey as Wn, getExecutor as Wt, listCommand$4 as X, confirmationArgs as Xn, MIGRATION_LABEL_KEY as Xt, treeCommand as Y, configArg as Yn, bundleMigrationScript as Yt, listOrganizations as Z, deploymentArgs as Zn, 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, pagedLogArgs as er, 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, workspaceArgs as ir, getCommand$2 as it, listWorkflows as j, assertWritable 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, resolveMachineUserInputSource as nr, 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, defineAppCommand as qn, executeScript as qt, queryCommand as r, DIFF_FILE_NAME as rn, toPageDirection as rr, listFolders as rt, removeUser as s, assertValidMigrationFiles as sn, deleteFolder as st, isNativeTypeScriptRuntime as t, protoGqlPermission as tn, paginationArgs as tr, 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, loadMachineUserName as zn, getWorkflowExecution as zt };
20149
+ //# sourceMappingURL=runtime-DlklyuHN.mjs.map