@tailor-platform/sdk 2.2.0 → 2.4.0

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 (117) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +1 -1
  3. package/dist/{application-BpLeawBg.mjs → application-C8a0UJ-z.mjs} +312 -166
  4. package/dist/application-C8a0UJ-z.mjs.map +1 -0
  5. package/dist/application-D4zOiLLa.mjs +3 -0
  6. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +47 -24
  7. package/dist/cli/commands/tailordb/migrate/generate.d.mts +6 -0
  8. package/dist/cli/commands/tailordb/migrate/rename-detection.d.mts +22 -0
  9. package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +1 -1
  10. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +30 -11
  11. package/dist/cli/commands/tailordb/truncate.d.mts +2 -2
  12. package/dist/cli/lib.mjs +2 -2
  13. package/dist/cli/lib.mjs.map +1 -1
  14. package/dist/cli/main.mjs +366 -137
  15. package/dist/cli/main.mjs.map +1 -1
  16. package/dist/cli/ts-hook.mjs +55 -8
  17. package/dist/completion/zsh-worker.zsh +38 -10
  18. package/dist/configure/config/index.d.mts +1 -1
  19. package/dist/configure/index.d.mts +3 -2
  20. package/dist/configure/index.mjs +92 -25
  21. package/dist/configure/index.mjs.map +1 -1
  22. package/dist/configure/services/aigateway/index.d.mts +5 -4
  23. package/dist/configure/services/aigateway/types.d.mts +6 -1
  24. package/dist/configure/services/auth/types.d.mts +2 -2
  25. package/dist/configure/services/index.d.mts +2 -2
  26. package/dist/configure/services/tailordb/permission.d.mts +1 -1
  27. package/dist/configure/services/tailordb/schema.d.mts +1 -1
  28. package/dist/configure/services/tailordb/types.d.mts +7 -4
  29. package/dist/configure/services/workflow/index.d.mts +2 -2
  30. package/dist/configure/services/workflow/wait-point.d.mts +72 -13
  31. package/dist/configure/types/auth-namespace-name.d.mts +18 -0
  32. package/dist/{crashreport-CINZ5dVN.mjs → crashreport-Cd4TqfZq.mjs} +1 -1
  33. package/dist/{crashreport-CIIfLnoO.mjs → crashreport-Q0pDAlrj.mjs} +8 -4
  34. package/dist/{crashreport-CIIfLnoO.mjs.map → crashreport-Q0pDAlrj.mjs.map} +1 -1
  35. package/dist/{errors-CWj21238.mjs → errors-Bxut5_Sy.mjs} +17 -3
  36. package/dist/{errors-CWj21238.mjs.map → errors-Bxut5_Sy.mjs.map} +1 -1
  37. package/dist/file-BUcmVIH2.mjs.map +1 -1
  38. package/dist/kysely/index.d.mts +2 -1
  39. package/dist/kysely/index.mjs +2 -1
  40. package/dist/kysely/index.mjs.map +1 -1
  41. package/dist/{logger-DSdExfor.mjs → logger-D0bEznPv.mjs} +9 -5
  42. package/dist/{logger-DSdExfor.mjs.map → logger-D0bEznPv.mjs.map} +1 -1
  43. package/dist/package-json-8b0O9TlX.mjs.map +1 -1
  44. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  45. package/dist/plugin/builtin/enum-constants/index.mjs +5 -5
  46. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
  47. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  48. package/dist/plugin/builtin/file-utils/index.mjs +14 -11
  49. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
  50. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  51. package/dist/plugin/builtin/kysely-type/index.mjs +9 -9
  52. package/dist/plugin/builtin/kysely-type/index.mjs.map +1 -1
  53. package/dist/plugin/builtin/seed/index.mjs +1 -1
  54. package/dist/plugin/builtin/seed/seed-type-processor.d.mts +4 -4
  55. package/dist/plugin/get-generated-type.d.mts +4 -4
  56. package/dist/plugin/index.mjs +13 -13
  57. package/dist/plugin/index.mjs.map +1 -1
  58. package/dist/plugin/types.d.mts +2 -2
  59. package/dist/plugin/with-context.d.mts +1 -1
  60. package/dist/{register-ts-hook-CTth1eqj.mjs → register-ts-hook-Vqjza10T.mjs} +2516 -857
  61. package/dist/register-ts-hook-Vqjza10T.mjs.map +1 -0
  62. package/dist/{repl-editor-BCozyiNq.mjs → repl-editor-F9LotMNx.mjs} +3 -2
  63. package/dist/{repl-editor-BCozyiNq.mjs.map → repl-editor-F9LotMNx.mjs.map} +1 -1
  64. package/dist/runtime/file.d.mts +14 -14
  65. package/dist/{schema--xYWRGfe.mjs → schema-D4TC4BC3.mjs} +4 -3
  66. package/dist/schema-D4TC4BC3.mjs.map +1 -0
  67. package/dist/seed/index.d.mts +4 -4
  68. package/dist/seed/index.mjs +3 -3
  69. package/dist/seed/index.mjs.map +1 -1
  70. package/dist/{seed-xqM9WIHP.mjs → seed-Cibjmtry.mjs} +46 -40
  71. package/dist/seed-Cibjmtry.mjs.map +1 -0
  72. package/dist/{service-goqlJJgA.mjs → service-2grcAOCJ.mjs} +61 -27
  73. package/dist/service-2grcAOCJ.mjs.map +1 -0
  74. package/dist/service-CaBPNDIZ.mjs +3 -0
  75. package/dist/{service-CCwl3Avt.mjs → service-LTfp03ZZ.mjs} +7 -5
  76. package/dist/{service-CCwl3Avt.mjs.map → service-LTfp03ZZ.mjs.map} +1 -1
  77. package/dist/types/aigateway.generated.d.mts +2 -2
  78. package/dist/types/auth.generated.d.mts +3 -3
  79. package/dist/types/executor.generated.d.mts +1 -1
  80. package/dist/types/tailordb.generated.d.mts +12 -12
  81. package/dist/utils/test/index.d.mts +4 -4
  82. package/dist/utils/test/index.mjs +4 -4
  83. package/dist/utils/test/index.mjs.map +1 -1
  84. package/dist/vitest/index.mjs +95 -7
  85. package/dist/vitest/index.mjs.map +1 -1
  86. package/dist/vitest/mocks/workflow.d.mts +13 -1
  87. package/dist/wait-point-invoker-__oE88_P.mjs +148 -0
  88. package/dist/wait-point-invoker-__oE88_P.mjs.map +1 -0
  89. package/dist/wait-point-registry-TL99zotw.mjs +47 -0
  90. package/dist/wait-point-registry-TL99zotw.mjs.map +1 -0
  91. package/docs/cli/application.md +3 -1
  92. package/docs/cli/function.md +17 -13
  93. package/docs/cli/setup.md +14 -1
  94. package/docs/cli/tailordb.md +30 -27
  95. package/docs/cli/workspace.md +2 -2
  96. package/docs/cli-reference.md +23 -22
  97. package/docs/configuration.md +2 -2
  98. package/docs/github-actions.md +73 -28
  99. package/docs/migration/v2.md +58 -4
  100. package/docs/migration/v3.md +41 -0
  101. package/docs/quickstart.md +1 -1
  102. package/docs/services/aigateway.md +33 -9
  103. package/docs/services/executor.md +5 -1
  104. package/docs/services/tailordb-migration.md +146 -44
  105. package/docs/services/tailordb.md +7 -7
  106. package/docs/services/workflow.md +52 -2
  107. package/docs/testing.md +13 -1
  108. package/package.json +8 -8
  109. package/dist/application-BpLeawBg.mjs.map +0 -1
  110. package/dist/application-BxLLiLsr.mjs +0 -3
  111. package/dist/register-ts-hook-CTth1eqj.mjs.map +0 -1
  112. package/dist/schema--xYWRGfe.mjs.map +0 -1
  113. package/dist/seed-xqM9WIHP.mjs.map +0 -1
  114. package/dist/service-_XmjSEGr.mjs +0 -3
  115. package/dist/service-goqlJJgA.mjs.map +0 -1
  116. package/dist/test-env-key-D7UkZp99.mjs +0 -75
  117. package/dist/test-env-key-D7UkZp99.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"register-ts-hook-CTth1eqj.mjs","names":["fs","semverLt","fs","CLIError","fs","CLIError","fs","CHUNK_SIZE","crypto","planServices","planServices","planServices","fs","fs","#indent","#stream","#isEnabled","#writeLine","#started","#renderFrame","#timer","#clearDrawn","#stopAndPersist","#frame","#linesDrawn","fs","fs","createWorkspace","createCommand","listCommand","CLIError","fs","nameArgs","getCommand","formatTime","setTimeout","getCommand","setTimeout","waitForExecution","listCommand","loadOptions","getCommand","loadOptions","listCommand","fs","generate","listCommand","getCommand","listCommand","deleteCommand","getCommand","listCommand","updateCommand","getCommand","listCommand","updateCommand","loadOptions","removeCommand","setTimeout","fs","mimeLookup","fs","fsPromises","fs","fsPromises","listCommand","waitForExecution","loadOptions","loadOptions","listCommand","loadOptions","loadOptions","loadOptions","loadOptions","loadOptions","loadOptions","loadOptions","CLIError","TailorDBTypeSchema","parseSql"],"sources":["../src/cli/shared/args.ts","../src/cli/shared/command.ts","../src/parser/app-config/schema.ts","../src/parser/plugin-config/schema.ts","../src/cli/shared/token-store.ts","../src/cli/shared/context.ts","../src/cli/shared/env-secret-scan.ts","../src/cli/shared/mock.ts","../src/cli/shared/config-loader.ts","../src/cli/shared/readonly-guard.ts","../src/cli/commands/api/api-call.ts","../src/cli/shared/prompt.ts","../src/cli/cache/types.ts","../src/cli/cache/store.ts","../src/cli/cache/manager.ts","../src/cli/commands/tailordb/migrate/migration-number.ts","../src/cli/shared/publish-events.ts","../src/cli/shared/type-generator.ts","../src/plugin/manager.ts","../src/cli/commands/deploy/change-set.ts","../src/cli/commands/deploy/compare.ts","../src/cli/commands/deploy/label.ts","../src/cli/commands/deploy/owned-resource.ts","../src/cli/commands/deploy/staticwebsite.ts","../src/cli/commands/deploy/aigateway.ts","../src/cli/commands/deploy/application.ts","../src/cli/commands/deploy/secrets-state.ts","../src/cli/commands/deploy/auth-connection.ts","../src/cli/commands/deploy/function-registry.ts","../src/cli/commands/deploy/grouped-display.ts","../src/parser/service/idp/permission.ts","../src/cli/commands/deploy/idp.ts","../src/cli/commands/deploy/auth.ts","../src/cli/commands/deploy/invoker.ts","../src/cli/commands/deploy/executor.ts","../src/cli/commands/deploy/resolver.ts","../src/cli/commands/deploy/secret-manager.ts","../src/cli/commands/tailordb/migrate/config.ts","../src/parser/service/tailordb/type-script.ts","../src/cli/commands/tailordb/migrate/diff-calculator.ts","../src/cli/commands/tailordb/migrate/field-type-change.ts","../src/cli/commands/tailordb/migrate/types.ts","../src/cli/commands/tailordb/migrate/snapshot-schema.ts","../src/cli/commands/tailordb/migrate/snapshot-types.ts","../src/cli/commands/tailordb/migrate/snapshot.ts","../src/cli/commands/tailordb/migrate/file-state.ts","../src/cli/commands/tailordb/migrate/snapshot-manifest.ts","../src/cli/commands/tailordb/migrate/pre-migration-schema.ts","../src/cli/commands/tailordb/migrate/remote-state.ts","../src/cli/commands/tailordb/migrate/schema-checks.ts","../src/cli/commands/tailordb/migrate/bundler.ts","../src/cli/commands/tailordb/migrate/hints.ts","../src/cli/shared/script-executor.ts","../src/cli/shared/spinner.ts","../src/cli/commands/deploy/tailordb/migration.ts","../src/cli/commands/deploy/tailordb/index.ts","../src/cli/commands/deploy/workflow.ts","../src/cli/commands/deploy/workflow-execution-policy.ts","../src/cli/commands/deploy/apply-phases.ts","../src/cli/commands/deploy/config-id-injector.ts","../src/cli/commands/deploy/confirm.ts","../src/cli/commands/deploy/dependency-records.ts","../src/cli/commands/deploy/validate-plan.ts","../src/cli/shared/profile-name.ts","../src/cli/shared/workspace-name.ts","../src/cli/shared/format.ts","../src/cli/commands/workspace/transform.ts","../src/cli/commands/workspace/create.ts","../src/cli/commands/workspace/list.ts","../src/cli/commands/deploy/workspace-context.ts","../src/cli/commands/deploy/workspace.ts","../src/cli/commands/deploy/deploy.ts","../src/cli/commands/executor/status.ts","../src/cli/commands/executor/transform.ts","../src/cli/commands/executor/get.ts","../src/cli/shared/function-execution.ts","../src/cli/shared/wait-error.ts","../src/cli/commands/workflow/args.ts","../src/cli/commands/workflow/status.ts","../src/cli/commands/workflow/transform.ts","../src/cli/commands/workflow/waiter.ts","../src/cli/commands/workflow/executions.ts","../src/cli/commands/workflow/get.ts","../src/cli/commands/workflow/start.ts","../src/cli/commands/executor/jobs.ts","../src/cli/commands/executor/list.ts","../src/cli/commands/executor/trigger.ts","../src/cli/commands/executor/webhook.ts","../src/cli/commands/function/transform.ts","../src/cli/commands/function/get.ts","../src/cli/commands/function/list.ts","../src/cli/shared/auth-input.ts","../src/cli/commands/generate/service.ts","../src/cli/commands/machineuser/list.ts","../src/cli/commands/machineuser/token.ts","../src/cli/commands/oauth2client/transform.ts","../src/cli/commands/oauth2client/get.ts","../src/cli/commands/oauth2client/list.ts","../src/cli/commands/organization/transform.ts","../src/cli/commands/organization/folder/create.ts","../src/cli/commands/organization/folder/delete.ts","../src/cli/commands/organization/folder/get.ts","../src/cli/commands/organization/folder/list.ts","../src/cli/commands/organization/folder/update.ts","../src/cli/commands/organization/get.ts","../src/cli/commands/organization/list.ts","../src/cli/commands/organization/tree.ts","../src/cli/commands/organization/update.ts","../src/cli/commands/remove.ts","../src/cli/shared/beta.ts","../src/cli/shared/config.ts","../src/cli/commands/show.ts","../src/cli/shared/progress.ts","../src/cli/commands/staticwebsite/deploy.ts","../src/cli/shared/editor.ts","../src/cli/commands/tailordb/migrate/db-types-generator.ts","../src/cli/commands/tailordb/migrate/template-generator.ts","../src/cli/commands/tailordb/migrate/script.ts","../src/cli/commands/tailordb/migrate/generate.ts","../src/cli/commands/generate/seed/bundler.ts","../src/cli/shared/seed-chunker.ts","../src/plugin/builtin/seed/seed-type-processor.ts","../src/cli/shared/tailordb-namespaces.ts","../src/cli/shared/seed-context.ts","../src/cli/shared/tailordb-namespace.ts","../src/cli/commands/tailordb/truncate.ts","../src/cli/commands/workflow/list.ts","../src/cli/commands/workflow/resume.ts","../src/cli/commands/workflow/wait.ts","../src/cli/commands/workspace/app/transform.ts","../src/cli/commands/workspace/app/health.ts","../src/cli/commands/workspace/app/list.ts","../src/cli/commands/workspace/delete.ts","../src/cli/commands/workspace/get.ts","../src/cli/commands/workspace/restore.ts","../src/cli/commands/workspace/user/transform.ts","../src/cli/commands/workspace/user/invite.ts","../src/cli/commands/workspace/user/list.ts","../src/cli/commands/workspace/user/remove.ts","../src/cli/commands/workspace/user/update.ts","../src/cli/bundler/query/query-bundler.ts","../src/cli/query/errors.ts","../src/cli/query/graphql-repl.ts","../src/cli/query/sql-repl.ts","../src/cli/query/sql-type-extractor.ts","../src/cli/query/type-field-order.ts","../src/cli/query/types.ts","../src/cli/query/index.ts","../src/cli/shared/error-json.ts","../src/cli/shared/runtime.ts","../src/cli/shared/register-ts-hook.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport { parseEnv } from \"node:util\";\nimport { PageDirection } from \"@tailor-platform/tailor-proto/resource_pb\";\nimport * as path from \"pathe\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { logger } from \"./logger\";\n\ntype ArgsShape = Record<string, z.ZodType>;\nexport type MachineUserInputSource = \"option\" | \"env\";\ntype ResolveMachineUserInputSourceOptions = {\n valueIsExplicit?: boolean;\n};\n\n// ============================================================================\n// Validators\n// ============================================================================\n\nconst durationUnits = [\"ms\", \"s\", \"m\"] as const;\ntype DurationUnit = (typeof durationUnits)[number];\n\nconst unitToMs: Record<DurationUnit, number> = {\n ms: 1,\n s: 1000,\n m: 60 * 1000,\n};\n\nconst durationPattern = /^(\\d+)(ms|s|m)$/;\n\n/**\n * Schema for duration string validation (e.g., \"3s\", \"500ms\", \"1m\")\n * Only validates format; use parseDuration() to convert to milliseconds\n */\nexport const durationArg = z\n .string()\n .refine((val) => durationPattern.test(val), {\n message: \"Invalid duration format. Expected format: '3s', '500ms', '1m'\",\n })\n .refine(\n (val) => {\n const match = val.match(durationPattern);\n if (!match) return false;\n const digits = match[1];\n return digits !== undefined && parseInt(digits, 10) > 0;\n },\n { message: \"Duration must be greater than 0\" },\n );\n\n/**\n * Parse a validated duration string into milliseconds\n * @param duration - Duration string (e.g., \"3s\", \"500ms\", \"1m\")\n * @returns Duration in milliseconds\n */\nexport function parseDuration(duration: string): number {\n const match = assertDefined(\n duration.match(durationPattern),\n `invalid duration format: ${duration}`,\n );\n const value = parseInt(assertDefined(match[1], \"duration digits group missing\"), 10);\n const unit = assertDefined(match[2], \"duration unit group missing\") as DurationUnit;\n return value * unitToMs[unit];\n}\n\n/**\n * Schema for positive integer validation (from string input)\n * Transforms the string to a number\n */\nexport const positiveIntArg = z.coerce.number().int().positive();\n\n/**\n * Schema for non-negative integer validation (from string input).\n * Accepts 0 (used for `--limit 0` to disable the limit).\n */\nexport const nonNegativeIntArg = z.coerce.number().int().nonnegative();\n\n/**\n * Schema for sort order (`asc` or `desc`).\n */\nexport const orderArg = z.enum([\"asc\", \"desc\"]);\n\nexport type Order = z.infer<typeof orderArg>;\n\n/**\n * Translate a CLI `--order` value into the proto `PageDirection` enum.\n * Returns `undefined` when the user did not specify an order so that\n * callers can omit the field and fall back to the server default.\n * @param order - Order string from CLI args (`\"asc\"` | `\"desc\"` | undefined)\n * @returns PageDirection, or undefined when `order` is undefined\n */\nexport function toPageDirection(order: Order | undefined): PageDirection | undefined {\n if (order === undefined) return undefined;\n return order === \"asc\" ? PageDirection.ASC : PageDirection.DESC;\n}\n\nfunction hasMachineUserFlag(argv: readonly string[]): boolean {\n const optionArgs = argv.slice(0, argv.indexOf(\"--\") === -1 ? argv.length : argv.indexOf(\"--\"));\n return optionArgs.some(\n (token) =>\n token === \"-m\" ||\n token.startsWith(\"-m=\") ||\n token === \"--machine-user\" ||\n token.startsWith(\"--machine-user=\") ||\n token === \"--machineUser\" ||\n token.startsWith(\"--machineUser=\") ||\n token === \"--machineuser\" ||\n token.startsWith(\"--machineuser=\"),\n );\n}\n\n/**\n * Resolve whether a parsed machine user value came from an explicit CLI option or env fallback.\n * @param machineUser - Parsed machine user value\n * @param argv - Raw CLI argv, excluding the executable and script path\n * @param options - Source resolution options\n * @returns Machine user input source, or undefined when no value was parsed\n */\nexport function resolveMachineUserInputSource(\n machineUser: string | undefined,\n argv: readonly string[] = process.argv.slice(2),\n options: ResolveMachineUserInputSourceOptions = {},\n): MachineUserInputSource | undefined {\n if (machineUser === undefined) return undefined;\n if (options.valueIsExplicit) return \"option\";\n if (hasMachineUserFlag(argv)) return \"option\";\n return process.env.TAILOR_PLATFORM_MACHINE_USER_NAME === machineUser ? \"env\" : \"option\";\n}\n\n// ============================================================================\n// Env File Helpers\n// ============================================================================\n\ntype EnvFileArg = string | string[] | undefined;\n\n/**\n * Load env files from parsed arguments.\n * Processes --env-file first, then --env-file-if-exists.\n *\n * Follows Node.js --env-file behavior:\n * - Variables already set in the environment are NOT overwritten\n * - Variables from later files override those from earlier files\n * @param envFiles - Required env file path(s) that must exist\n * @param envFilesIfExists - Optional env file path(s) that are loaded if they exist\n */\nexport function loadEnvFiles(envFiles: EnvFileArg, envFilesIfExists: EnvFileArg): void {\n // Snapshot of originally set environment variables (before loading any files)\n const originalEnvKeys = new Set(Object.keys(process.env));\n\n const load = (files: EnvFileArg, required: boolean) => {\n for (const file of [files ?? []].flat()) {\n const envPath = path.resolve(process.cwd(), file);\n if (!fs.existsSync(envPath)) {\n if (required) {\n throw new Error(`Environment file not found: ${envPath}`);\n }\n continue;\n }\n const content = fs.readFileSync(envPath, \"utf-8\");\n const parsed = parseEnv(content);\n for (const [key, value] of Object.entries(parsed)) {\n // Skip if the variable was originally set in the environment\n if (originalEnvKeys.has(key)) {\n continue;\n }\n // Allow overwriting between env files\n process.env[key] = value;\n }\n }\n };\n\n load(envFiles, true);\n load(envFilesIfExists, false);\n}\n\n// ============================================================================\n// Argument Definitions\n// ============================================================================\n\n/**\n * Common arguments for all CLI commands\n *\n * NOTE: --env-file and --env-file-if-exists collide with Node.js flags due to a bug\n * (https://github.com/nodejs/node/issues/54232). Node.js parses these even after the\n * script path, causing warnings (twice due to tsx loader).\n */\nexport const commonArgs = {\n \"env-file\": arg(z.string().optional(), {\n alias: \"e\",\n description: \"Path to the environment file (error if not found)\",\n completion: { type: \"file\", matcher: [\".env.*\", \".env\"] },\n }),\n \"env-file-if-exists\": arg(z.string().optional(), {\n description: \"Path to the environment file (ignored if not found)\",\n completion: { type: \"file\", matcher: [\".env.*\", \".env\"] },\n effect: (_value, { args }) => {\n loadEnvFiles(\n args[\"env-file\"] as string | undefined,\n args[\"env-file-if-exists\"] as string | undefined,\n );\n },\n }),\n verbose: arg(z.boolean().default(false), {\n description: \"Enable verbose logging\",\n effect: (value) => {\n verboseMode = value;\n },\n }),\n json: arg(z.boolean().default(false), {\n alias: \"j\",\n description: \"Output as JSON\",\n effect: (value) => {\n logger.jsonMode = value;\n },\n }),\n} satisfies ArgsShape;\n\n/**\n * Arguments for commands that require workspace context\n */\nexport const workspaceArgs = {\n \"workspace-id\": arg(z.string().optional(), {\n alias: \"w\",\n description: \"Workspace ID\",\n env: \"TAILOR_PLATFORM_WORKSPACE_ID\",\n completion: { type: \"none\" },\n }),\n profile: arg(z.string().optional(), {\n alias: \"p\",\n description: \"Workspace profile\",\n env: \"TAILOR_PLATFORM_PROFILE\",\n completion: { type: \"none\" },\n }),\n} satisfies ArgsShape;\n\n/**\n * Default config file path used when --config is not passed\n */\nexport const DEFAULT_CONFIG_PATH = \"tailor.config.ts\";\n\n/**\n * Format the --config argument for remediation command hints so they target\n * the same config the current run used. The `--config=<value>` form keeps a\n * leading-hyphen path bound as the option value.\n * @param {string} [configPath] - Config path the current run used, if any\n * @returns {string | undefined} `--config=<path>` argument, or undefined when the default config is in use\n */\nexport function formatConfigArg(configPath?: string): string | undefined {\n if (!configPath) return undefined;\n const relativeConfigPath = path.relative(process.cwd(), configPath);\n if (relativeConfigPath === DEFAULT_CONFIG_PATH) return undefined;\n return `--config=${relativeConfigPath}`;\n}\n\n/**\n * Shared config arg for commands that accept a config file path\n */\nexport const configArg = {\n config: arg(z.string().default(DEFAULT_CONFIG_PATH), {\n alias: \"c\",\n description: \"Path to Tailor config file\",\n env: \"TAILOR_CONFIG_PATH\",\n completion: { type: \"file\", extensions: [\"ts\"] },\n }),\n} satisfies ArgsShape;\n\n/**\n * Shared config arg for commands that accept one or more comma-separated config file paths\n */\nexport const multiConfigArg = {\n config: arg(z.string().default(DEFAULT_CONFIG_PATH), {\n alias: \"c\",\n description:\n \"Path to SDK config file. Use comma-separated paths to deploy multiple apps together.\",\n env: \"TAILOR_PLATFORM_SDK_CONFIG_PATH\",\n completion: { type: \"file\", extensions: [\"ts\"] },\n }),\n} satisfies ArgsShape;\n\n/**\n * Arguments for commands that interact with deployed resources (includes config)\n */\nexport const deploymentArgs = {\n ...workspaceArgs,\n ...configArg,\n} satisfies ArgsShape;\n\n/**\n * Arguments for commands that require confirmation\n */\nexport const confirmationArgs = {\n yes: arg(z.boolean().default(false), {\n alias: \"y\",\n description: \"Skip confirmation prompts\",\n }),\n} satisfies ArgsShape;\n\n/**\n * Arguments for commands that require organization context\n */\nexport const organizationArgs = {\n \"organization-id\": arg(z.string(), {\n alias: \"o\",\n description: \"Organization ID\",\n env: \"TAILOR_PLATFORM_ORGANIZATION_ID\",\n completion: { type: \"none\" },\n }),\n} satisfies ArgsShape;\n\n/**\n * Arguments for list commands that accept `--order` / `--limit`. Sort\n * order defaults to `desc` (newest first) because most callers want the\n * latest items; pass `--order asc` to opt in to ascending order. The\n * limit is unbounded by default so existing invocations keep returning\n * every item; pass `--limit N` to cap the result size.\n * @param defaultOrder - Default value for `--order` (defaults to `\"desc\"`)\n * @returns Argument shape suitable for spreading into a command schema\n */\nexport const paginationArgs = (defaultOrder: Order = \"desc\") =>\n ({\n order: arg(orderArg.default(defaultOrder), {\n description: \"Sort order (asc or desc)\",\n }),\n limit: arg(nonNegativeIntArg.optional(), {\n alias: \"l\",\n description: \"Maximum number of items to return (0 or omit: unlimited)\",\n }),\n }) satisfies ArgsShape;\n\n/**\n * Arguments for time-series log list commands. Defaults to newest-first\n * (`desc`) and a 50-item cap so that listing stays responsive on busy\n * workspaces. Pass `--limit 0` to disable the cap and fetch all entries.\n */\nexport const pagedLogArgs = {\n order: arg(orderArg.default(\"desc\"), {\n description: \"Sort order (asc or desc)\",\n }),\n limit: arg(nonNegativeIntArg.default(50), {\n alias: \"l\",\n description: \"Maximum number of items to return (0: unlimited)\",\n }),\n} satisfies ArgsShape;\n\n/**\n * Arguments for commands that require folder context\n */\nexport const folderArgs = {\n \"folder-id\": arg(z.string(), {\n alias: \"f\",\n description: \"Folder ID\",\n env: \"TAILOR_PLATFORM_FOLDER_ID\",\n completion: { type: \"none\" },\n }),\n} satisfies ArgsShape;\n\nexport type CommonArgsType = z.infer<z.ZodObject<typeof commonArgs>>;\n\n// Tracks verbose mode for use in global error handler (cleanup)\nlet verboseMode = false;\n\n/**\n * Returns whether verbose mode is enabled.\n * Used by the global cleanup handler which doesn't have access to parsed args.\n * @returns Whether verbose mode is enabled\n */\nexport function isVerbose(): boolean {\n return verboseMode;\n}\n","import { createDefineCommand } from \"politty\";\nimport type { CommonArgsType } from \"./args\";\n\n/**\n * defineCommand with global args type (CommonArgsType).\n * Use this for leaf commands with `run` to get type-safe access to global args.\n * Parent commands with only `subCommands` can use `defineCommand` from politty directly.\n */\nexport const defineAppCommand = createDefineCommand<CommonArgsType>();\n","import { z } from \"zod\";\nimport { LOG_LEVELS } from \"./log-level\";\n\nconst envValueSchema = z.union([z.string(), z.number(), z.boolean()]);\n\n// A boolean is never detected as a credential, so it cannot need an allowance.\nconst allowedSecretValueSchema = z.union([z.string(), z.number()]);\n\nconst envEntrySchema = z.union([\n envValueSchema,\n z.strictObject({\n value: allowedSecretValueSchema,\n allowSecretReason: z.string().min(1, {\n message: \"'allowSecretReason' must state why the value is safe to keep in 'env'.\",\n }),\n }),\n]);\n\nexport const LogLevelSchema = z.enum(LOG_LEVELS);\n\nconst logLevelSchema = z\n .string()\n .refine((value) => LogLevelSchema.safeParse(value.trim().toUpperCase()).success, {\n message: `'logLevel' must be one of: ${LOG_LEVELS.join(\", \")}.`,\n });\n\n/**\n * Structural validation schema for `defineConfig({...})`. Validates only\n * top-level fields with platform-side constraints (notably `id`); fields\n * that carry SDK builder objects (`auth`, `idp`, `db`, ...) are accepted\n * as opaque values, since their internal shapes are validated by their\n * own factory functions and parser-level schemas.\n *\n * The `id` is auto-managed by `deploy` and stored as a plain UUID. A\n * label-compatible prefix is added at the metadata boundary, so user-facing\n * configs only need to carry a UUID.\n */\nexport const AppConfigSchema = z.strictObject({\n id: z.uuid({ message: \"'id' must be a UUID.\" }).optional(),\n name: z.string().min(1, { message: \"'name' must be a non-empty string.\" }),\n env: z.record(z.string(), envEntrySchema).optional(),\n cors: z.array(z.string()).optional(),\n allowedIpAddresses: z.array(z.string()).optional(),\n disableIntrospection: z.boolean().optional(),\n inlineSourcemap: z.boolean().optional(),\n logLevel: logLevelSchema.optional(),\n db: z.unknown().optional(),\n resolver: z.unknown().optional(),\n idp: z.unknown().optional(),\n auth: z.unknown().optional(),\n executor: z.unknown().optional(),\n workflow: z.unknown().optional(),\n httpAdapter: z.unknown().optional(),\n staticWebsites: z.unknown().optional(),\n aiGateways: z.unknown().optional(),\n secrets: z.unknown().optional(),\n});\n","import { z } from \"zod\";\nimport { functionSchema } from \"#/parser/service/common\";\nimport type { Plugin } from \"#/plugin/types\";\n\n// Custom plugin schema (object form)\n// Using passthrough() to preserve additional properties on Plugin instances\nexport const PluginConfigSchema = z\n .looseObject({\n id: z.string(),\n description: z.string(),\n importPath: z.string().optional(),\n pluginConfig: z.unknown().optional(),\n typeConfigRequired: z.union([z.boolean(), functionSchema]).optional(),\n // Definition-time hooks\n onTypeLoaded: functionSchema.optional(),\n onNamespaceLoaded: functionSchema.optional(),\n // Generation-time hooks\n onTailorDBReady: functionSchema.optional(),\n onResolverReady: functionSchema.optional(),\n onExecutorReady: functionSchema.optional(),\n })\n .refine(\n (p) => {\n // importPath is required when plugin has definition-time hooks\n const hasDefineHooks = p.onTypeLoaded || p.onNamespaceLoaded;\n return !hasDefineHooks || !!p.importPath;\n },\n {\n message:\n \"importPath is required when plugin has definition-time hooks (onTypeLoaded/onNamespaceLoaded)\",\n },\n )\n .transform((plugin) => plugin as Plugin);\n","import { logger } from \"./logger\";\n\nconst SERVICE_NAME = \"tailor-platform-cli\";\n\ntype TokenData = {\n accessToken: string;\n refreshToken?: string;\n};\n\ntype EntryLike = {\n setPassword(password: string): void;\n getPassword(): string | null;\n deletePassword(): void;\n};\n\ntype EntryConstructor = new (service: string, account: string) => EntryLike;\n\nlet entryClass: EntryConstructor | false | undefined;\n\nasync function getEntryClass(): Promise<EntryConstructor | false> {\n if (entryClass !== undefined) return entryClass;\n\n try {\n const mod = await import(\"@napi-rs/keyring\");\n const probe = new mod.Entry(SERVICE_NAME, \"__probe__\");\n probe.setPassword(\"probe\");\n probe.deletePassword();\n entryClass = mod.Entry;\n } catch {\n logger.warn(\n \"System keyring is not available. Tokens will be stored in the config file. Set TAILOR_PLATFORM_TOKEN environment variable for CI environments.\",\n );\n entryClass = false;\n }\n\n return entryClass;\n}\n\n/**\n * Check whether the OS keyring is available and functional.\n * @returns true if keyring is available\n */\nexport async function isKeyringAvailable(): Promise<boolean> {\n return (await getEntryClass()) !== false;\n}\n\n/**\n * Load tokens from the OS keyring for a given account.\n * @param account - User identifier (e.g. email or client ID)\n * @returns Token data or undefined if not found or keyring unavailable\n */\nexport async function loadKeyringTokens(account: string): Promise<TokenData | undefined> {\n const Entry = await getEntryClass();\n if (!Entry) return undefined;\n\n try {\n const entry = new Entry(SERVICE_NAME, account);\n const raw = entry.getPassword();\n if (raw === null) return undefined;\n return JSON.parse(raw) as TokenData;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Save tokens to the OS keyring for a given account.\n * @param account - User identifier (e.g. email or client ID)\n * @param tokens - Token data to store\n */\nexport async function saveKeyringTokens(account: string, tokens: TokenData): Promise<void> {\n const Entry = await getEntryClass();\n if (!Entry) return;\n\n const entry = new Entry(SERVICE_NAME, account);\n entry.setPassword(JSON.stringify(tokens));\n}\n\n/**\n * Delete tokens from the OS keyring for a given account.\n * @param account - User identifier (e.g. email or client ID)\n */\nexport async function deleteKeyringTokens(account: string): Promise<void> {\n const Entry = await getEntryClass();\n if (!Entry) return;\n\n try {\n const entry = new Entry(SERVICE_NAME, account);\n entry.deletePassword();\n } catch {\n // Ignore \"not found\" errors\n }\n}\n\n/**\n * Reset the cached keyring state. Used for testing.\n */\nexport function resetKeyringState(): void {\n entryClass = undefined;\n}\n\nexport type { TokenData };\n","import * as fs from \"node:fs\";\nimport { parseYAML, stringifyYAML } from \"confbox\";\nimport { findUpSync } from \"find-up-simple\";\nimport * as path from \"pathe\";\nimport { lt as semverLt } from \"semver\";\nimport { xdgConfig } from \"xdg-basedir\";\nimport { z } from \"zod\";\nimport { assertDefined } from \"#/utils/assert\";\nimport ml from \"#/utils/multiline\";\nimport { type MachineUserInputSource } from \"./args\";\nimport {\n defaultPlatformBaseUrl,\n fetchUserInfo,\n getConsoleBaseUrl,\n getPlatformBaseUrl,\n initOAuth2Client,\n normalizeBaseUrl,\n rememberPlatformConfigForToken,\n type PlatformClientConfig,\n} from \"./client\";\nimport { CLIError } from \"./errors\";\nimport { logger } from \"./logger\";\nimport { readPackageJson } from \"./package-json\";\nimport { tightenSecretFilePermissions, writeSecretFile } from \"./secret-file\";\nimport {\n isKeyringAvailable,\n loadKeyringTokens,\n saveKeyringTokens,\n deleteKeyringTokens,\n} from \"./token-store\";\n\n// strip unknown keys\nconst pfProfileSchema = z.object({\n user: z.string(),\n workspace_id: z.string(),\n readonly: z.boolean().optional(),\n machine_user: z.string().optional(),\n machine_user_override: z.enum([\"allow\", \"deny\"]).optional(),\n platform_url: z.url().optional(),\n oauth2_client_id: z.string().optional(),\n console_url: z.url().optional(),\n});\n\n// strip unknown keys\nconst pfUserSchemaV1 = z.object({\n access_token: z.string(),\n refresh_token: z.string().optional(),\n token_expires_at: z.string(),\n});\n\n// strip unknown keys\nconst pfUserKeyringSchema = z.object({\n storage: z.literal(\"keyring\"),\n token_expires_at: z.string(),\n});\n\n// strip unknown keys\nconst pfUserFileSchema = z.object({\n storage: z.literal(\"file\"),\n token_expires_at: z.string(),\n access_token: z.string(),\n refresh_token: z.string().optional(),\n});\n\nconst pfUserSchemaV2 = z.discriminatedUnion(\"storage\", [pfUserKeyringSchema, pfUserFileSchema]);\n\nconst pfUserKeyringSchemaV3 = pfUserKeyringSchema.extend({\n email: z.string().optional(),\n});\n\nconst pfUserFileSchemaV3 = pfUserFileSchema.extend({\n email: z.string().optional(),\n});\n\nconst pfUserSchemaV3 = z.discriminatedUnion(\"storage\", [pfUserKeyringSchemaV3, pfUserFileSchemaV3]);\n\n// strip unknown keys\nconst pfConfigSchemaV1 = z.object({\n version: z.literal(1),\n users: z.partialRecord(z.string(), pfUserSchemaV1),\n profiles: z.partialRecord(z.string(), pfProfileSchema),\n current_user: z.string().nullable(),\n});\n\nconst V2_CONFIG_VERSION = 2;\nconst LATEST_CONFIG_VERSION = 3;\nconst V2_MIN_SDK_VERSION = \"1.29.0\";\nconst V3_MIN_SDK_VERSION = \"2.0.0\";\n\nconst semverSchema = z.templateLiteral([\n z.number().int(),\n \".\",\n z.number().int(),\n \".\",\n z.number().int(),\n]);\n\n// strip unknown keys\nconst pfConfigSchemaV2 = z.object({\n version: z.literal(V2_CONFIG_VERSION),\n min_sdk_version: semverSchema,\n latest_version: z.number().int().optional(),\n latest_min_sdk_version: semverSchema.optional(),\n users: z.partialRecord(z.string(), pfUserSchemaV2),\n profiles: z.partialRecord(z.string(), pfProfileSchema),\n current_user: z.string().nullable(),\n});\n\n// strip unknown keys\nconst pfConfigSchemaV3 = z.object({\n version: z.literal(LATEST_CONFIG_VERSION),\n min_sdk_version: semverSchema,\n latest_version: z.number().int().optional(),\n latest_min_sdk_version: semverSchema.optional(),\n users: z.partialRecord(z.string(), pfUserSchemaV3),\n profiles: z.partialRecord(z.string(), pfProfileSchema),\n current_user: z.string().nullable(),\n});\n\ntype PfConfigV1 = z.output<typeof pfConfigSchemaV1>;\ntype PfConfigV2 = z.output<typeof pfConfigSchemaV2>;\ntype PfConfig = z.output<typeof pfConfigSchemaV3>;\ntype PfUser = z.output<typeof pfUserSchemaV3>;\ntype UserTokens = { accessToken: string; refreshToken?: string };\ntype PfConfigV3 = PfConfig;\ntype LoadWorkspaceIdOptions = {\n workspaceId?: string;\n profile?: string;\n};\ntype LoadAccessTokenOptions = {\n profile?: string;\n};\ntype LoadPlatformClientConfigOptions = {\n profile?: string;\n allowMissingProfile?: boolean;\n};\ntype LoadConsoleBaseUrlOptions = {\n profile?: string;\n allowMissingProfile?: boolean;\n};\ntype LoadMachineUserNameOptions = {\n machineUser?: string;\n machineUserSource?: MachineUserInputSource;\n profile?: string;\n};\ntype ExplicitMachineUser = {\n source: MachineUserInputSource;\n value: string;\n};\n\nfunction platformConfigPath() {\n if (!xdgConfig) {\n throw new Error(\"User home directory not found\");\n }\n return path.join(xdgConfig, \"tailor-platform\", \"config.yaml\");\n}\n\ntype ProfilePlatformSettings = {\n platform_url?: string;\n oauth2_client_id?: string;\n console_url?: string;\n};\n\n/**\n * Convert stored profile platform fields to platform client settings.\n * @param profile - Profile platform settings\n * @returns Platform client settings\n */\nexport function platformConfigFromProfile(\n profile: ProfilePlatformSettings | undefined,\n): PlatformClientConfig | undefined {\n const config = {\n ...(profile?.platform_url ? { platformUrl: profile.platform_url } : {}),\n ...(profile?.oauth2_client_id ? { oauth2ClientId: profile.oauth2_client_id } : {}),\n ...(profile?.console_url ? { consoleUrl: profile.console_url } : {}),\n };\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\nfunction platformUserKey(user: string, config?: PlatformClientConfig): string {\n const platformUrl = getPlatformBaseUrl(config);\n if (platformUrl === normalizeBaseUrl(defaultPlatformBaseUrl)) {\n return user;\n }\n return `${platformUrl}|${user}`;\n}\n\nfunction userFromPlatformUserKey(userKey: string, config?: PlatformClientConfig): string {\n const platformPrefix = `${getPlatformBaseUrl(config)}|`;\n return userKey.startsWith(platformPrefix) ? userKey.slice(platformPrefix.length) : userKey;\n}\n\nfunction canUseLegacyUserKey(platformUrl: string): boolean {\n try {\n return getPlatformBaseUrl() === platformUrl;\n } catch {\n return false;\n }\n}\n\ntype UserEntryLookupOptions = {\n allowLegacyUserKey?: boolean;\n};\n\nfunction findUserByEmail(\n users: PfConfig[\"users\"],\n email: string,\n platformConfig?: PlatformClientConfig,\n) {\n const platformUrl = getPlatformBaseUrl(platformConfig);\n const platformPrefix = `${platformUrl}|`;\n const defaultPlatform = platformUrl === normalizeBaseUrl(defaultPlatformBaseUrl);\n return Object.entries(users).find(([key, entry]) => {\n if (entry?.email !== email) return false;\n return defaultPlatform ? !key.includes(\"|\") : key.startsWith(platformPrefix);\n });\n}\n\nfunction findUserEntry(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n opts: UserEntryLookupOptions = {},\n) {\n const userKey = platformUserKey(user, platformConfig);\n const userEntry = config.users[userKey];\n if (userEntry) {\n return { userKey, userEntry };\n }\n const emailMatch = findUserByEmail(config.users, user, platformConfig);\n if (emailMatch?.[1]) {\n return { userKey: emailMatch[0], userEntry: emailMatch[1] };\n }\n const platformUrl = getPlatformBaseUrl(platformConfig);\n if (\n userKey !== user &&\n (opts.allowLegacyUserKey === false || !canUseLegacyUserKey(platformUrl))\n ) {\n return { userKey, userEntry };\n }\n const legacyEntry = config.users[user];\n return legacyEntry ? { userKey: user, userEntry: legacyEntry } : { userKey, userEntry };\n}\n\n/**\n * Resolve the config user key that would be used for a user on the selected platform.\n * @param config - Platform config\n * @param user - User name\n * @param platformConfig - Optional platform connection settings\n * @param opts - Token lookup options\n * @returns Resolved config user key\n */\nexport function resolveUserTokenKey(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n opts?: UserEntryLookupOptions,\n): string {\n return findUserEntry(config, user, platformConfig, opts).userKey;\n}\n\nexport function resolveConfigUser(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n opts?: UserEntryLookupOptions,\n): string | undefined {\n const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);\n return userEntry ? userFromPlatformUserKey(userKey, platformConfig) : undefined;\n}\n\n/**\n * Check whether tokens are registered for a user on the selected platform.\n * @param config - Platform config\n * @param user - User name\n * @param platformConfig - Optional platform connection settings\n * @param opts - Token lookup options\n * @returns True when the user has a registered token entry\n */\nexport function hasUserTokenEntry(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n opts?: UserEntryLookupOptions,\n): boolean {\n return findUserEntry(config, user, platformConfig, opts).userEntry !== undefined;\n}\n\nfunction hasUserKeyForName(users: Record<string, unknown>, user: string): boolean {\n return users[user] !== undefined || Object.keys(users).some((key) => key.endsWith(`|${user}`));\n}\n\nfunction hasUserEmailEntry(users: PfConfig[\"users\"], user: string): boolean {\n return Object.values(users).some((entry) => entry?.email === user);\n}\n\n/**\n * Check whether any platform has tokens registered for a user.\n * @param config - Platform config\n * @param user - User name\n * @returns True when the user has a token entry for any platform\n */\nexport function hasAnyUserTokenEntry(config: Pick<PfConfig, \"users\">, user: string): boolean {\n return hasUserKeyForName(config.users, user) || hasUserEmailEntry(config.users, user);\n}\n\nfunction hasCurrentUserEntry(users: PfConfigV1[\"users\"], currentUser: string): boolean {\n return hasUserKeyForName(users, currentUser);\n}\n\n/**\n * Migrate a v1 config to v2.\n * Tokens are kept in the config file (storage: \"file\") during migration.\n * They will be moved to the OS keyring on next login or token refresh.\n * @param v1Config - v1 configuration to migrate\n * @returns Migrated v2 configuration\n */\nfunction migrateV1ToV2(v1Config: PfConfigV1): PfConfigV2 {\n const users: PfConfigV2[\"users\"] = {};\n\n for (const [name, v1User] of Object.entries(v1Config.users)) {\n if (!v1User) continue;\n\n users[name] = {\n access_token: v1User.access_token,\n refresh_token: v1User.refresh_token,\n token_expires_at: v1User.token_expires_at,\n storage: \"file\",\n };\n }\n\n return {\n version: V2_CONFIG_VERSION,\n min_sdk_version: V2_MIN_SDK_VERSION,\n users,\n profiles: v1Config.profiles,\n current_user: v1Config.current_user,\n };\n}\n\nfunction inferEmailFromUserId(user: string): string | undefined {\n return z.email().safeParse(user).success ? user : undefined;\n}\n\nfunction migrateV2ToV3(v2Config: PfConfigV2): PfConfig {\n const users: PfConfig[\"users\"] = {};\n\n for (const [user, entry] of Object.entries(v2Config.users)) {\n if (!entry) continue;\n const email = inferEmailFromUserId(user);\n users[user] = {\n ...entry,\n ...(email ? { email } : {}),\n };\n }\n\n return {\n version: LATEST_CONFIG_VERSION,\n min_sdk_version: V3_MIN_SDK_VERSION,\n users,\n profiles: v2Config.profiles,\n current_user: v2Config.current_user,\n };\n}\n\nfunction migrateV1ToV3(v1Config: PfConfigV1): PfConfig {\n return migrateV2ToV3(migrateV1ToV2(v1Config));\n}\n\nfunction formatUnknownError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nasync function trySaveTokensInKeyring(user: string, tokens: UserTokens): Promise<boolean> {\n if (!(await isKeyringAvailable())) return false;\n try {\n await saveKeyringTokens(user, tokens);\n return true;\n } catch (error) {\n logger.warn(\n `System keyring failed to store credentials. Tokens will be stored in the config file. ${formatUnknownError(error)}`,\n );\n return false;\n }\n}\n\nasync function warnIfNewerConfigAvailable(config: {\n latest_version?: number;\n latest_min_sdk_version?: string;\n}) {\n if (!config.latest_min_sdk_version) return;\n const packageJson = await readPackageJson();\n const sdkVersion = packageJson.version ?? \"0.0.0\";\n if (semverLt(sdkVersion, config.latest_min_sdk_version)) {\n logger.warn(ml`\n A newer config version (${String(config.latest_version)}) is available.\n Please update your SDK to >= ${config.latest_min_sdk_version}: pnpm update @tailor-platform/sdk\n `);\n }\n}\n\n/**\n * Read Tailor Platform CLI configuration, migrating from v1 if necessary.\n * @returns Parsed platform configuration\n */\nexport async function readPlatformConfig(): Promise<PfConfig> {\n const configPath = platformConfigPath();\n\n if (!fs.existsSync(configPath)) {\n const config: PfConfig = {\n version: LATEST_CONFIG_VERSION,\n min_sdk_version: V3_MIN_SDK_VERSION,\n users: {},\n profiles: {},\n current_user: null,\n };\n writePlatformConfig(config);\n return config;\n }\n\n const rawConfig = parseYAML(fs.readFileSync(configPath, \"utf-8\"));\n\n // Legacy installs may have left the config world-readable (umask default\n // 0o644). Tighten it here so users who only run read-only commands still\n // get the secret-file permissions applied without waiting for a write.\n tightenSecretFilePermissions(configPath);\n\n // Check for unsupported future versions\n const version =\n rawConfig != null && typeof rawConfig === \"object\" && \"version\" in rawConfig\n ? (rawConfig as { version: unknown }).version\n : undefined;\n if (typeof version === \"number\" && version > LATEST_CONFIG_VERSION) {\n const minSdk =\n \"min_sdk_version\" in (rawConfig as object)\n ? String((rawConfig as { min_sdk_version: unknown }).min_sdk_version)\n : undefined;\n const updateHint = minSdk\n ? `Please update your SDK to >= ${minSdk}: pnpm update @tailor-platform/sdk`\n : \"Please update your SDK: pnpm update @tailor-platform/sdk\";\n throw new Error(ml`\n Config file uses version ${String(version)}, but this SDK only supports up to version ${String(LATEST_CONFIG_VERSION)}.\n ${updateHint}\n `);\n }\n\n // Try v3 first\n const v3Result = pfConfigSchemaV3.safeParse(rawConfig);\n if (v3Result.success) {\n await warnIfNewerConfigAvailable(v3Result.data);\n return v3Result.data;\n }\n\n // Try v2 next\n const v2Result = pfConfigSchemaV2.safeParse(rawConfig);\n if (v2Result.success) {\n await warnIfNewerConfigAvailable(v2Result.data);\n return migrateV2ToV3(v2Result.data);\n }\n\n // Fall back to v1 (convert to v3 in memory, but don't rewrite disk)\n const v1Result = pfConfigSchemaV1.safeParse(rawConfig);\n if (v1Result.success) {\n return migrateV1ToV3(v1Result.data);\n }\n\n // Neither v1, v2, nor v3\n throw new Error(ml`\n Failed to parse config file at ${configPath}.\n The file may be corrupted or created by an incompatible SDK version.\n `);\n}\n\nfunction toV1ForDisk(config: PfConfigV2): PfConfigV1 {\n const users: PfConfigV1[\"users\"] = {};\n for (const [name, entry] of Object.entries(config.users)) {\n if (!entry || entry.storage === \"keyring\") continue;\n users[name] = {\n access_token: entry.access_token,\n refresh_token: entry.refresh_token,\n token_expires_at: entry.token_expires_at,\n };\n }\n const currentUser =\n config.current_user && hasCurrentUserEntry(users, config.current_user)\n ? config.current_user\n : null;\n return {\n version: 1,\n users,\n profiles: config.profiles,\n current_user: currentUser,\n };\n}\n\nfunction hasProfilePlatformSettings(config: Pick<PfConfig | PfConfigV1, \"profiles\">): boolean {\n return Object.values(config.profiles).some(\n (profile) =>\n profile?.platform_url !== undefined ||\n profile?.oauth2_client_id !== undefined ||\n profile?.console_url !== undefined,\n );\n}\n\nfunction hasScopedUserKeys(config: Pick<PfConfig | PfConfigV1, \"users\">): boolean {\n return Object.keys(config.users).some((userKey) => userKey.includes(\"|\"));\n}\n\nfunction hasUserEmailMetadata(config: Pick<PfConfig | PfConfigV1, \"users\">): boolean {\n return Object.values(config.users).some(\n (user) => user != null && \"email\" in user && user.email !== undefined,\n );\n}\n\nfunction toLatestForDisk(config: PfConfig | PfConfigV2 | PfConfigV1): PfConfigV3 {\n const latestInput = config.version === 1 ? migrateV1ToV2(config) : config;\n return {\n ...latestInput,\n version: LATEST_CONFIG_VERSION,\n min_sdk_version: V3_MIN_SDK_VERSION,\n };\n}\n\n/**\n * Write Tailor Platform CLI configuration to disk.\n * By default, file-backed configs without newer fields are converted to V1 for\n * backward compatibility, so an older SDK can still read the file. Configs\n * containing a keyring user are kept in V2 or later because the keyring storage\n * variant is not representable in V1. Configs containing profile-level Platform\n * settings, platform-scoped user tokens, canonical user IDs, or email metadata\n * are written in the latest min-SDK-gated format because older SDKs would\n * silently drop or misread those settings.\n *\n * The config file may contain access/refresh tokens when the OS keyring is\n * unavailable, so it is written via {@link writeSecretFile} so other users\n * on the host cannot read it.\n * @param config - Platform configuration to write\n */\nexport function writePlatformConfig(config: PfConfig | PfConfigV2 | PfConfigV1) {\n const configPath = platformConfigPath();\n const hasKeyringUser =\n config.version !== 1 && Object.values(config.users).some((u) => u?.storage === \"keyring\");\n const diskConfig =\n config.version === LATEST_CONFIG_VERSION ||\n hasProfilePlatformSettings(config) ||\n hasScopedUserKeys(config) ||\n hasUserEmailMetadata(config)\n ? toLatestForDisk(config)\n : config.version === V2_CONFIG_VERSION && !hasKeyringUser\n ? toV1ForDisk(config)\n : config;\n writeSecretFile(configPath, stringifyYAML(diskConfig));\n}\n\nfunction validateUUID(value: string, source: string): string {\n const result = z.uuid().safeParse(value);\n if (!result.success) {\n throw new Error(`Invalid value from ${source}: must be a valid UUID`);\n }\n return result.data;\n}\n\n/**\n * Load workspace ID from command options, environment variables, or platform config.\n * In CLI context, env fallback is also handled by politty's arg env option.\n * Priority: opts/workspaceId > env/workspaceId > opts/profile > error\n * @param opts - Workspace and profile options\n * @returns Resolved workspace ID\n */\nexport async function loadWorkspaceId(opts?: LoadWorkspaceIdOptions): Promise<string> {\n const workspaceId = await tryLoadWorkspaceId(opts);\n if (workspaceId) return workspaceId;\n\n throw new Error(ml`\n Workspace ID not found.\n Please specify workspace ID via --workspace-id option or TAILOR_PLATFORM_WORKSPACE_ID environment variable.\n `);\n}\n\n/**\n * Load a workspace ID when one is explicitly configured.\n * @param opts - Workspace and profile options\n * @returns Resolved workspace ID, or undefined when no source is configured\n */\nexport async function tryLoadWorkspaceId(\n opts?: LoadWorkspaceIdOptions,\n): Promise<string | undefined> {\n const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;\n\n if (opts?.workspaceId !== undefined) {\n return validateUUID(opts.workspaceId, \"--workspace-id option\");\n }\n\n if (process.env.TAILOR_PLATFORM_WORKSPACE_ID) {\n return validateUUID(\n process.env.TAILOR_PLATFORM_WORKSPACE_ID,\n \"TAILOR_PLATFORM_WORKSPACE_ID environment variable\",\n );\n }\n\n if (profile) {\n const pfConfig = await readPlatformConfig();\n const profileEntry = pfConfig.profiles[profile];\n const wsId = profileEntry?.workspace_id;\n if (!wsId) {\n throw new Error(`Profile \"${profile}\" not found`);\n }\n return validateUUID(wsId, `profile \"${profile}\"`);\n }\n\n return undefined;\n}\n\n/**\n * Load machine user name from command options, environment variables, or platform config.\n * In CLI context, env fallback is also handled by politty's arg env option.\n * Priority: opts/machineUser > env/TAILOR_PLATFORM_MACHINE_USER_NAME > opts/profile (profile default) > undefined.\n * 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.\n * 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`.\n * @param opts - Machine user and profile options\n * @returns Resolved machine user name, or undefined if not set\n */\nexport async function loadMachineUserName(\n opts?: LoadMachineUserNameOptions,\n): Promise<string | undefined> {\n if (opts?.machineUser === \"\") {\n throw CLIError({\n code: \"MACHINE_USER_NAME_EMPTY\",\n message: \"Machine user name cannot be empty.\",\n suggestion:\n \"Pass a non-empty machine user name, or omit the option to use the environment variable or profile default.\",\n });\n }\n\n const envMachineUser = process.env.TAILOR_PLATFORM_MACHINE_USER_NAME || undefined;\n const explicitMachineUser: ExplicitMachineUser | undefined = opts?.machineUser\n ? {\n source: opts.machineUserSource ?? \"option\",\n value: opts.machineUser,\n }\n : envMachineUser\n ? { source: \"env\", value: envMachineUser }\n : undefined;\n const explicit = explicitMachineUser?.value;\n\n const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;\n if (!profile) return explicit;\n\n const pfConfig = await readPlatformConfig();\n const entry = pfConfig.profiles[profile];\n if (!entry) {\n if (explicit) return explicit;\n throw new Error(`Profile \"${profile}\" not found`);\n }\n\n if (entry.machine_user && entry.machine_user_override === \"deny\") {\n if (explicit && explicit !== entry.machine_user) {\n const details =\n explicitMachineUser.source === \"env\"\n ? `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}\".`\n : `This profile fixes the machine user to \"${entry.machine_user}\" for application-data commands.`;\n throw CLIError({\n code: \"PROFILE_MACHINE_USER_OVERRIDE_DENIED\",\n message: `Profile \"${profile}\" denies overriding the machine user.`,\n details,\n suggestion: `Omit the machine user option, unset TAILOR_PLATFORM_MACHINE_USER_NAME, or run 'tailor profile update ${profile} --machine-user-override allow'.`,\n });\n }\n return entry.machine_user;\n }\n\n return explicit || entry.machine_user;\n}\n\n/**\n * Load access token from environment variables, command options, or platform config.\n * In CLI context, profile env fallback is also handled by politty's arg env option.\n * Priority: env/TAILOR_PLATFORM_TOKEN > env/TAILOR_TOKEN (deprecated) > opts/profile > env/profile > config/currentUser > error\n * @param opts - Profile options\n * @returns Resolved access token\n */\nexport async function loadAccessToken(opts?: LoadAccessTokenOptions) {\n const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;\n const envToken = process.env.TAILOR_PLATFORM_TOKEN ?? process.env.TAILOR_TOKEN;\n if (envToken && !process.env.TAILOR_PLATFORM_TOKEN) {\n logger.warn(\"TAILOR_TOKEN is deprecated. Please use TAILOR_PLATFORM_TOKEN instead.\");\n }\n\n if (envToken) {\n const platformConfig = await loadPlatformClientConfig({ profile, allowMissingProfile: true });\n rememberPlatformConfigForToken(envToken, platformConfig);\n return envToken;\n }\n\n const pfConfig = await readPlatformConfig();\n const profileEntry = profile ? pfConfig.profiles[profile] : undefined;\n if (profile && !profileEntry) {\n throw new Error(`Profile \"${profile}\" not found`);\n }\n const user = profileEntry?.user ?? pfConfig.current_user;\n if (!user) {\n throw new Error(ml`\n Tailor Platform token not found.\n Please specify token via TAILOR_PLATFORM_TOKEN environment variable or login using 'tailor login' command.\n `);\n }\n const fromProfile = profileEntry ? platformConfigFromProfile(profileEntry) : undefined;\n return (await fetchLatestToken(pfConfig, user, fromProfile)).accessToken;\n}\n\n/**\n * Load platform connection settings from the active profile.\n * @param opts - Profile options\n * @returns Resolved platform connection settings, or undefined for the default environment\n */\nexport async function loadPlatformClientConfig(\n opts?: LoadPlatformClientConfigOptions,\n): Promise<PlatformClientConfig | undefined> {\n const profile = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;\n if (!profile) {\n return undefined;\n }\n\n let pfConfig: PfConfig;\n try {\n pfConfig = await readPlatformConfig();\n } catch (error) {\n if (opts?.allowMissingProfile) {\n return undefined;\n }\n throw error;\n }\n const profileEntry = pfConfig.profiles[profile];\n if (!profileEntry) {\n if (opts?.allowMissingProfile) {\n return undefined;\n }\n throw new Error(`Profile \"${profile}\" not found`);\n }\n return platformConfigFromProfile(profileEntry);\n}\n\n/**\n * Load the Tailor Platform Console base URL from environment variables or the active profile.\n * @param opts - Profile options\n * @returns Resolved Console base URL\n */\nexport async function loadConsoleBaseUrl(opts?: LoadConsoleBaseUrlOptions): Promise<string> {\n const platformConfig = await loadPlatformClientConfig(opts);\n return getConsoleBaseUrl(platformConfig);\n}\n\n/**\n * Resolve the actual token values for a user, reading from keyring or config as appropriate.\n * @param userEntry - User entry from the config\n * @param user - User identifier\n * @param label - User-facing identifier used in error messages\n * @returns Access token and optional refresh token\n */\nexport async function resolveTokens(\n userEntry: PfUser,\n user: string,\n label = user,\n): Promise<{ accessToken: string; refreshToken?: string }> {\n if (userEntry.storage === \"keyring\") {\n const tokens = await loadKeyringTokens(user);\n if (!tokens) {\n throw new Error(ml`\n Credentials not found in OS keyring for \"${label}\".\n Please run 'tailor login' and try again.\n `);\n }\n return tokens;\n }\n\n return {\n accessToken: userEntry.access_token,\n refreshToken: userEntry.refresh_token,\n };\n}\n\n/**\n * Save tokens for a user, writing to keyring by default when available.\n * @param config - Platform config\n * @param user - User identifier\n * @param tokens - Token data to save\n * @param tokens.accessToken - Access token to save\n * @param tokens.refreshToken - Optional refresh token to save\n * @param expiresAt - Token expiration date\n * @param opts - Optional platform and user metadata\n */\nexport async function saveUserTokens(\n config: PfConfig,\n user: string,\n tokens: UserTokens,\n expiresAt: string,\n opts: { platformConfig?: PlatformClientConfig; email?: string } = {},\n): Promise<void> {\n const userKey = platformUserKey(user, opts.platformConfig);\n const email = opts.email ?? config.users[userKey]?.email;\n if (await trySaveTokensInKeyring(userKey, tokens)) {\n config.users[userKey] = {\n token_expires_at: expiresAt,\n storage: \"keyring\",\n ...(email ? { email } : {}),\n };\n } else {\n if (config.users[userKey]?.storage === \"keyring\") {\n await deleteKeyringTokens(userKey);\n }\n config.users[userKey] = {\n access_token: tokens.accessToken,\n refresh_token: tokens.refreshToken,\n token_expires_at: expiresAt,\n storage: \"file\",\n ...(email ? { email } : {}),\n };\n }\n}\n\n/**\n * Delete tokens for a user from keyring if applicable.\n * @param config - Platform config\n * @param user - User identifier\n * @param platformConfig - Optional platform connection settings\n * @param opts - Token lookup options\n */\nexport async function deleteUserTokens(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n opts?: UserEntryLookupOptions,\n): Promise<void> {\n const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);\n if (userEntry?.storage === \"keyring\") {\n await deleteKeyringTokens(userKey);\n }\n delete config.users[userKey];\n}\n\n/**\n * Resolve stored tokens for a user on the selected platform.\n * @param config - Platform config\n * @param user - User name\n * @param platformConfig - Optional platform connection settings\n * @param opts - Token lookup options\n * @returns Stored user entry and token values, or undefined when the user is not logged in\n */\nexport async function loadStoredUserTokens(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n opts?: UserEntryLookupOptions,\n): Promise<\n | {\n userEntry: PfUser;\n accessToken: string;\n refreshToken?: string;\n }\n | undefined\n> {\n const { userKey, userEntry } = findUserEntry(config, user, platformConfig, opts);\n if (!userEntry) return undefined;\n const tokens = await resolveTokens(userEntry, userKey, user);\n return { userEntry, ...tokens };\n}\n\nfunction updateUserReferences(config: PfConfig, fromUser: string, toUser: string) {\n if (fromUser === toUser) return;\n if (config.current_user === fromUser) {\n config.current_user = toUser;\n }\n for (const profile of Object.values(config.profiles)) {\n if (profile?.user === fromUser) {\n profile.user = toUser;\n }\n }\n}\n\n/**\n * Remove a legacy alias after a canonical user ID has been written.\n * @param config - Platform config\n * @param legacyUser - Previous user key\n * @param canonicalUser - Canonical user key\n * @param platformConfig - Platform settings for scoped token storage\n */\nexport async function removeLegacyUserAlias(\n config: PfConfig,\n legacyUser: string,\n canonicalUser: string,\n platformConfig?: PlatformClientConfig,\n): Promise<void> {\n if (legacyUser === canonicalUser) return;\n updateUserReferences(config, legacyUser, canonicalUser);\n const canonicalKey = platformUserKey(canonicalUser, platformConfig);\n const legacyKeys = new Set([legacyUser, platformUserKey(legacyUser, platformConfig)]);\n for (const legacyKey of legacyKeys) {\n if (legacyKey === canonicalKey) continue;\n const entry = config.users[legacyKey];\n if (entry?.storage === \"keyring\") {\n await deleteKeyringTokens(legacyKey);\n }\n delete config.users[legacyKey];\n }\n}\n\nfunction shouldResolveSubjectOnRefresh(user: string, userEntry: PfUser): boolean {\n return Boolean(userEntry.email || inferEmailFromUserId(user));\n}\n\n/**\n * Fetch the latest access token, refreshing if necessary.\n * @param config - Platform config\n * @param user - User identifier\n * @param platformConfig - Optional platform connection settings\n * @returns Latest access token and the canonical user ID it is stored under\n * (the resolved subject when a legacy email key was migrated during refresh,\n * otherwise the matching config user)\n */\nexport async function fetchLatestToken(\n config: PfConfig,\n user: string,\n platformConfig?: PlatformClientConfig,\n): Promise<{ accessToken: string; user: string }> {\n const { userKey: storedUser, userEntry } = findUserEntry(config, user, platformConfig);\n if (!userEntry) {\n throw new Error(ml`\n User \"${user}\" not found.\n Please verify your user name and login using 'tailor login' command.\n `);\n }\n\n const storedConfigUser = userFromPlatformUserKey(storedUser, platformConfig);\n const tokens = await resolveTokens(userEntry, storedUser, user);\n\n if (new Date(userEntry.token_expires_at) > new Date()) {\n rememberPlatformConfigForToken(tokens.accessToken, platformConfig);\n return { accessToken: tokens.accessToken, user: storedConfigUser };\n }\n\n if (!tokens.refreshToken) {\n throw new Error(ml`\n Token expired.\n Please run 'tailor login' and try again.\n `);\n }\n\n const client = initOAuth2Client(platformConfig);\n let resp;\n try {\n resp = await client.refreshToken({\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken,\n expiresAt: Date.parse(userEntry.token_expires_at),\n });\n } catch {\n throw new Error(ml`\n Failed to refresh token. Your session may have expired.\n Please run 'tailor login' and try again.\n `);\n }\n\n const newExpiresAt = new Date(\n assertDefined(resp.expiresAt, \"token refresh response missing expiresAt\"),\n ).toISOString();\n\n let resolvedUser = storedConfigUser;\n const previousEmail =\n userEntry.email ?? inferEmailFromUserId(user) ?? inferEmailFromUserId(storedConfigUser);\n let email = previousEmail;\n if (\n shouldResolveSubjectOnRefresh(user, userEntry) ||\n shouldResolveSubjectOnRefresh(storedConfigUser, userEntry)\n ) {\n try {\n const userInfo = await fetchUserInfo(resp.accessToken, platformConfig);\n resolvedUser = userInfo.sub;\n email = userInfo.email;\n } catch (error) {\n logger.debug(`Failed to resolve refreshed token user info: ${String(error)}`);\n }\n }\n\n await saveUserTokens(\n config,\n resolvedUser,\n {\n accessToken: resp.accessToken,\n refreshToken: resp.refreshToken ?? undefined,\n },\n newExpiresAt,\n { platformConfig, email },\n );\n await removeLegacyUserAlias(config, user, resolvedUser, platformConfig);\n const canonicalKey = platformUserKey(resolvedUser, platformConfig);\n if (storedUser !== canonicalKey) {\n const entry = config.users[storedUser];\n if (entry?.storage === \"keyring\") {\n await deleteKeyringTokens(storedUser);\n }\n delete config.users[storedUser];\n }\n if (previousEmail && email && previousEmail !== email) {\n logger.info(`Updated local user email from \"${previousEmail}\" to \"${email}\".`);\n }\n writePlatformConfig(config);\n rememberPlatformConfigForToken(resp.accessToken, platformConfig);\n return { accessToken: resp.accessToken, user: resolvedUser };\n}\n\nconst DEFAULT_CONFIG_FILENAME = \"tailor.config.ts\";\n\n/**\n * Load config path from command options, environment variables, or search parent directories.\n * In CLI context, env fallback is also handled by politty's arg env option.\n * Priority: opts/config > env/config > search parent directories\n * @param configPath - Optional explicit config path\n * @returns Resolved config path or undefined\n */\nexport function loadConfigPath(configPath?: string): string | undefined {\n if (configPath) {\n return configPath;\n }\n if (process.env.TAILOR_CONFIG_PATH) {\n return process.env.TAILOR_CONFIG_PATH;\n }\n\n // Search for config file in current directory and parent directories\n return findUpSync(DEFAULT_CONFIG_FILENAME);\n}\n","import { createHash } from \"node:crypto\";\nimport { logger, styles } from \"./logger\";\nimport type { EnvEntry, EnvValue } from \"#/configure/config/types\";\n\nconst AWS_RULE_ID = \"@secretlint/secretlint-rule-aws\";\nconst RULE_ID_PREFIX = \"@secretlint/secretlint-rule-\";\n/**\n * Honors `secretlint-disable` comments found in the scanned text. `env` values\n * are author-controlled text, so leaving this rule in let a value act as a\n * directive and suppress the findings of the entries after it — defeating the\n * check without the explicit allowance.\n *\n * Matched by id on purpose: the rule declares itself a `scanner`, so it cannot\n * be told apart by `meta.type`, and the preset's `disabled` option has no\n * effect on it.\n */\nconst COMMENT_DIRECTIVE_RULE_ID = \"@secretlint/secretlint-rule-filter-comments\";\nconst HIGH_ENTROPY_DETECTOR = \"high-entropy\";\n\n/**\n * The scanned document is assembled in memory, so the path only labels the\n * source for the scanner and never reaches the filesystem.\n */\nconst VIRTUAL_SOURCE_PATH = \"/tailor-config-env\";\n\nconst ENTROPY_MIN_LENGTH = 20;\n/**\n * Bits per character. Above 4.0 no hex-only string can reach the threshold,\n * which keeps commit hashes, UUIDs and slugs out of the heuristic while still\n * catching base64/base62 credentials.\n */\nconst ENTROPY_MIN_BITS_PER_CHAR = 4.2;\nconst TOKEN_LIKE_VALUE = /^[A-Za-z0-9+/=_.-]+$/;\n\n/**\n * A single command can load the same config repeatedly — `setup generate`\n * derives five separate answers, each through its own `loadConfig` — so results\n * are memoized on the entries scanned. Without this the scanner would run, and\n * warnings would print, once per load.\n *\n * Keys are digests rather than the serialized entries, so the cache does not\n * hold the values it was asked to judge for the life of the process.\n */\nconst scans = new Map<string, Promise<void>>();\n\ninterface EnvSecretFinding {\n /** `env` key holding the value. */\n readonly key: string;\n /** Short name of what matched, e.g. `slack`, `aws`, `high-entropy`. */\n readonly detector: string;\n /**\n * Which of the detector's patterns matched, e.g. `AWSAccountID`. A detector\n * can recognize several credential shapes — `aws` alone covers an account id,\n * an access key id and a secret access key — and knowing which one fired is\n * what tells the reader whether the value is actually sensitive.\n */\n readonly rule?: string;\n /** Where the matched pattern is documented. */\n readonly docsUrl?: string;\n /** `error` for provider-specific matches, `warning` for the entropy heuristic. */\n readonly severity: \"error\" | \"warning\";\n}\n\ninterface EnvSecretScanInput {\n /** `env` entries as written in the config, before `{ value, allowSecretReason }` wrappers are resolved. */\n readonly env?: Readonly<Record<string, EnvEntry>>;\n /** Config file the entries came from, named in the failure so multi-config projects can tell which one. */\n readonly configPath?: string;\n}\n\ntype ScannedEntry = readonly [key: string, value: EnvValue];\n\ntype EntryRange = {\n readonly key: string;\n readonly start: number;\n readonly end: number;\n};\n\n/**\n * Resolve an `env` entry to the value that gets deployed.\n * @param entry - Entry as written in the config\n * @returns The entry's value, unwrapped when it carries an `allowSecretReason`\n */\nexport function resolveEnvValue(entry: EnvEntry): EnvValue {\n return isAllowedSecret(entry) ? entry.value : entry;\n}\n\n/**\n * Scan `env` values for credentials.\n *\n * Entries wrapped as `{ value, allowSecretReason }` are skipped.\n * Provider-specific matches are reported as errors; values that merely look\n * randomly generated are reported as warnings.\n * @param input - `env` entries as written in the config\n * @returns Provider matches first, then entropy warnings; empty when nothing matched\n */\nexport async function scanEnvForSecrets(input: EnvSecretScanInput): Promise<EnvSecretFinding[]> {\n const entries: ScannedEntry[] = Object.entries(input.env ?? {})\n .filter(([, entry]) => !isAllowedSecret(entry))\n .map(([key, entry]) => [key, resolveEnvValue(entry)]);\n if (entries.length === 0) {\n return [];\n }\n\n const findings = await scanWithProviderRules(entries);\n const alreadyFound = new Set(findings.map((finding) => finding.key));\n\n for (const [key, value] of entries) {\n if (alreadyFound.has(key) || typeof value !== \"string\") continue;\n if (looksRandomlyGenerated(value)) {\n findings.push({ key, detector: HIGH_ENTROPY_DETECTOR, severity: \"warning\" });\n }\n }\n\n return findings;\n}\n\n/**\n * Report secret-looking `env` values, failing when a credential is identified.\n *\n * Warnings are logged and do not fail the command. Repeated calls for the same\n * entries reuse the first result.\n * @param input - `env` entries as written in the config\n * @returns Promise that resolves when the entries carry no credential\n * @throws When a value is identified as a credential\n */\nexport async function assertEnvHasNoSecrets(input: EnvSecretScanInput): Promise<void> {\n const key = createHash(\"sha256\")\n .update(JSON.stringify([input.configPath ?? \"\", input.env ?? {}]))\n .digest(\"hex\");\n const pending = scans.get(key);\n if (pending) {\n return pending;\n }\n\n const scan = reportEnvSecrets(input);\n scans.set(key, scan);\n return scan;\n}\n\n/**\n * Log warnings and throw on credentials found in `env`.\n * @param input - `env` entries as written in the config\n * @throws When a value is identified as a credential\n */\nasync function reportEnvSecrets(input: EnvSecretScanInput): Promise<void> {\n const findings = await scanEnvForSecrets(input);\n\n for (const finding of findings) {\n if (finding.severity !== \"warning\") continue;\n logger.warn(\n `env.${finding.key} looks like a randomly generated credential. ` +\n `If it is one, move it to Secret Manager; otherwise allow it with ${styles.bold(\"allowSecretReason\")}.`,\n );\n }\n\n const errors = findings.filter((finding) => finding.severity === \"error\");\n if (errors.length === 0) {\n return;\n }\n\n const location = input.configPath ? ` in ${input.configPath}` : \"\";\n const list = errors\n .map((error) => {\n const matched = error.rule ? `${error.detector}: ${error.rule}` : error.detector;\n const reference = error.docsUrl ? `\\n ${error.docsUrl}` : \"\";\n return ` - env.${error.key} (matched ${matched})${reference}`;\n })\n .join(\"\\n\");\n const example = errors[0]?.key ?? \"KEY\";\n throw new Error(\n `Secret detected in 'env'${location}:\\n${list}\\n` +\n \"'env' values are deployed as plaintext and are readable by anyone who can read the application's configuration. \" +\n \"Define these with defineSecretManager() instead, and read them through Secret Manager at runtime.\\n\" +\n \"If a value is genuinely safe to keep in 'env', allow it where it is defined: \" +\n `${example}: { value: ..., allowSecretReason: \"<why this is safe>\" }`,\n );\n}\n\n/**\n * Run the provider rule set over all entries at once.\n *\n * Entries are scanned as one `KEY=value` document because some rules only match\n * when the key name accompanies the value (`AWS_SECRET_ACCESS_KEY`, database\n * connection strings). Each finding is mapped back to its key through the\n * character range the entry occupies, which stays correct for multi-line values.\n * @param entries - `env` entries to scan\n * @returns Error-severity findings, deduplicated per key and rule\n */\nasync function scanWithProviderRules(\n entries: ReadonlyArray<ScannedEntry>,\n): Promise<EnvSecretFinding[]> {\n const [{ lintSource }, { rules }] = await Promise.all([\n import(\"@secretlint/core\"),\n import(\"@secretlint/secretlint-rule-preset-recommend\"),\n ]);\n\n const ranges: EntryRange[] = [];\n let content = \"\";\n for (const [key, value] of entries) {\n const line = `${key}=${String(value)}`;\n ranges.push({ key, start: content.length, end: content.length + line.length });\n content += `${line}\\n`;\n }\n\n const result = await lintSource({\n source: { filePath: VIRTUAL_SOURCE_PATH, content, contentType: \"text\" },\n options: {\n // Messages embed the matched value, so mask them: nothing this scan\n // produces should be able to print a credential.\n maskSecrets: true,\n noPhysicFilePath: true,\n config: {\n // Registered individually rather than through the preset so the\n // comment-directive rule can be left out (see its id above).\n rules: rules\n .filter((rule) => rule.meta.id !== COMMENT_DIRECTIVE_RULE_ID)\n .map((rule) => ({\n id: rule.meta.id,\n rule,\n // Off by default, and the only way to catch a bare access key id.\n ...(rule.meta.id === AWS_RULE_ID ? { options: { enableIDScanRule: true } } : {}),\n })),\n },\n },\n });\n\n const findings: EnvSecretFinding[] = [];\n const seen = new Set<string>();\n for (const message of result.messages) {\n const entry = ranges.find(\n (range) => message.range[0] >= range.start && message.range[0] < range.end,\n );\n if (!entry) continue;\n\n const detector = message.ruleId.startsWith(RULE_ID_PREFIX)\n ? message.ruleId.slice(RULE_ID_PREFIX.length)\n : message.ruleId;\n const dedupeKey = JSON.stringify([entry.key, detector, message.messageId]);\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n\n // The message text embeds the matched value; the identifiers do not.\n findings.push({\n key: entry.key,\n detector,\n rule: message.messageId,\n ...(message.docsUrl ? { docsUrl: message.docsUrl } : {}),\n severity: \"error\",\n });\n }\n\n return findings;\n}\n\n/**\n * Decide whether an entry carries its own allowance.\n * @param entry - Entry as written in the config\n * @returns True when the entry is the `{ value, allowSecretReason }` form\n */\nfunction isAllowedSecret(entry: EnvEntry): entry is Exclude<EnvEntry, EnvValue> {\n return typeof entry === \"object\";\n}\n\n/**\n * Decide whether a value carries enough randomness to look generated rather\n * than authored.\n * @param value - `env` value to inspect\n * @returns True when the value is long, token-shaped and high-entropy\n */\nfunction looksRandomlyGenerated(value: string): boolean {\n if (value.length < ENTROPY_MIN_LENGTH || !TOKEN_LIKE_VALUE.test(value)) {\n return false;\n }\n return shannonEntropyPerChar(value) >= ENTROPY_MIN_BITS_PER_CHAR;\n}\n\n/**\n * Compute Shannon entropy of a string in bits per character.\n * @param value - String to measure\n * @returns Bits per character\n */\nfunction shannonEntropyPerChar(value: string): number {\n const occurrences = new Map<string, number>();\n for (const char of value) {\n occurrences.set(char, (occurrences.get(char) ?? 0) + 1);\n }\n\n let entropy = 0;\n for (const count of occurrences.values()) {\n const probability = count / value.length;\n entropy -= probability * Math.log2(probability);\n }\n return entropy;\n}\n","/**\n * Install a stub `globalThis.tailordb` so that user code loaded by the CLI\n * (e.g. via `createGetDB` in `@tailor-platform/sdk/kysely`) can reference\n * `tailordb.Client` without hitting a `ReferenceError`. The CLI never\n * actually executes the user code paths that issue queries, so a no-op\n * client suffices.\n *\n * Exposed as a function (rather than a top-level statement) so that\n * `package.json#sideEffects` can keep the file marked side-effect-free\n * without bundlers eliminating the install step.\n */\nexport function installCliTailordbStub(): void {\n (\n globalThis as unknown as {\n tailordb: {\n Client: typeof tailordb.Client;\n };\n }\n ).tailordb = {\n Client: class {\n constructor(_config: { namespace: string }) {}\n async connect(): Promise<void> {}\n async end(): Promise<void> {}\n async queryObject<O>(): Promise<tailordb.QueryResult<O>> {\n return {} as Promise<tailordb.QueryResult<O>>;\n }\n },\n };\n}\n","import * as fs from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport * as path from \"pathe\";\nimport { AppConfigSchema } from \"#/parser/app-config/schema\";\nimport { PluginConfigSchema } from \"#/parser/plugin-config/index\";\nimport { loadConfigPath } from \"./context\";\nimport { assertEnvHasNoSecrets, resolveEnvValue } from \"./env-secret-scan\";\nimport { installCliTailordbStub } from \"./mock\";\nimport type { AppConfig, EnvValue } from \"#/configure/config/types\";\nimport type { Plugin } from \"#/plugin/types\";\n\n/**\n * App config whose `env` entries have been resolved to the values that get\n * deployed: the `{ value, allowSecretReason }` form accepted in `defineConfig`\n * is unwrapped during loading, so nothing downstream can deploy a wrapper\n * object or the reason string alongside the value.\n */\nexport type ResolvedEnvAppConfig = Omit<AppConfig, \"env\"> & {\n env?: Record<string, EnvValue>;\n};\n\n/** Loaded configuration with resolved path. */\nexport type LoadedConfig = ResolvedEnvAppConfig & { path: string };\n\nexport interface LoadConfigOptions {\n /** Import cache-busting value for callers that reload the config module after a rebuild. */\n importNonce?: string;\n}\n\n/**\n * Load Tailor configuration file and associated plugins.\n * @param configPath - Optional explicit config path\n * @param options - Optional module import behavior.\n * @returns Loaded config, plugins, and config path\n */\nexport async function loadConfig(\n configPath?: string,\n options: LoadConfigOptions = {},\n): Promise<{ config: LoadedConfig; plugins: Plugin[] }> {\n installCliTailordbStub();\n const foundPath = loadConfigPath(configPath);\n if (!foundPath) {\n throw new Error(\n \"Configuration file not found: tailor.config.ts not found in current or parent directories\",\n );\n }\n const resolvedPath = path.resolve(process.cwd(), foundPath);\n\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`Configuration file not found: ${configPath}`);\n }\n\n const configUrl = pathToFileURL(resolvedPath);\n if (options.importNonce) {\n configUrl.searchParams.set(\"tailorImportNonce\", options.importNonce);\n }\n const configModule = await import(configUrl.href);\n if (!configModule || !configModule.default) {\n throw new Error(\"Invalid Tailor config module: default export not found\");\n }\n\n const validated = AppConfigSchema.safeParse(configModule.default);\n if (!validated.success) {\n const issues = validated.error.issues\n .map((i) => ` - ${i.path.join(\".\") || \"(root)\"}: ${i.message}`)\n .join(\"\\n\");\n throw new Error(`Invalid Tailor config in ${resolvedPath}:\\n${issues}`);\n }\n\n const appConfig = configModule.default as AppConfig;\n await assertEnvHasNoSecrets({ env: appConfig.env, configPath: resolvedPath });\n const env = appConfig.env\n ? Object.fromEntries(\n Object.entries(appConfig.env).map(([key, entry]) => [key, resolveEnvValue(entry)]),\n )\n : undefined;\n\n // Collect all plugin exports (plugins, plugins2, etc.)\n const allPlugins: Plugin[] = [];\n\n for (const value of Object.values(configModule)) {\n if (Array.isArray(value)) {\n const pluginParsed = value.reduce(\n (acc, item) => {\n if (!acc.success) return acc;\n\n const result = PluginConfigSchema.safeParse(item);\n if (result.success) {\n acc.items.push(result.data);\n } else {\n acc.success = false;\n }\n return acc;\n },\n { success: true, items: [] as Plugin[] },\n );\n if (pluginParsed.success && pluginParsed.items.length > 0) {\n allPlugins.push(...pluginParsed.items);\n }\n }\n }\n\n return {\n config: {\n ...configModule.default,\n ...(env ? { env } : {}),\n path: resolvedPath,\n } as LoadedConfig,\n plugins: allPlugins,\n };\n}\n","import { readPlatformConfig } from \"./context\";\nimport { CLIError } from \"./errors\";\n\ninterface AssertWritableOptions {\n /** Explicit profile name from command args. Falls back to TAILOR_PLATFORM_PROFILE. */\n profile?: string;\n}\n\n/**\n * Throw a CLIError if the active profile has `readonly: true`.\n *\n * Resolves the active profile in this order:\n * 1. `opts.profile` (CLI flag)\n * 2. `process.env.TAILOR_PLATFORM_PROFILE`\n *\n * If neither is set, no profile is in scope so the call is allowed. This is\n * intentional: `TAILOR_PLATFORM_TOKEN` direct access (CI / machine user) and\n * `--workspace-id` without a profile are out-of-band paths whose authorization\n * is governed by the bearer token itself, not by the local profile flag.\n *\n * If the resolved profile cannot be found in the config, this function returns\n * silently and lets downstream loaders surface the not-found error.\n * @param opts - Options\n * @param opts.profile - Optional explicit profile name from command args\n */\nexport async function assertWritable(opts?: AssertWritableOptions): Promise<void> {\n // Truthy fallback (||, not ??) so an empty `--profile \"\"` flag falls\n // through to TAILOR_PLATFORM_PROFILE, matching loadAccessToken /\n // loadWorkspaceId. Otherwise the loaders would still resolve a readonly\n // profile from the env var while this guard returns silently.\n const profileName = opts?.profile || process.env.TAILOR_PLATFORM_PROFILE;\n if (!profileName) return;\n const config = await readPlatformConfig();\n const profile = config.profiles[profileName];\n if (!profile || profile.readonly !== true) return;\n throw CLIError({\n code: \"PROFILE_READONLY\",\n message: `Profile \"${profileName}\" is read-only.`,\n details:\n \"This profile blocks platform-state mutations (apply, create/update/delete, deploy, etc.). Application-data operations remain available because their permissions are governed by the machine user.\",\n suggestion: `Use a different profile, unset TAILOR_PLATFORM_PROFILE, or run 'tailor profile update ${profileName} --permission write'.`,\n });\n}\n","import { getPlatformBaseUrl, userAgent, type PlatformClientConfig } from \"#/cli/shared/client\";\nimport { loadAccessToken, loadPlatformClientConfig } from \"#/cli/shared/context\";\n\nexport interface ApiCallOptions {\n profile?: string;\n endpoint: string;\n body?: string;\n}\n\nexport interface ApiCallResult {\n status: number;\n data: unknown;\n}\n\nfunction hasEnvAccessToken(): boolean {\n const envToken = process.env.TAILOR_PLATFORM_TOKEN ?? process.env.TAILOR_TOKEN;\n return Boolean(envToken);\n}\n\n/**\n * Call Tailor Platform API endpoints directly.\n * If the endpoint doesn't contain \"/\", it defaults to `tailor.v1.OperatorService/{endpoint}`.\n * @param options - API call options (profile, endpoint, body)\n * @returns Response status and data\n */\nexport async function apiCall(options: ApiCallOptions): Promise<ApiCallResult> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n let platformConfig: PlatformClientConfig | undefined;\n try {\n platformConfig = await loadPlatformClientConfig({\n profile: options.profile,\n });\n } catch (error) {\n if (!hasEnvAccessToken()) throw error;\n }\n\n let endpointPath: string;\n if (options.endpoint.includes(\"/\")) {\n endpointPath = options.endpoint;\n } else {\n endpointPath = `tailor.v1.OperatorService/${options.endpoint}`;\n }\n\n const url = new URL(endpointPath, getPlatformBaseUrl(platformConfig));\n\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n \"User-Agent\": await userAgent(),\n },\n body: options.body ?? \"{}\",\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(`API call failed (${response.status}): ${JSON.stringify(data)}`);\n }\n\n return {\n status: response.status,\n data,\n };\n}\n","import { ExitPromptError } from \"@inquirer/core\";\nimport { confirm, input, password, select } from \"@inquirer/prompts\";\nimport { isCI } from \"std-env\";\nimport { CIPromptError, logger } from \"./logger\";\n\nexport function canPrompt(): boolean {\n return !isCI && process.stdin.isTTY === true && process.stdout.isTTY === true && !logger.jsonMode;\n}\n\n/**\n * Wraps a prompt function with CI guard and cancellation handling.\n * @param fn - A prompt function from `@inquirer/prompts`\n * @param unavailableMessage - Message used when interactive input is unavailable\n * @returns A wrapped function that throws in CI and exits on cancel\n */\nfunction withGuard<Args extends unknown[], R>(\n fn: (...args: Args) => Promise<R>,\n unavailableMessage?: string,\n): (...args: Args) => Promise<R> {\n return async (...args: Args): Promise<R> => {\n if (!canPrompt()) throw new CIPromptError(unavailableMessage);\n try {\n return await fn(...args);\n } catch (error) {\n if (error instanceof ExitPromptError) process.exit(130);\n throw error;\n }\n };\n}\n\nexport const prompt = {\n confirm: withGuard(\n confirm,\n \"Interactive confirmations are not available in this environment. Use --yes to skip confirmation prompts, or provide the required options explicitly.\",\n ),\n text: withGuard(input),\n password: withGuard(password),\n select: withGuard(select),\n};\n","import { z } from \"zod\";\n\n// strip unknown keys\nconst cacheOutputFileSchema = z.object({\n outputPath: z.string(),\n contentHash: z.string(),\n});\n\n// strip unknown keys\nconst cacheEntrySchema = z.object({\n kind: z.literal(\"bundle\"),\n inputHash: z.string(),\n dependencyPaths: z.array(z.string()),\n outputFiles: z.array(cacheOutputFileSchema),\n createdAt: z.string(),\n});\n\n// strip unknown keys\nconst cacheManifestSchema = z.object({\n version: z.literal(1),\n sdkVersion: z.string(),\n lockfileHash: z.string().optional(),\n entries: z.record(z.string(), cacheEntrySchema),\n});\n\ntype CacheEntry = z.infer<typeof cacheEntrySchema>;\ntype CacheManifest = z.infer<typeof cacheManifestSchema>;\n\n/**\n * Runtime configuration for the caching subsystem.\n */\ntype CacheConfig = {\n /** Directory where cache artifacts are stored. */\n cacheDir: string;\n};\n\nexport { cacheManifestSchema };\nexport type { CacheConfig, CacheEntry, CacheManifest };\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { hashContent } from \"./hasher\";\nimport { cacheManifestSchema } from \"./types\";\nimport type { CacheConfig, CacheEntry, CacheManifest } from \"./types\";\n\n/**\n * Public interface for cache persistence operations.\n */\ntype CacheStore = {\n /** Read manifest from disk, returning undefined if missing or invalid. */\n loadManifest(): CacheManifest | undefined;\n /** Return the current in-memory manifest, loading from disk on first access if not yet loaded. */\n getCurrentManifest(): CacheManifest | undefined;\n /** Persist manifest to disk using atomic write (temp file + rename). */\n saveManifest(manifest: CacheManifest): void;\n /** Retrieve a cache entry by key from the in-memory manifest. */\n getEntry(key: string): CacheEntry | undefined;\n /** Add or update a cache entry in the in-memory manifest. */\n setEntry(key: string, entry: CacheEntry): void;\n /** Remove a cache entry from the in-memory manifest. */\n deleteEntry(key: string): void;\n /** Store bundled code content directly into cache/bundles/. */\n storeBundleContent(cacheKey: string, content: string): void;\n /** Restore bundled code content from cache/bundles/. Returns undefined if not found. */\n restoreBundleContent(cacheKey: string): string | undefined;\n /** Delete the entire cache directory. */\n clean(): void;\n};\n\nconst MANIFEST_FILENAME = \"manifest.json\";\nconst BUNDLES_DIR = \"bundles\";\n\n/**\n * Create a cache store for manifest persistence and bundle output storage.\n * @param config - Cache configuration specifying the cache directory\n * @returns A CacheStore instance\n */\nfunction createCacheStore(config: CacheConfig): CacheStore {\n // Tri-state: null = not yet loaded, undefined = loaded but missing/invalid, CacheManifest = loaded\n let cachedManifest: CacheManifest | undefined | null = null;\n\n function manifestPath(): string {\n return path.join(config.cacheDir, MANIFEST_FILENAME);\n }\n\n function bundlesDir(): string {\n return path.join(config.cacheDir, BUNDLES_DIR);\n }\n\n function bundlePath(cacheKey: string): string {\n return path.join(bundlesDir(), `${hashContent(cacheKey)}.js`);\n }\n\n function loadManifest(): CacheManifest | undefined {\n try {\n const raw = fs.readFileSync(manifestPath(), \"utf-8\");\n const result = cacheManifestSchema.safeParse(JSON.parse(raw));\n\n if (!result.success) {\n cachedManifest = undefined;\n return undefined;\n }\n\n cachedManifest = result.data;\n return cachedManifest;\n } catch {\n // Missing file, parse error, etc.\n cachedManifest = undefined;\n return undefined;\n }\n }\n\n function getCurrentManifest(): CacheManifest | undefined {\n if (cachedManifest === null) {\n loadManifest();\n }\n return cachedManifest ?? undefined;\n }\n\n function ensureManifestLoaded(): CacheManifest {\n if (cachedManifest === null) {\n loadManifest();\n }\n if (cachedManifest == null) {\n cachedManifest = {\n version: 1,\n sdkVersion: \"\",\n entries: {},\n };\n }\n return cachedManifest;\n }\n\n function saveManifest(manifest: CacheManifest): void {\n fs.mkdirSync(config.cacheDir, { recursive: true });\n\n const target = manifestPath();\n const tmpFile = path.join(config.cacheDir, `.manifest.${process.pid}.tmp`);\n\n // Atomic write: write to temp file, then rename\n try {\n fs.writeFileSync(tmpFile, JSON.stringify(manifest, null, 2), \"utf-8\");\n fs.renameSync(tmpFile, target);\n } catch (e) {\n try {\n fs.rmSync(tmpFile, { force: true });\n } catch {\n // Ignore cleanup errors\n }\n throw e;\n }\n\n cachedManifest = manifest;\n }\n\n function getEntry(key: string): CacheEntry | undefined {\n const manifest = ensureManifestLoaded();\n return manifest.entries[key];\n }\n\n function setEntry(key: string, entry: CacheEntry): void {\n const manifest = ensureManifestLoaded();\n manifest.entries[key] = entry;\n }\n\n function deleteEntry(key: string): void {\n const manifest = ensureManifestLoaded();\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- Cache entry removal by dynamic key\n delete manifest.entries[key];\n }\n\n function storeBundleContent(cacheKey: string, content: string): void {\n const dir = bundlesDir();\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(bundlePath(cacheKey), content, \"utf-8\");\n }\n\n function restoreBundleContent(cacheKey: string): string | undefined {\n try {\n return fs.readFileSync(bundlePath(cacheKey), \"utf-8\");\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n throw e;\n }\n }\n\n function clean(): void {\n fs.rmSync(config.cacheDir, { recursive: true, force: true });\n cachedManifest = null;\n }\n\n return {\n loadManifest,\n getCurrentManifest,\n saveManifest,\n getEntry,\n setEntry,\n deleteEntry,\n storeBundleContent,\n restoreBundleContent,\n clean,\n };\n}\n\nexport { createCacheStore };\nexport type { CacheStore };\n","import * as path from \"pathe\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { createBundleCache, type BundleCache } from \"./bundle-cache\";\nimport { createCacheStore } from \"./store\";\n\n/**\n * Options for creating a CacheManager.\n */\ntype CacheManagerOptions = {\n /** Whether caching is enabled. Defaults to true. */\n enabled?: boolean;\n /** Directory where cache artifacts are stored. Defaults to `<distDir>/cache`. */\n cacheDir?: string;\n /** Current SDK version for cache invalidation on upgrade. */\n sdkVersion: string;\n /** Hash of the lockfile for cache invalidation on dependency changes. */\n lockfileHash?: string;\n};\n\n/**\n * Top-level facade that orchestrates cache operations.\n */\ntype CacheManager = {\n readonly enabled: boolean;\n readonly bundleCache: BundleCache;\n /** Persist the cache manifest to disk. */\n finalize(): void;\n};\n\n/**\n * Create a CacheManager that orchestrates cache operations.\n * @param options - Configuration for the cache manager\n * @returns A CacheManager instance\n */\nfunction createCacheManager(options: CacheManagerOptions): CacheManager {\n const enabled = options.enabled ?? true;\n\n if (!enabled) {\n return {\n enabled: false,\n bundleCache: {\n tryRestore() {\n return undefined;\n },\n save() {\n // no-op\n },\n },\n finalize() {\n // no-op\n },\n };\n }\n\n const cacheDir = options.cacheDir ?? path.resolve(getDistDir(), \"cache\");\n\n const store = createCacheStore({ cacheDir });\n\n // Load existing manifest and check SDK version / lockfile hash for cache invalidation\n const existingManifest = store.loadManifest();\n if (existingManifest) {\n if (existingManifest.sdkVersion !== options.sdkVersion) {\n logger.debug(\n `Cache invalidated: SDK version changed from ${existingManifest.sdkVersion} to ${options.sdkVersion}`,\n );\n store.clean();\n } else if (existingManifest.lockfileHash !== options.lockfileHash) {\n logger.debug(\"Cache invalidated: lockfile changed\");\n store.clean();\n }\n }\n\n const bundleCache = createBundleCache(store);\n\n return {\n enabled: true,\n bundleCache,\n finalize() {\n const currentManifest = store.getCurrentManifest() ?? {\n version: 1 as const,\n sdkVersion: options.sdkVersion,\n lockfileHash: options.lockfileHash,\n entries: {},\n };\n const latestManifest = store.loadManifest();\n const manifest =\n latestManifest?.sdkVersion === options.sdkVersion &&\n latestManifest.lockfileHash === options.lockfileHash\n ? {\n ...latestManifest,\n entries: {\n ...latestManifest.entries,\n ...currentManifest.entries,\n },\n }\n : currentManifest;\n manifest.sdkVersion = options.sdkVersion;\n manifest.lockfileHash = options.lockfileHash;\n store.saveManifest(manifest);\n },\n };\n}\n\nexport { createCacheManager };\nexport type { CacheManager, CacheManagerOptions };\n","/**\n * Format migration number as 4-digit string.\n * @param num - Migration number\n * @returns 4-digit padded string\n */\nexport function formatMigrationNumber(num: number): string {\n return num.toString().padStart(4, \"0\");\n}\n\n/**\n * Parse a migration number CLI argument.\n *\n * Accepts the canonical 4-digit form (\"0001\") or a bare integer without\n * leading zeros (\"0\"–\"9999\"). Commands that disallow the baseline reject\n * 0 themselves with a context-specific message.\n * @param numberStr - Raw CLI argument\n * @returns Parsed migration number\n */\nexport function parseMigrationNumberArg(numberStr: string): number {\n if (/^\\d{4}$/.test(numberStr)) {\n return parseInt(numberStr, 10);\n }\n if (/^(0|[1-9]\\d*)$/.test(numberStr)) {\n const parsed = parseInt(numberStr, 10);\n if (parsed > 9999) {\n throw new Error(`Migration number ${numberStr} is out of range. Expected 0-9999.`);\n }\n return parsed;\n }\n throw new Error(\n `Invalid migration number format: ${numberStr}. Expected 4-digit format (e.g., 0001) or integer 0-9999 (e.g., 1).`,\n );\n}\n","/** Resource and trigger named in a `publishEvents` opt-out conflict error. */\nexport type PublishEventsConflict = {\n /** Resource named in the error, e.g. `TailorDB type \"Order\"`. */\n resource: string;\n /** Executor trigger family named in the error, e.g. `record`. */\n trigger: string;\n /** What the subscribing executors subscribe to. Defaults to `\"it\"`. */\n subscribesTo?: string;\n};\n\n/**\n * How each event-publishing resource is named in user-facing messages.\n *\n * Every message naming one of these reads from here, so a conflict error and the\n * confirmation that lists the same resource cannot drift apart.\n */\nexport const eventSourceLabel = {\n tailorDBType: (name: string) => `TailorDB type \"${name}\"`,\n resolver: (name: string) => `Resolver \"${name}\"`,\n idpService: (name: string) => `IdP service \"${name}\"`,\n workflow: (name: string) => `Workflow \"${name}\"`,\n workflowJob: (name: string) => `Job \"${name}\"`,\n workflowJobs: (workflowName: string) => `Jobs of workflow \"${workflowName}\"`,\n} as const;\n\n/** Opt-out conflict details per event-publishing resource. */\nexport const publishEventsConflict = {\n tailorDBType: (name: string): PublishEventsConflict => ({\n resource: eventSourceLabel.tailorDBType(name),\n trigger: \"record\",\n }),\n resolver: (name: string): PublishEventsConflict => ({\n resource: eventSourceLabel.resolver(name),\n trigger: \"resolverExecuted\",\n }),\n idpService: (name: string): PublishEventsConflict => ({\n resource: eventSourceLabel.idpService(name),\n trigger: \"idpUser\",\n }),\n workflow: (name: string): PublishEventsConflict => ({\n resource: eventSourceLabel.workflow(name),\n trigger: \"workflowExecution\",\n }),\n workflowJob: (name: string): PublishEventsConflict => ({\n resource: eventSourceLabel.workflowJob(name),\n trigger: \"workflowJobExecution\",\n subscribesTo: \"a workflow that runs it\",\n }),\n} as const;\n\n/**\n * Build the error raised when a resource opts out of publishing that a\n * subscribing executor needs.\n * @param conflict - Resource, trigger, and subscription target named in the error\n * @returns Error message\n */\nfunction publishEventsConflictError(conflict: PublishEventsConflict): string {\n const { resource, trigger, subscribesTo = \"it\" } = conflict;\n return (\n `${resource} has \"publishEvents: false\", but executors with ${trigger} triggers subscribe to ${subscribesTo}. ` +\n `Either remove \"publishEvents: false\" or remove the matching executor triggers.`\n );\n}\n\n/** Inputs deciding whether a resource publishes events. */\nexport type ResolvePublishEventsParams = {\n /** `publishEvents` declared on the resource, or undefined when unset. */\n explicit: boolean | undefined;\n /** Whether an executor taking part in the same run subscribes to it. */\n subscribed: boolean;\n /** Resource and trigger named when an opt-out conflicts with a subscriber. */\n conflict: PublishEventsConflict;\n};\n\n/**\n * Reject an opt-out that a subscribing executor contradicts.\n *\n * Separate from {@link resolvePublishEvents} so a planner can reject the whole\n * config before issuing any request, rather than partway through.\n * @param params - Declared value, subscriber presence, and conflict error details\n */\nexport function assertNoPublishEventsConflict(params: ResolvePublishEventsParams): void {\n const { explicit, subscribed, conflict } = params;\n if (explicit === false && subscribed) {\n throw new Error(publishEventsConflictError(conflict));\n }\n}\n\n/**\n * Resolve whether a resource publishes events.\n *\n * An unset value is recomputed from the executors taking part in the run, so\n * removing the last subscribing trigger turns publishing back off. A `deploy`\n * covering several configs counts a subscriber in any of them, so a resource\n * shared across configs needs `publishEvents: true` on the resource itself only\n * to keep publishing when the subscribing config is deployed on its own.\n * @param params - Declared value, subscriber presence, and conflict error details\n * @returns Whether the resource publishes events\n */\nexport function resolvePublishEvents(params: ResolvePublishEventsParams): boolean {\n assertNoPublishEventsConflict(params);\n return params.explicit ?? params.subscribed;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { logger } from \"#/cli/shared/logger\";\nimport ml from \"#/utils/multiline\";\nimport type { ResolvedEnvAppConfig } from \"#/cli/shared/config-loader\";\nimport type { AppConfig } from \"#/configure/config/types\";\n\nexport interface AttributeTypeInfo {\n type: string;\n optional?: boolean;\n}\n\nexport interface AttributesConfig {\n [key: string]: AttributeTypeInfo;\n}\n\nexport type AttributeListConfig = readonly string[];\n\ninterface ExtractedAttributes {\n attributes?: AttributesConfig;\n attributeList?: AttributeListConfig;\n env?: Record<string, string | number | boolean>;\n machineUserNames?: string[];\n idpNames?: string[];\n connectionNames?: string[];\n aiGatewayNames?: string[];\n}\n\ntype AttributeFieldLike = {\n type?: string;\n metadata?: {\n array?: boolean;\n allowedValues?: Array<{ value: string }>;\n required?: boolean;\n };\n};\n\n/**\n * Extract attribute definitions from the app config for user-defined typing.\n * @param config - Application config to inspect\n * @returns Extracted attributes/list and env values\n * @internal\n */\nexport function extractAttributesFromConfig(config: AppConfig): ExtractedAttributes {\n return collectAttributesFromConfig(config);\n}\n\n// Quote generated keys only when they aren't valid TypeScript identifiers — matches\n// the formatter (oxfmt) output so subsequent format passes are no-ops.\nconst isValidIdentifier = (s: string): boolean => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(s);\n\n/**\n * Generate the contents of the user-defined type definition file.\n * @param attributes - Attribute configuration\n * @param attributeList - Attribute list configuration\n * @param env - Environment configuration\n * @param machineUserNames - Registered machine user names (used to narrow `invoker` strings)\n * @param idpNames - Registered IdP names (used to narrow `idpUser*Trigger({ idp })` strings)\n * @param connectionNames - Registered auth connection names (used to narrow `getConnectionToken()` strings)\n * @param aiGatewayNames - Registered AI Gateway names (used to narrow `aigateway.get()` strings)\n * @returns Generated type definition source\n */\nexport function generateTypeDefinition(\n attributes: AttributesConfig | undefined,\n attributeList: AttributeListConfig | undefined,\n env?: Record<string, string | number | boolean>,\n machineUserNames?: readonly string[],\n idpNames?: readonly string[],\n connectionNames?: readonly string[],\n aiGatewayNames?: readonly string[],\n): string {\n // Generate Attributes interface\n // attributes values carry a type string representation (e.g., \"string\", \"boolean\", \"string[]\")\n // and whether the underlying field is optional, so the key mirrors that optionality.\n const attributeFields = attributes\n ? Object.entries(attributes)\n .map(([key, { type, optional }]) => ` ${key}${optional ? \"?\" : \"\"}: ${type};`)\n .join(\"\\n\")\n : \"\";\n\n const attributesBody =\n !attributes || Object.keys(attributes).length === 0\n ? \"{}\"\n : `{\n${attributeFields}\n }`;\n\n // Generate AttributeList type as a tuple of strings based on the length\n const listType = attributeList ? `[${attributeList.map(() => \"string\").join(\", \")}]` : \"[]\";\n\n // Use interface with __tuple marker for declaration merging and tuple type support\n const listBody = `{\n __tuple?: ${listType};\n }`;\n\n // Generate Env interface.\n // Emit the value's type, never the value itself — a literal would leak the\n // configured value into this generated file.\n const envFields = env\n ? Object.entries(env)\n .map(\n ([key, value]) =>\n ` ${isValidIdentifier(key) ? key : JSON.stringify(key)}: ${typeof value};`,\n )\n .join(\"\\n\")\n : \"\";\n\n const envBody =\n !env || Object.keys(env).length === 0\n ? \"{}\"\n : `{\n${envFields}\n }`;\n\n // Generate MachineUserNameRegistry interface.\n const machineUserFields = machineUserNames?.length\n ? machineUserNames\n .map((name) => ` ${isValidIdentifier(name) ? name : JSON.stringify(name)}: true;`)\n .join(\"\\n\")\n : \"\";\n\n const machineUserBody =\n !machineUserNames || machineUserNames.length === 0\n ? \"{}\"\n : `{\n${machineUserFields}\n }`;\n\n // Generate IdpNameRegistry interface (same quoting rules as machine users).\n const idpNameFields = idpNames?.length\n ? idpNames\n .map((name) => ` ${isValidIdentifier(name) ? name : JSON.stringify(name)}: true;`)\n .join(\"\\n\")\n : \"\";\n\n const idpNameBody =\n !idpNames || idpNames.length === 0\n ? \"{}\"\n : `{\n${idpNameFields}\n }`;\n\n // Generate ConnectionNameRegistry interface (same quoting rules as machine users).\n const connectionNameFields = connectionNames?.length\n ? connectionNames\n .map((name) => ` ${isValidIdentifier(name) ? name : JSON.stringify(name)}: true;`)\n .join(\"\\n\")\n : \"\";\n\n const connectionNameBody =\n !connectionNames || connectionNames.length === 0\n ? \"{}\"\n : `{\n${connectionNameFields}\n }`;\n\n // Generate AIGatewayNameRegistry interface (same quoting rules as machine users).\n const aiGatewayNameFields = aiGatewayNames?.length\n ? aiGatewayNames\n .map((name) => ` ${isValidIdentifier(name) ? name : JSON.stringify(name)}: true;`)\n .join(\"\\n\")\n : \"\";\n\n const aiGatewayNameBody =\n !aiGatewayNames || aiGatewayNames.length === 0\n ? \"{}\"\n : `{\n${aiGatewayNameFields}\n }`;\n\n return ml /* ts */ `\n// This file is auto-generated by @tailor-platform/sdk\n// Do not edit this file manually\n// Regenerated automatically when running 'tailor deploy' or 'tailor generate'\n\ndeclare module \"@tailor-platform/sdk\" {\n interface Attributes ${attributesBody}\n interface AttributeList ${listBody}\n interface Env ${envBody}\n interface MachineUserNameRegistry ${machineUserBody}\n interface IdpNameRegistry ${idpNameBody}\n interface ConnectionNameRegistry ${connectionNameBody}\n interface AIGatewayNameRegistry ${aiGatewayNameBody}\n}\n\nexport {};\n\n`;\n}\n\nfunction collectAttributesFromConfig(config: AppConfig): ExtractedAttributes {\n // De-duplicate IdP names so duplicates in config don't emit duplicate\n // `IdpNameRegistry` keys (which would be invalid TypeScript).\n const idpNames = config.idp?.length ? [...new Set(config.idp.map((idp) => idp.name))] : undefined;\n\n // De-duplicate AI Gateway names for the same reason.\n const aiGatewayNames = config.aiGateways?.length\n ? [...new Set(config.aiGateways.map((gateway) => gateway.name))]\n : undefined;\n\n const auth = config.auth;\n if (!auth || typeof auth !== \"object\") {\n return idpNames || aiGatewayNames ? { idpNames, aiGatewayNames } : {};\n }\n\n // Extract machine user names from auth.machineUsers (available regardless of userProfile vs. machineUserAttributes)\n const machineUsersObj = (auth as { machineUsers?: Record<string, unknown> }).machineUsers;\n const machineUserNames =\n machineUsersObj && typeof machineUsersObj === \"object\"\n ? Object.keys(machineUsersObj)\n : undefined;\n\n // Extract connection names from auth.connections (available regardless of userProfile vs. machineUserAttributes)\n const connectionsObj = (auth as { connections?: Record<string, unknown> }).connections;\n const connectionNames =\n connectionsObj && typeof connectionsObj === \"object\" ? Object.keys(connectionsObj) : undefined;\n\n const inferAttributeType = (field?: AttributeFieldLike): AttributeTypeInfo => {\n const type = field?.type;\n const metadata = field?.metadata;\n\n // Default to string if no metadata\n if (!metadata) {\n return { type: \"string\" };\n }\n\n let typeStr = \"string\";\n\n if (type === \"boolean\") {\n typeStr = \"boolean\";\n } else if (type === \"enum\" && metadata.allowedValues) {\n // Generate union type from enum values\n typeStr = metadata.allowedValues.map((v) => `\"${v.value}\"`).join(\" | \");\n }\n\n // Add array suffix if needed\n if (metadata.array) {\n typeStr = typeStr.includes(\" | \") ? `(${typeStr})[]` : `${typeStr}[]`;\n }\n\n return { type: typeStr, optional: metadata.required === false };\n };\n\n // Check if auth has userProfile with attributes/attributeList\n if (\"userProfile\" in auth) {\n const userProfile = (\n auth as {\n userProfile?: {\n type?: {\n fields?: Record<string, AttributeFieldLike>;\n };\n attributes?: Record<string, true>;\n attributeList?: AttributeListConfig;\n };\n }\n ).userProfile;\n\n const selectedAttributes = userProfile?.attributes;\n const fields = userProfile?.type?.fields;\n const attributeList = userProfile?.attributeList;\n\n // Convert attributes to AttributesConfig by inferring types from field metadata\n const attributes: AttributesConfig | undefined = selectedAttributes\n ? Object.keys(selectedAttributes).reduce((acc, key) => {\n acc[key] = inferAttributeType(fields?.[key]);\n return acc;\n }, {} as AttributesConfig)\n : undefined;\n\n return {\n attributes,\n attributeList,\n machineUserNames,\n idpNames,\n connectionNames,\n aiGatewayNames,\n };\n }\n\n if (\"machineUserAttributes\" in auth) {\n const machineUserAttributes = (\n auth as {\n machineUserAttributes?: Record<string, AttributeFieldLike>;\n }\n ).machineUserAttributes;\n\n if (!machineUserAttributes) {\n return { machineUserNames, idpNames, connectionNames, aiGatewayNames };\n }\n\n const attributes = Object.entries(machineUserAttributes).reduce((acc, [key, field]) => {\n acc[key] = inferAttributeType(field);\n return acc;\n }, {} as AttributesConfig);\n\n return {\n attributes,\n machineUserNames,\n idpNames,\n connectionNames,\n aiGatewayNames,\n };\n }\n\n return { machineUserNames, idpNames, connectionNames, aiGatewayNames };\n}\n\n/**\n * Resolve the output path for the generated type definition file.\n *\n * When the `TAILOR_DTS_PATH` environment variable is set, the value is\n * used as the output path (resolved relative to cwd when relative).\n * Otherwise, the file is written next to the config file as `tailor.d.ts`.\n * @param configPath - Path to Tailor config file\n * @returns Absolute path to the type definition file\n */\nexport function resolveTypeDefinitionPath(configPath: string): string {\n const envPath = process.env.TAILOR_DTS_PATH;\n if (envPath) {\n return path.resolve(envPath);\n }\n return path.join(path.dirname(path.resolve(configPath)), \"tailor.d.ts\");\n}\n\n/**\n * Options for generating user type definitions\n */\ninterface GenerateUserTypesOptions {\n /** Application config with resolved `env` values */\n config: ResolvedEnvAppConfig;\n /** Path to Tailor config file */\n configPath: string;\n}\n\n/**\n * Generate user type definitions from the app config and write them to disk.\n * @param options - Generation options\n * @returns Promise that resolves when types are generated\n */\nexport async function generateUserTypes(options: GenerateUserTypesOptions): Promise<void> {\n const { config, configPath } = options;\n try {\n const {\n attributes,\n attributeList,\n machineUserNames,\n idpNames,\n connectionNames,\n aiGatewayNames,\n } = extractAttributesFromConfig(config);\n if (!attributes && !attributeList) {\n logger.info(\"No attributes found in configuration\", { mode: \"plain\" });\n }\n\n if (attributes) {\n logger.debug(`Extracted Attributes: ${JSON.stringify(attributes)}`);\n }\n if (attributeList) {\n logger.debug(`Extracted AttributeList: ${JSON.stringify(attributeList)}`);\n }\n if (machineUserNames?.length) {\n logger.debug(`Extracted MachineUserNames: ${JSON.stringify(machineUserNames)}`);\n }\n if (idpNames?.length) {\n logger.debug(`Extracted IdpNames: ${JSON.stringify(idpNames)}`);\n }\n if (connectionNames?.length) {\n logger.debug(`Extracted ConnectionNames: ${JSON.stringify(connectionNames)}`);\n }\n if (aiGatewayNames?.length) {\n logger.debug(`Extracted AIGatewayNames: ${JSON.stringify(aiGatewayNames)}`);\n }\n\n const env = config.env;\n if (env) {\n logger.debug(`Extracted Env: ${JSON.stringify(env)}`);\n }\n\n // Generate type definition\n const typeDefContent = generateTypeDefinition(\n attributes,\n attributeList,\n env,\n machineUserNames,\n idpNames,\n connectionNames,\n aiGatewayNames,\n );\n const outputPath = resolveTypeDefinitionPath(configPath);\n\n // Write to file\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.writeFileSync(outputPath, typeDefContent);\n const relativePath = path.relative(process.cwd(), outputPath);\n logger.newline();\n logger.success(`Generated type definitions: ${relativePath}`, {\n mode: \"plain\",\n });\n } catch (error) {\n logger.error(\"Error generating types\");\n logger.error(String(error));\n // Don't throw - this should not block apply/generate\n }\n}\n","import { db, type TailorAnyDBType } from \"#/configure/services/tailordb/index\";\nimport { hasGenerationHooks, getPluginGenerationDependencies } from \"#/plugin/guards\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type {\n TailorTypePermission,\n TailorTypeGqlPermission,\n} from \"#/configure/services/tailordb/permission\";\nimport type {\n DependencyKind,\n Plugin,\n PluginAttachment,\n PluginGeneratedExecutor,\n PluginGeneratedType,\n PluginNamespaceProcessContext,\n PluginOutput,\n TypePluginOutput,\n} from \"#/plugin/types\";\nimport type { TailorDBTypeRaw } from \"#/types/tailordb.generated\";\n\n/**\n * Context for processing a single plugin attachment on a raw TailorDBType\n */\nexport interface ProcessAttachmentContext {\n type: TailorAnyDBType;\n typeConfig: unknown;\n namespace: string;\n pluginId: string;\n}\n\n/**\n * Information about a plugin-generated type (for type file generation)\n */\nexport interface PluginGeneratedTypeInfo {\n /** Plugin ID that generated this type */\n pluginId: string;\n /** Plugin import path for resolving executor files */\n pluginImportPath: string;\n /** Source type name that triggered the plugin */\n sourceTypeName: string;\n /** Kind identifier for this generated type */\n kind: string;\n /** The generated TailorDB type object */\n type: PluginGeneratedType;\n /** Namespace where this type was generated */\n namespace: string;\n /** Plugin config used to generate this type */\n pluginConfig?: unknown;\n}\n\n/**\n * Extended executor info with plugin import path\n */\nexport interface PluginExecutorInfoExtended extends PluginExecutorInfo {\n /** Plugin's import path for resolving executor files */\n pluginImportPath: string;\n}\n\n/**\n * Result of processing a type-attached plugin\n */\nexport type ProcessAttachmentResult =\n | { success: true; output: TypePluginOutput }\n | { success: false; error: string };\n\n/**\n * Result of processing a namespace plugin\n */\nexport type ProcessNamespaceResult =\n | { success: true; output: PluginOutput }\n | { success: false; error: string };\n\n/**\n * Parameters for processing all plugin attachments of a TailorDB type.\n */\nexport interface ProcessAttachmentsForTypeParams {\n rawType: TailorDBTypeRaw;\n attachments: PluginAttachment[];\n namespace: string;\n}\n\n/**\n * Progress event emitted while processing plugin attachments for a TailorDB type.\n * Plain data so the caller (typically the cli) can format and output it.\n */\nexport type ProcessAttachmentEvent =\n | { kind: \"extended\"; typeName: string; fieldCount: number; pluginId: string }\n | { kind: \"generated\"; typeName: string; pluginId: string };\n\n/**\n * Generated type produced by a plugin during attachment processing.\n */\nexport interface ProcessAttachmentsGeneratedType {\n typeName: string;\n type: TailorDBTypeRaw;\n kind: string;\n pluginId: string;\n pluginImportPath: string;\n pluginConfig?: unknown;\n}\n\n/**\n * Result of {@link PluginManager.processAttachmentsForType}.\n */\nexport interface ProcessAttachmentsForTypeResult {\n /** Final type after all extends are applied; undefined if no plugin extended the type. */\n extendedType?: TailorDBTypeRaw;\n /** Types newly generated by plugins for this attachment chain. */\n generatedTypes: ProcessAttachmentsGeneratedType[];\n /** Events for the caller to render. */\n events: ProcessAttachmentEvent[];\n}\n\n/**\n * Information about a plugin-generated executor\n */\nexport interface PluginExecutorInfo {\n /** The executor definition */\n executor: PluginGeneratedExecutor;\n /** Plugin ID that generated this executor */\n pluginId: string;\n /** Namespace where the executor was generated */\n namespace: string;\n /** Source type name (for type-attached executors, undefined for namespace) */\n sourceTypeName?: string;\n}\n\n/**\n * Manages plugin registration and processing\n */\nexport class PluginManager {\n private plugins: Map<string, Plugin> = new Map();\n private generatedExecutors: PluginExecutorInfo[] = [];\n private generatedTypes: PluginGeneratedTypeInfo[] = [];\n private namespaceGeneratedTypeKeys: Set<string> = new Set();\n private namespaceGeneratedExecutorKeys: Set<string> = new Set();\n\n /** Generated plugin executor file paths */\n private pluginExecutorFiles: string[] = [];\n\n constructor(plugins: Plugin[] = []) {\n for (const plugin of plugins) {\n if (this.plugins.has(plugin.id)) {\n throw new Error(\n `Duplicate plugin ID \"${plugin.id}\" detected. Each plugin must have a unique ID.`,\n );\n }\n this.plugins.set(plugin.id, plugin);\n }\n }\n\n /**\n * Process a single plugin attachment on a raw TailorDBType.\n * This method is called during type loading before parsing.\n * @param context - Context containing the raw type, config, namespace, and plugin ID\n * @returns Result with plugin output on success, or error message on failure\n */\n async processAttachment(context: ProcessAttachmentContext): Promise<ProcessAttachmentResult> {\n const plugin = this.plugins.get(context.pluginId);\n if (!plugin) {\n return {\n success: false,\n error: `Plugin \"${context.pluginId}\" not found`,\n };\n }\n\n const typeConfigRequired = plugin.typeConfigRequired;\n const resolvedRequired =\n typeof typeConfigRequired === \"function\"\n ? typeConfigRequired(plugin.pluginConfig)\n : typeConfigRequired === true;\n if (resolvedRequired && (context.typeConfig === undefined || context.typeConfig === null)) {\n return {\n success: false,\n error: `Plugin \"${plugin.id}\" requires typeConfig, but none was provided for type \"${context.type.name}\".`,\n };\n }\n\n // Check if plugin supports type-attached processing\n if (!plugin.onTypeLoaded) {\n return {\n success: false,\n error: `Plugin \"${plugin.id}\" does not support type-attached processing (missing onTypeLoaded method). Use onNamespaceLoaded via definePlugins() instead.`,\n };\n }\n\n // Execute plugin onTypeLoaded with raw TailorDBType\n let output: TypePluginOutput;\n try {\n output = await plugin.onTypeLoaded({\n type: context.type,\n typeConfig: context.typeConfig,\n pluginConfig: plugin.pluginConfig,\n namespace: context.namespace,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Plugin \"${plugin.id}\" threw an error while processing type \"${context.type.name}\": ${message}`,\n };\n }\n\n // Collect generated types\n if (output.types && Object.keys(output.types).length > 0) {\n // importPath is guaranteed by schema validation for plugins with definition-time hooks\n const importPath = assertDefined(\n plugin.importPath,\n `plugin \"${plugin.id}\" missing importPath`,\n );\n for (const [kind, type] of Object.entries(output.types)) {\n this.generatedTypes.push({\n pluginId: context.pluginId,\n pluginImportPath: importPath,\n sourceTypeName: context.type.name,\n kind,\n type,\n namespace: context.namespace,\n pluginConfig: plugin.pluginConfig,\n });\n }\n }\n\n // Collect generated executors\n if (output.executors && output.executors.length > 0) {\n for (const executor of output.executors) {\n this.generatedExecutors.push({\n executor,\n pluginId: context.pluginId,\n namespace: context.namespace,\n sourceTypeName: context.type.name,\n });\n }\n }\n\n return { success: true, output };\n }\n\n /**\n * Process namespace plugins that don't require a source type.\n * This method is called once per namespace for plugins with onNamespaceLoaded method.\n * @param namespace - The target namespace for generated types\n * @returns Array of results with plugin outputs and configs\n */\n async processNamespacePlugins(\n namespace: string,\n ): Promise<Array<{ pluginId: string; config: unknown; result: ProcessNamespaceResult }>> {\n const results: Array<{ pluginId: string; config: unknown; result: ProcessNamespaceResult }> =\n [];\n\n for (const [pluginId, plugin] of this.plugins) {\n // Skip plugins without onNamespaceLoaded method\n if (!plugin.onNamespaceLoaded) {\n continue;\n }\n\n // Use stored plugin config (from definePlugins)\n const config = plugin.pluginConfig;\n\n // Execute plugin onNamespaceLoaded\n const context: PluginNamespaceProcessContext = {\n pluginConfig: config,\n namespace,\n };\n\n let output: Awaited<ReturnType<NonNullable<Plugin[\"onNamespaceLoaded\"]>>>;\n try {\n output = await plugin.onNamespaceLoaded(context);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n results.push({\n pluginId,\n config,\n result: {\n success: false,\n error: `Plugin \"${plugin.id}\" threw an error during namespace processing for \"${namespace}\": ${message}`,\n },\n });\n continue;\n }\n\n // Collect generated executors (namespace - no source type)\n if (output.executors && output.executors.length > 0) {\n for (const executor of output.executors) {\n const executorKey = `${pluginId}:${executor.name}`;\n if (this.namespaceGeneratedExecutorKeys.has(executorKey)) {\n continue;\n }\n this.namespaceGeneratedExecutorKeys.add(executorKey);\n this.generatedExecutors.push({\n executor,\n pluginId,\n namespace,\n });\n }\n }\n\n // Collect generated types (namespace - no source type)\n if (output.types && Object.keys(output.types).length > 0) {\n // importPath is guaranteed by schema validation for plugins with definition-time hooks\n const importPath = assertDefined(\n plugin.importPath,\n `plugin \"${plugin.id}\" missing importPath`,\n );\n for (const [kind, type] of Object.entries(output.types)) {\n const typeKey = `${pluginId}:${kind}:${type.name}`;\n if (this.namespaceGeneratedTypeKeys.has(typeKey)) {\n continue;\n }\n this.namespaceGeneratedTypeKeys.add(typeKey);\n this.generatedTypes.push({\n pluginId,\n pluginImportPath: importPath,\n sourceTypeName: \"(namespace)\",\n kind,\n type,\n namespace,\n pluginConfig: plugin.pluginConfig,\n });\n }\n }\n\n results.push({\n pluginId,\n config,\n result: { success: true, output },\n });\n }\n\n return results;\n }\n\n /**\n * Run every plugin attachment for a single TailorDB type in order, threading the\n * extended type through the chain. Returns plain data (no logging, no shared state)\n * so the caller decides how to apply updates and render progress.\n * @param params - The raw type, its attachments, and the target namespace\n * @returns Final extended type (if any), generated types, and render events\n */\n async processAttachmentsForType(\n params: ProcessAttachmentsForTypeParams,\n ): Promise<ProcessAttachmentsForTypeResult> {\n const { rawType, attachments, namespace } = params;\n // The runtime value is a configure-layer builder instance; we accept the structural\n // TailorDBTypeRaw at the boundary so callers (cli) don't need to depend on TailorAnyDBType.\n let currentType: TailorAnyDBType = rawType as unknown as TailorAnyDBType;\n let extendedType: TailorDBTypeRaw | undefined;\n const generatedTypes: ProcessAttachmentsGeneratedType[] = [];\n const events: ProcessAttachmentEvent[] = [];\n\n for (const attachment of attachments) {\n const result = await this.processAttachment({\n type: currentType,\n typeConfig: attachment.config,\n namespace,\n pluginId: attachment.pluginId,\n });\n if (!result.success) {\n throw new Error(result.error);\n }\n\n const output = result.output;\n const extendFields = output.extends?.fields;\n if (extendFields && Object.keys(extendFields).length > 0) {\n currentType = this.extendType({\n originalType: currentType,\n extendFields,\n pluginId: attachment.pluginId,\n });\n extendedType = currentType as unknown as TailorDBTypeRaw;\n events.push({\n kind: \"extended\",\n typeName: currentType.name,\n fieldCount: Object.keys(extendFields).length,\n pluginId: attachment.pluginId,\n });\n }\n\n const plugin = this.getPlugin(attachment.pluginId);\n for (const [kind, gen] of Object.entries(output.types ?? {})) {\n generatedTypes.push({\n typeName: gen.name,\n type: gen as unknown as TailorDBTypeRaw,\n kind,\n pluginId: attachment.pluginId,\n pluginImportPath: this.getPluginImportPath(attachment.pluginId) ?? \"\",\n pluginConfig: plugin?.pluginConfig,\n });\n events.push({ kind: \"generated\", typeName: gen.name, pluginId: attachment.pluginId });\n }\n }\n\n return { extendedType, generatedTypes, events };\n }\n\n /**\n * Get plugins that have onNamespaceLoaded method\n * @returns Array of plugin IDs that support namespace processing\n */\n getNamespacePluginIds(): string[] {\n return Array.from(this.plugins.entries())\n .filter(([, plugin]) => plugin.onNamespaceLoaded !== undefined)\n .map(([id]) => id);\n }\n\n /**\n * Get the count of registered plugins\n * @returns Number of registered plugins\n */\n get pluginCount(): number {\n return this.plugins.size;\n }\n\n /**\n * Get a plugin by its ID\n * @param pluginId - The plugin ID to look up\n * @returns The plugin instance, or undefined if not found\n */\n getPlugin(pluginId: string): Plugin | undefined {\n return this.plugins.get(pluginId);\n }\n\n /**\n * Get the import path for a plugin\n * @param pluginId - The plugin ID to look up\n * @returns The plugin's import path, or undefined if not found\n */\n getPluginImportPath(pluginId: string): string | undefined {\n return this.plugins.get(pluginId)?.importPath;\n }\n\n /**\n * Get all plugin-generated executors\n * @returns Array of plugin-generated executor info\n */\n getPluginGeneratedExecutors(): ReadonlyArray<PluginExecutorInfo> {\n return this.generatedExecutors;\n }\n\n /**\n * Get all plugin-generated executors with import paths\n * @returns Array of plugin-generated executor info with import paths\n */\n getPluginGeneratedExecutorsWithImportPath(): ReadonlyArray<PluginExecutorInfoExtended> {\n return this.generatedExecutors.map((info) => ({\n ...info,\n pluginImportPath: this.getPluginImportPath(info.pluginId) ?? \"\",\n }));\n }\n\n /**\n * Get all plugin-generated types\n * @returns Array of plugin-generated type info\n */\n getPluginGeneratedTypes(): ReadonlyArray<PluginGeneratedTypeInfo> {\n return this.generatedTypes;\n }\n\n /**\n * Get plugin-generated executors for a specific namespace\n * @param namespace - The namespace to filter by\n * @returns Array of plugin-generated executor info for the namespace\n */\n getPluginGeneratedExecutorsForNamespace(namespace: string): ReadonlyArray<PluginExecutorInfo> {\n return this.generatedExecutors.filter((info) => info.namespace === namespace);\n }\n\n /**\n * Get plugins that have any generation-time hooks.\n * @returns Array of plugins with generation hooks\n */\n getPluginsWithGenerationHooks(): Plugin[] {\n return Array.from(this.plugins.values()).filter((plugin) => hasGenerationHooks(plugin));\n }\n\n /**\n * Get the generation-time dependencies for a specific plugin.\n * @param pluginId - The plugin ID to look up\n * @returns Set of dependency kinds, or empty set if plugin not found\n */\n getPluginGenerationDependencies(pluginId: string): Set<DependencyKind> {\n const plugin = this.plugins.get(pluginId);\n if (!plugin) return new Set();\n return getPluginGenerationDependencies(plugin);\n }\n\n /**\n * Generate plugin files (types and executors) and store the executor file paths.\n * @param params - Parameters for file generation\n * @returns Generated executor file paths\n */\n generatePluginFiles(params: GeneratePluginFilesParams): string[] {\n const { outputDir, sourceTypeInfoMap, configPath, typeGenerator, executorGenerator } = params;\n\n // Generate type files\n const typeGenerationResult = typeGenerator(this.generatedTypes, outputDir);\n\n // Generate executor files\n const pluginExecutors = this.getPluginGeneratedExecutorsWithImportPath();\n this.pluginExecutorFiles = executorGenerator(\n pluginExecutors,\n outputDir,\n typeGenerationResult,\n sourceTypeInfoMap,\n configPath,\n );\n\n return this.pluginExecutorFiles;\n }\n\n /**\n * Extend a TailorDB type with new fields.\n * This method handles the `db.table()` call and metadata copying internally.\n * @param params - Parameters for type extension\n * @returns The extended TailorDB type\n */\n extendType(params: ExtendTypeParams): TailorAnyDBType {\n const { originalType, extendFields, pluginId } = params;\n const existingFieldNames = Object.keys(originalType.fields);\n const newFieldNames = Object.keys(extendFields);\n const duplicateFields = newFieldNames.filter((name) => existingFieldNames.includes(name));\n\n if (duplicateFields.length > 0) {\n throw new Error(\n `Plugin \"${pluginId}\" attempted to add fields that already exist in type \"${originalType.name}\": ${duplicateFields.join(\", \")}. ` +\n `extendFields cannot overwrite existing fields.`,\n );\n }\n\n const mergedFields = {\n ...originalType.fields,\n ...extendFields,\n };\n\n const { id: _id, ...fieldsWithoutId } = mergedFields;\n const pluralForm = originalType.metadata.settings?.pluralForm;\n const typeName = pluralForm\n ? ([originalType.name, pluralForm] as [string, string])\n : originalType.name;\n const extendedType = db.table(typeName, fieldsWithoutId);\n return copyMetadataToExtendedType(originalType, extendedType);\n }\n}\n\n/**\n * Source info for user-defined types\n */\nexport type SourceTypeInfo = {\n filePath: string;\n exportName: string;\n};\n\n/**\n * Result of generating plugin type files\n */\nexport interface PluginTypeGenerationResult {\n /** Map of type name to generated file path (relative to outputDir) */\n typeFilePaths: Map<string, string>;\n /** List of all generated file paths (absolute) */\n generatedFiles: string[];\n}\n\n/**\n * Parameters for generating plugin files\n */\nexport interface GeneratePluginFilesParams {\n /** Base output directory (e.g., .tailor/plugin) */\n outputDir: string;\n /** Map of source type names to their source info */\n sourceTypeInfoMap: Map<string, SourceTypeInfo>;\n /** Path to tailor.config.ts (used for resolving plugin import paths) */\n configPath: string;\n /** Function to generate type files */\n typeGenerator: (\n types: ReadonlyArray<PluginGeneratedTypeInfo>,\n outputDir: string,\n ) => PluginTypeGenerationResult;\n /** Function to generate executor files */\n executorGenerator: (\n executors: ReadonlyArray<PluginExecutorInfoExtended>,\n outputDir: string,\n typeGenerationResult: PluginTypeGenerationResult,\n sourceTypeInfoMap: Map<string, SourceTypeInfo>,\n configPath: string,\n ) => string[];\n}\n\n/**\n * Parameters for extending a TailorDB type\n */\nexport interface ExtendTypeParams {\n /** The original TailorDB type to extend */\n originalType: TailorAnyDBType;\n /** New fields to add to the type */\n extendFields: Record<string, unknown>;\n /** The ID of the plugin extending the type */\n pluginId: string;\n}\n\n/**\n * Copy metadata from original type to extended type.\n * Preserves files, settings, permissions, indexes, and plugins.\n * @param original - The original TailorDB type with metadata\n * @param extended - The newly created extended type\n * @returns The extended type with copied metadata\n */\nfunction copyMetadataToExtendedType(\n original: TailorAnyDBType,\n extended: TailorAnyDBType,\n): TailorAnyDBType {\n let result = extended;\n\n // Copy description\n if (original._description) {\n result = result.description(original._description);\n }\n\n // Copy files metadata\n const metadata = original.metadata;\n if (Object.keys(metadata.files).length > 0) {\n result = result.files(metadata.files);\n }\n\n // Copy settings/features (excluding pluralForm which is set during construction)\n if (metadata.settings) {\n const { pluralForm: _pluralForm, ...features } = metadata.settings;\n if (Object.keys(features).length > 0) {\n result = result.features(\n features as typeof features & { aggregation?: true; bulkUpsert?: true },\n );\n }\n }\n\n // Copy permissions from metadata\n // Zod schema operand types are wider unions than the configure layer's discriminated PermissionCondition,\n // so type assertions are needed here.\n if (metadata.permissions.record) {\n result = result.permission(metadata.permissions.record as TailorTypePermission);\n }\n if (metadata.permissions.gql) {\n result = result.gqlPermission(metadata.permissions.gql as TailorTypeGqlPermission);\n }\n\n // Copy indexes from metadata (indexes are stored in metadata, not as a direct property)\n if (metadata.indexes && Object.keys(metadata.indexes).length > 0) {\n const indexDefs = Object.entries(metadata.indexes).map(([name, def]) => ({\n name,\n // Cast fields array to tuple type (IndexDef expects [T, T, ...T[]])\n fields: def.fields as [string, string, ...string[]],\n unique: def.unique,\n }));\n result = result.indexes(...indexDefs);\n }\n\n // Copy plugins (but don't re-process them)\n if (original.plugins.length > 0) {\n for (const plugin of original.plugins) {\n // Use type assertion as plugin ID is dynamic at runtime\n result = result.plugin({\n [plugin.pluginId]: plugin.config,\n } as Parameters<typeof result.plugin>[0]);\n }\n }\n\n return result;\n}\n","import { styles, symbols } from \"#/cli/shared/logger\";\n\nexport interface HasName {\n name: string;\n /**\n * Optional pre-formatted lines rendered indented beneath the item by\n * `ChangeSet.lines()` (e.g. per-sub-resource diffs embedded in a single\n * resource).\n */\n details?: readonly string[];\n}\n\nexport type ChangeSet<\n C extends HasName,\n U extends HasName,\n D extends HasName,\n R extends HasName = never,\n Un extends HasName = HasName,\n> = {\n readonly title: string;\n readonly creates: C[];\n readonly updates: U[];\n readonly deletes: D[];\n readonly replaces: R[];\n readonly unchanged: Un[];\n isEmpty: () => boolean;\n lines: () => string[];\n};\n\nexport interface PlanSummary {\n create: number;\n update: number;\n delete: number;\n replace: number;\n}\n\n/**\n * Create a new ChangeSet for tracking resource changes.\n * @param title - Title for the change set\n * @returns Empty ChangeSet instance with isEmpty() and lines() methods\n */\nexport function createChangeSet<\n C extends HasName,\n U extends HasName,\n D extends HasName,\n R extends HasName = never,\n Un extends HasName = HasName,\n>(title: string): ChangeSet<C, U, D, R, Un> {\n const creates: C[] = [];\n const updates: U[] = [];\n const deletes: D[] = [];\n const replaces: R[] = [];\n const unchanged: Un[] = [];\n\n const isEmpty = (): boolean =>\n creates.length === 0 && updates.length === 0 && deletes.length === 0 && replaces.length === 0;\n\n return {\n title,\n creates,\n updates,\n deletes,\n replaces,\n unchanged,\n isEmpty,\n lines: () => {\n if (isEmpty()) return [];\n const itemLines = (symbol: string) => (item: HasName) => [\n ` ${symbol} ${item.name}`,\n ...(item.details ?? []).map((d) => ` ${d}`),\n ];\n return [\n styles.bold(`${title}:`),\n ...creates.flatMap(itemLines(symbols.create)),\n ...deletes.flatMap(itemLines(symbols.delete)),\n ...updates.flatMap(itemLines(symbols.update)),\n ...replaces.flatMap(itemLines(symbols.replace)),\n ];\n },\n };\n}\n\n/**\n * Summarize resource counts across multiple change sets.\n * @param changeSets - Change sets to aggregate\n * @returns Aggregated plan counts by action\n */\nexport function summarizeChangeSets(\n changeSets: Array<\n Pick<\n ChangeSet<HasName, HasName, HasName, HasName>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >\n >,\n): PlanSummary {\n const summary: PlanSummary = { create: 0, update: 0, delete: 0, replace: 0 };\n\n for (const changeSet of changeSets) {\n summary.create += changeSet.creates.length;\n summary.update += changeSet.updates.length;\n summary.delete += changeSet.deletes.length;\n summary.replace += changeSet.replaces.length;\n }\n\n return summary;\n}\n\n/**\n * Format an aggregated plan summary for CLI output.\n * @param summary - Aggregated plan counts\n * @returns Human-readable plan summary line\n */\nexport function formatPlanSummary(summary: PlanSummary): string {\n const parts = [\n `${summary.create} to create`,\n `${summary.update} to update`,\n `${summary.delete} to delete`,\n ];\n\n if (summary.replace > 0) {\n parts.push(`${summary.replace} to replace`);\n }\n\n return `Plan: ${parts.join(\", \")}`;\n}\n","import { create, toJson, type DescMessage, type MessageInitShape } from \"@bufbuild/protobuf\";\n\n/**\n * Canonicalize a proto message (or init shape) into proto JSON for comparison.\n *\n * Deserialized messages materialize implicit proto3 fields with their zero\n * values while locally built init shapes omit them, so comparing the raw\n * objects reports a diff for every field the SDK does not set — including\n * fields newly added to the proto. Proto JSON omits implicit zero values on\n * both sides, which matches wire semantics (unset == zero value).\n * @param schema - Message schema describing the value\n * @param value - Message or init shape to canonicalize\n * @returns Proto JSON representation of the value\n */\nexport function toComparableProtoJson<Desc extends DescMessage>(\n schema: Desc,\n value: MessageInitShape<Desc>,\n): unknown {\n return toJson(schema, create(schema, value));\n}\n\n/**\n * Stable JSON-like serialization that sorts object keys and ignores proto runtime metadata.\n * @param value - Value to serialize\n * @returns Stable serialized string\n */\nexport function stableStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((item) => (item === undefined ? \"null\" : stableStringify(item))).join(\",\")}]`;\n }\n if (value && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([key, entryValue]) => key !== \"$typeName\" && entryValue !== undefined)\n .toSorted(([left], [right]) => left.localeCompare(right));\n return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(\",\")}}`;\n }\n if (typeof value === \"bigint\") {\n return JSON.stringify(value.toString());\n }\n return JSON.stringify(value);\n}\n\n/**\n * Normalize a proto-ish object into a plain JSON-compatible structure for comparison.\n * @param value - Value to normalize\n * @returns Normalized value\n */\nexport function normalizeProtoConfig<T>(value: T): T {\n if (value === undefined || value === null) {\n return value;\n }\n return JSON.parse(stableStringify(value)) as T;\n}\n\n/**\n * Sort a string array for order-insensitive comparison.\n * @param values - Values to sort\n * @returns Sorted values\n */\nexport function normalizeStringArray(values: readonly string[] | undefined): string[] {\n return (values ?? []).toSorted();\n}\n\n/**\n * Compare two values after proto normalization.\n * @param left - Left value\n * @param right - Right value\n * @returns True when normalized values are equal\n */\nexport function areNormalizedEqual(left: unknown, right: unknown): boolean {\n return (\n stableStringify(normalizeProtoConfig(left)) === stableStringify(normalizeProtoConfig(right))\n );\n}\n","import { getOrNull } from \"#/cli/shared/client\";\nimport { readPackageJson } from \"#/cli/shared/package-json\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { SetMetadataRequestSchema } from \"@tailor-platform/tailor-proto/metadata_pb\";\n\nexport type WithLabel<T> = Partial<\n Record<\n string,\n {\n resource: T;\n label: string | undefined;\n allLabels?: Record<string, string>;\n }\n >\n>;\n\n/**\n * Build TRN prefix for a workspace.\n * @param workspaceId - Workspace ID\n * @returns TRN prefix string\n */\nfunction trnPrefix(workspaceId: string): string {\n return `trn:v1:workspace:${workspaceId}`;\n}\n\n/**\n * Resource kind segment used in a TRN (`trn:v1:workspace:<id>:<kind>:<name>`).\n */\nexport type ResourceKind =\n | \"application\"\n | \"function_registry\"\n | \"pipeline\"\n | \"idp\"\n | \"auth\"\n | \"auth_connection\"\n | \"executor\"\n | \"workflow\"\n | \"workflow_job_function\"\n | \"workflow_job_function_execution_policy\"\n | \"staticwebsite\"\n | \"aigateway\"\n | \"tailordb\"\n | \"vault\";\n\n/**\n * Build the TRN for a workspace resource.\n * @param workspaceId - Workspace ID\n * @param kind - Resource kind segment\n * @param name - Resource name\n * @returns Fully-qualified TRN string\n */\nexport function resourceTrn(workspaceId: string, kind: ResourceKind, name: string): string {\n return `${trnPrefix(workspaceId)}:${kind}:${name}`;\n}\n\n/**\n * Build the TRN for a resource nested inside another.\n *\n * The platform reads everything after the workspace id as alternating key/value\n * pairs and matches the pair list against one resource type, so a nested\n * resource is the parent's pair followed by its own. A TailorDB type is\n * `tailordb:<namespace>:type:<name>`, distinct from the namespace's own\n * `tailordb:<namespace>`.\n * @param workspaceId - Workspace ID\n * @param parent - Parent kind and name, e.g. the namespace holding the resource\n * @param child - Nested key and name, e.g. `[\"type\", \"Order\"]`\n * @returns Fully-qualified TRN string\n */\nfunction nestedResourceTrn(\n workspaceId: string,\n parent: readonly [ResourceKind, string],\n child: readonly [NestedResourceKey, string],\n): string {\n return `${trnPrefix(workspaceId)}:${parent[0]}:${parent[1]}:${child[0]}:${child[1]}`;\n}\n\n/** Key naming a resource nested inside a namespace in a TRN. */\ntype NestedResourceKey = \"type\" | \"resolver\";\n\n/**\n * Build the TRN for one TailorDB type.\n * @param workspaceId - Workspace ID\n * @param namespace - TailorDB namespace holding the type\n * @param typeName - Type name\n * @returns Fully-qualified TRN string\n */\nexport function tailorDBTypeTrn(workspaceId: string, namespace: string, typeName: string): string {\n return nestedResourceTrn(workspaceId, [\"tailordb\", namespace], [\"type\", typeName]);\n}\n\n/**\n * Build the TRN for one resolver.\n * @param workspaceId - Workspace ID\n * @param namespace - Resolver namespace holding the resolver\n * @param resolverName - Resolver name\n * @returns Fully-qualified TRN string\n */\nexport function resolverTrn(workspaceId: string, namespace: string, resolverName: string): string {\n return nestedResourceTrn(workspaceId, [\"pipeline\", namespace], [\"resolver\", resolverName]);\n}\n\nexport const sdkNameLabelKey = \"sdk-name\";\nexport const sdkVersionLabelKey = \"sdk-version\";\nexport const sdkAppIdLabelKey = \"sdk-app-id\";\n\n// The metadata label value regex requires a leading lowercase letter, while\n// the auto-generated app id is a plain UUID (which may start with a digit).\n// The `app-` prefix is added at the metadata boundary so the user-facing id\n// in `tailor.config.ts` can stay a plain UUID.\nconst appIdLabelPrefix = \"app-\";\n\nfunction toAppIdLabelValue(appId: string): string {\n return `${appIdLabelPrefix}${appId}`;\n}\n\n/**\n * Check whether existing metadata was produced by the current SDK version.\n * @param existingLabels - Labels currently stored on the remote resource\n * @param desiredLabels - Labels that will be written by the current apply run\n * @returns True when sdk-version matches\n */\nexport function hasMatchingSdkVersion(\n existingLabels: Record<string, string> | undefined,\n desiredLabels: Record<string, string> | undefined,\n): boolean {\n return existingLabels?.[sdkVersionLabelKey] === desiredLabels?.[sdkVersionLabelKey];\n}\n\n/**\n * Determine whether a remote resource is owned by the given application.\n * When the resource carries an `sdk-app-id`, ownership is decided strictly\n * by id match — a resource explicitly tagged with another app's id is\n * NOT ours even if the legacy sdk-name happens to match. Resources without\n * `sdk-app-id` (legacy) fall back to sdk-name comparison.\n * @param labels - Labels currently stored on the remote resource\n * @param appName - Application name from the local config\n * @param appId - Stable application id from the local config (when present)\n * @returns True when the resource is owned by the application\n */\nexport function isOwnedByApp(\n labels: Record<string, string> | undefined,\n appName: string,\n appId: string | undefined,\n): boolean {\n if (!labels) return false;\n const labelAppId = labels[sdkAppIdLabelKey];\n if (labelAppId) {\n return appId !== undefined && labelAppId === toAppIdLabelValue(appId);\n }\n return labels[sdkNameLabelKey] === appName;\n}\n\n// Records that another config must take part in the same deploy, because this\n// application's resources are applied differently when it does. The dependent\n// application's id goes in the key so several can be recorded at once — a label\n// value cannot hold a delimited list (values are `^$|^[a-z][a-z0-9_-]{0,62}$`).\nconst dependedByAppLabelPrefix = \"sdk-depended-by-app-\";\n\n// A workflow carries two independent values: its own publishExecutionEvents and\n// the one its jobs get. Different trigger kinds drive them, so their records need\n// separate namespaces on the one TRN — collapsing them lets a subscriber of one\n// suppress the confirmation for the other.\nconst jobDependedByAppLabelPrefix = \"sdk-job-depended-by-app-\";\n\n/** Which of a resource's values a dependency record concerns. */\nexport type DependencyScope = \"resource\" | \"jobs\";\n\nfunction prefixFor(scope: DependencyScope): string {\n return scope === \"jobs\" ? jobDependedByAppLabelPrefix : dependedByAppLabelPrefix;\n}\n\n/** Why a dependent config has to take part in the same deploy. */\nexport type DeployDependencyReason = \"publish-events\";\n\n// Label keys are `^[a-z][a-z0-9_-]{0,62}$`, so an id that is not a lowercase\n// UUID cannot be recorded. `ensureConfigIdForDeploy` writes canonical UUIDs;\n// this guards a hand-edited value rather than silently building an invalid key.\nconst RECORDABLE_APP_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * Build the label key recording that an application depends on this deploy.\n * @param appId - Stable id of the dependent application\n * @param scope - Which of the resource's values the record concerns\n * @returns Label key, or undefined when the id cannot form a valid key\n */\nexport function dependedByAppLabelKey(\n appId: string,\n scope: DependencyScope = \"resource\",\n): string | undefined {\n return RECORDABLE_APP_ID.test(appId) ? `${prefixFor(scope)}${appId}` : undefined;\n}\n\n/** An application recorded as depending on this deploy. */\nexport type RecordedDependency = {\n /** Stable id of the dependent application. */\n appId: string;\n /** Why it has to take part in the same deploy. */\n reason: string;\n};\n\n/**\n * Read the dependent applications recorded on a resource.\n *\n * Only keys {@link dependedByAppLabelKey} could have written are read back, so a\n * label the SDK could not have produced cannot raise a confirmation prompt that\n * naming no config in the run makes unanswerable.\n * @param labels - Labels currently stored on the remote resource\n * @param scope - Which of the resource's values to read records for\n * @returns Recorded dependencies, in label-key order\n */\nexport function recordedDependencies(\n labels: Record<string, string> | undefined,\n scope: DependencyScope = \"resource\",\n): RecordedDependency[] {\n if (!labels) return [];\n const prefix = prefixFor(scope);\n return Object.entries(labels)\n .toSorted(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .flatMap(([key, reason]) => {\n if (!key.startsWith(prefix)) return [];\n const appId = key.slice(prefix.length);\n return RECORDABLE_APP_ID.test(appId) ? [{ appId, reason }] : [];\n });\n}\n\n/**\n * Key one event-publishing resource for the dependency records.\n *\n * Planners rebuild the same string from the resource they are applying, so the\n * shape is the TRN's tail rather than anything new to keep in step.\n */\nexport const eventSourceKey = {\n tailorDBType: (namespace: string, typeName: string) => `tailordb:${namespace}:type:${typeName}`,\n resolver: (namespace: string, resolverName: string) =>\n `pipeline:${namespace}:resolver:${resolverName}`,\n idp: (name: string) => `idp:${name}`,\n workflow: (name: string) => `workflow:${name}`,\n // A workflowJobExecution trigger names a workflow, but drives the jobs' value\n // rather than the workflow's own, so it aggregates separately.\n workflowJobs: (name: string) => `workflow:${name}:jobs`,\n} as const;\n\n/**\n * Dependent application ids and reasons, keyed by the resource that carries them.\n * The key is the TRN's tail, e.g. `tailordb:db:type:Order` or `workflow:nightly`.\n */\nexport type DependentAppsByResource = ReadonlyMap<\n string,\n ReadonlyMap<string, DeployDependencyReason>\n>;\n\n/** Inputs deciding which dependency records a deploy writes and drops. */\nexport type DependencyLabelParams = {\n /** Labels currently stored on the resource. */\n existingLabels: Record<string, string> | undefined;\n /** Applications this run found depending on the resource being planned. */\n dependentApps: ReadonlyMap<string, DeployDependencyReason> | undefined;\n /** Stable ids of every application taking part in the run. */\n runAppIds: ReadonlySet<string> | undefined;\n /**\n * Whether the resource declares `publishEvents`. A declared value is not\n * recomputed, so no absent config can change it.\n */\n pinned: boolean;\n /** Which of the resource's values these records concern. */\n scope?: DependencyScope;\n};\n\n/**\n * Split the dependency records into the ones to write and the ones to drop.\n *\n * A record for an application outside the run appears in neither list, so\n * {@link writeMetadataLabels} keeps it: it was written when both took part, and\n * dropping it would lose the only signal that this partial deploy is about to\n * change how the resource is applied. A record for an application that does take\n * part is rewritten or dropped, so a dependency that no longer exists disappears\n * on the next deploy including both.\n *\n * A resource that declares `publishEvents` drops every record instead. Nothing\n * about it depends on which configs the run covers, so a record could only\n * produce a prompt about a change that cannot happen — and one the owner could\n * never clear on its own, since clearing needs the dependent to take part.\n * @param params - Existing labels and the run's dependency inputs\n * @returns Labels to set and label keys to delete\n */\nexport function dependencyLabelWrite(\n params: DependencyLabelParams,\n): Required<Pick<MetadataLabelWrite, \"labels\" | \"remove\">> {\n const { existingLabels, dependentApps, runAppIds, pinned, scope = \"resource\" } = params;\n if (pinned) {\n return {\n labels: {},\n remove: recordedDependencies(existingLabels, scope).flatMap(\n ({ appId }) => dependedByAppLabelKey(appId, scope) ?? [],\n ),\n };\n }\n const dependents = dependentApps ?? new Map<string, DeployDependencyReason>();\n const inRun = runAppIds ?? new Set<string>();\n\n const labels: Record<string, string> = {};\n for (const [appId, reason] of dependents) {\n const key = dependedByAppLabelKey(appId, scope);\n if (!key) {\n throw new Error(\n `Application id \"${appId}\" cannot be recorded as a dependency of this deploy. ` +\n `Ids are written by deploy as lowercase UUIDs; restore the generated value in the ` +\n `config's \"id\".`,\n );\n }\n labels[key] = reason;\n }\n\n const remove = recordedDependencies(existingLabels, scope).flatMap(({ appId }) => {\n if (!inRun.has(appId) || dependents.has(appId)) return [];\n const key = dependedByAppLabelKey(appId, scope);\n return key ? [key] : [];\n });\n\n return { labels, remove };\n}\n\nexport interface BuildMetaRequestParams {\n trn: string;\n appName: string;\n appId?: string;\n}\n\n/**\n * Build metadata request with SDK labels.\n *\n * Sets only the SDK's own labels; {@link writeMetadataLabels} keeps the rest\n * from the labels it reads at write time.\n *\n * Without an app id the id label is removed rather than merely left unset,\n * because {@link isOwnedByApp} decides ownership by that label alone: one left\n * over from an earlier deploy would keep reading as another app's, and every\n * later deploy would ask to re-tag the same resources again.\n * @param params - Parameters for building the metadata request\n * @param params.trn - Target TRN\n * @param params.appName - Application name label\n * @param params.appId - Stable application id label (when managed by SDK)\n * @returns Metadata request\n */\nexport async function buildMetaRequest(\n params: BuildMetaRequestParams,\n): Promise<MetadataLabelWrite> {\n const { trn, appName, appId } = params;\n const packageJson = await readPackageJson();\n // Format version to be suitable for label value\n const sdkVersion = packageJson.version\n ? `v${packageJson.version.replace(/\\./g, \"-\")}`\n : \"unknown\";\n\n return {\n trn,\n labels: {\n [sdkNameLabelKey]: appName,\n [sdkVersionLabelKey]: sdkVersion,\n ...(appId ? { [sdkAppIdLabelKey]: toAppIdLabelValue(appId) } : {}),\n },\n remove: appId ? undefined : [sdkAppIdLabelKey],\n };\n}\n\n/** What a planner knows about the resource it is recording dependencies for. */\nexport type ResourceDependencyParams = {\n /** Key identifying the resource, e.g. `workflow:nightly`. */\n key: string;\n /** Dependents the run resolved, keyed by resource. */\n dependentApps: DependentAppsByResource | undefined;\n /** Stable ids of every application taking part in the run. */\n runAppIds: ReadonlySet<string> | undefined;\n /** Whether the resource declares `publishEvents`. */\n pinned: boolean;\n /** Which of the resource's values these records concern. */\n scope?: DependencyScope;\n};\n\n/**\n * Fold a resource's dependency records into the write already planned for it.\n *\n * The reconciliation is attached rather than computed, so it runs against the\n * labels read at write time. Whatever {@link buildMetaRequest} asked for —\n * dropping a stale `sdk-app-id`, for instance — still happens alongside it.\n * @param write - The resource's planned metadata write, mutated in place\n * @param params - The resource's key and the run's inputs\n * @returns The same write, for use as an expression\n */\nexport function addDependencyRecords(\n write: MetadataLabelWrite,\n params: ResourceDependencyParams,\n): MetadataLabelWrite {\n const { key, dependentApps, runAppIds, pinned, scope } = params;\n write.dependencies = [\n ...(write.dependencies ?? []),\n { dependentApps: dependentApps?.get(key), runAppIds, pinned, scope },\n ];\n return write;\n}\n\n/**\n * The client surface {@link writeMetadataLabels} needs. Narrower than the full\n * operator client so tests can pass a stub and the module stays decoupled.\n */\nexport interface MetadataLabelClient {\n getMetadata(request: { trn: string }): Promise<{ metadata?: { labels: Record<string, string> } }>;\n setMetadata(request: MessageInitShape<typeof SetMetadataRequestSchema>): Promise<unknown>;\n}\n\n/** A metadata label write, expressed as a change rather than a whole map. */\nexport interface MetadataLabelWrite {\n /** Target TRN. */\n trn: string;\n /** Labels to set. Keys absent here keep whatever the resource already has. */\n labels?: Record<string, string>;\n /** Label keys to delete. Absent keys are ignored. */\n remove?: ReadonlyArray<string>;\n /**\n * Dependency records to reconcile against the labels found at write time.\n *\n * Which records to drop depends on what is already there, and\n * {@link writeMetadataLabels} reads that anyway — resolving it here rather than\n * while planning saves every planner a second read of the same resource.\n */\n dependencies?: ReadonlyArray<PendingDependencyRecords>;\n}\n\n/** A dependency-record reconciliation waiting on the resource's current labels. */\nexport type PendingDependencyRecords = Omit<DependencyLabelParams, \"existingLabels\">;\n\n/**\n * Write metadata labels as a change against the resource's current labels.\n *\n * `SetMetadata` replaces the whole label map, so a request built from labels\n * read earlier deletes anything written in between. This re-reads immediately\n * before writing and applies `labels` and `remove` to what it finds, which is\n * why every label write in the SDK goes through here rather than calling\n * `client.setMetadata` directly.\n *\n * Concurrent writers are still not safe in the strict sense — that needs\n * server-side conditional writes — but a write can no longer be built from\n * state this process read at an unrelated point in time.\n *\n * A write that changes nothing does nothing — whether the caller requested no\n * change or the change turns out to already hold. Writing back what was just\n * read would still overwrite whatever landed in between, for no gain, and the\n * labels the SDK sets are unchanged on most deploys.\n * @param client - Operator client instance\n * @param write - TRN, labels to set, and label keys to delete\n * @returns Promise that resolves when the labels are written\n */\nexport async function writeMetadataLabels(\n client: MetadataLabelClient,\n write: MetadataLabelWrite,\n): Promise<void> {\n const { trn, labels, remove, dependencies } = write;\n if (!Object.keys(labels ?? {}).length && !(remove ?? []).length && !dependencies?.length) return;\n const current = await getOrNull(() => client.getMetadata({ trn }));\n const currentLabels = current?.metadata?.labels ?? {};\n const resolved = (dependencies ?? []).map((pending) =>\n dependencyLabelWrite({ ...pending, existingLabels: currentLabels }),\n );\n const merged: Record<string, string> = {\n ...currentLabels,\n ...labels,\n ...Object.assign({}, ...resolved.map((records) => records.labels)),\n };\n for (const key of [...(remove ?? []), ...resolved.flatMap((records) => records.remove)]) {\n delete merged[key];\n }\n if (areSameLabels(currentLabels, merged)) return;\n await client.setMetadata({ trn, labels: merged });\n}\n\nfunction areSameLabels(a: Record<string, string>, b: Record<string, string>): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);\n}\n","import { fetchAllTolerant, type OperatorClient } from \"#/cli/shared/client\";\nimport { isOwnedByApp, sdkNameLabelKey, type WithLabel } from \"./label\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\n\ntype ResourcePageFetcher<T> = (pageToken: string, maxPageSize: number) => Promise<[T[], string]>;\n\nexport interface FetchExistingResourcesWithLabelsParams<T> {\n client: OperatorClient;\n fetchPage: ResourcePageFetcher<T>;\n getName: (resource: T) => string | undefined;\n getTrn: (name: string) => string;\n}\n\n/**\n * Fetch a workspace-scoped resource list and attach SDK ownership metadata.\n * @template T\n * @param params - Resource fetch parameters\n * @param params.client - Operator client instance\n * @param params.fetchPage - Function that fetches one resource page\n * @param params.getName - Function that extracts the resource name\n * @param params.getTrn - Function that builds the resource TRN\n * @returns Existing resources keyed by resource name, with SDK labels attached\n */\nexport async function fetchExistingResourcesWithLabels<T>(\n params: FetchExistingResourcesWithLabelsParams<T>,\n): Promise<WithLabel<T>> {\n const { client, fetchPage, getName, getTrn } = params;\n const withoutLabel = await fetchAllTolerant(fetchPage);\n const existingResources: WithLabel<T> = {};\n await Promise.all(\n withoutLabel.map(async (resource) => {\n const name = getName(resource);\n if (!name) {\n return;\n }\n const { metadata } = await client.getMetadata({\n trn: getTrn(name),\n });\n existingResources[name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\n );\n return existingResources;\n}\n\nexport interface TrackDesiredResourceOwnershipParams {\n labels: Record<string, string> | undefined;\n ownerLabel: string | undefined;\n appName: string;\n appId: string | undefined;\n resourceType: string;\n resourceName: string;\n conflicts: OwnerConflict[];\n unmanaged: UnmanagedResource[];\n}\n\n/**\n * Determine whether a same-named existing resource is managed by this app.\n * Records the user-facing confirmation data when ownership does not match.\n * @param params - Ownership classification inputs\n * @param params.labels - Existing resource labels\n * @param params.ownerLabel - Existing `sdk-name` label, when present\n * @param params.appName - Current application name\n * @param params.appId - Current application id, when present\n * @param params.resourceType - Resource kind for confirmation messages\n * @param params.resourceName - Resource name for confirmation messages\n * @param params.conflicts - Conflict accumulator\n * @param params.unmanaged - Unmanaged-resource accumulator\n * @returns True when the resource is owned by the current app\n */\nexport function trackDesiredResourceOwnership(\n params: TrackDesiredResourceOwnershipParams,\n): boolean {\n const { labels, ownerLabel, appName, appId, resourceType, resourceName, conflicts, unmanaged } =\n params;\n const owned = isOwnedByApp(labels, appName, appId);\n if (!owned) {\n if (!ownerLabel) {\n unmanaged.push({ resourceType, resourceName });\n } else {\n conflicts.push({\n resourceType,\n resourceName,\n currentOwner: ownerLabel,\n });\n }\n }\n return owned;\n}\n\nexport interface TrackRemainingResourceOwnerParams {\n labels: Record<string, string> | undefined;\n ownerLabel: string | undefined;\n appName: string;\n appId: string | undefined;\n resourceOwners: Set<string>;\n}\n\n/**\n * Determine whether a remote-only resource is still owned by this app.\n * Also records other SDK owners so renamed-empty applications can be handled.\n * @param params - Ownership classification inputs\n * @param params.labels - Existing resource labels\n * @param params.ownerLabel - Existing `sdk-name` label, when present\n * @param params.appName - Current application name\n * @param params.appId - Current application id, when present\n * @param params.resourceOwners - Other-owner accumulator\n * @returns True when the resource is owned by the current app\n */\nexport function trackRemainingResourceOwner(params: TrackRemainingResourceOwnerParams): boolean {\n const { labels, ownerLabel, appName, appId, resourceOwners } = params;\n const owned = isOwnedByApp(labels, appName, appId);\n if (ownerLabel && !owned) {\n resourceOwners.add(ownerLabel);\n }\n return owned;\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n type AddCustomDomainRequestSchema,\n type CreateStaticWebsiteRequestSchema,\n type DeleteStaticWebsiteRequestSchema,\n type RemoveCustomDomainRequestSchema,\n type UpdateStaticWebsiteRequestSchema,\n} from \"@tailor-platform/tailor-proto/staticwebsite_pb\";\nimport { getOrNull, type OperatorClient } from \"#/cli/shared/client\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { StaticWebsite as ProtoStaticWebsite } from \"@tailor-platform/tailor-proto/staticwebsite_resource_pb\";\n\n/**\n * Apply static website changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned static website changes\n * @param phase - Apply phase\n * @returns Promise that resolves when static websites are applied\n */\nexport async function applyStaticWebsite(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planStaticWebsite>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n) {\n const { changeSet, customDomainChangeSet } = result;\n if (phase === \"create-update\") {\n // StaticWebsites\n await Promise.all([\n ...changeSet.creates.map(async (create) => {\n await client.createStaticWebsite(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n await client.updateStaticWebsite(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n // Custom domains\n await Promise.all([\n ...customDomainChangeSet.creates.map(async (add) => {\n await client.addCustomDomain(add.request);\n await writeMetadataLabels(client, add.metaRequest);\n }),\n ...customDomainChangeSet.deletes.map((del) => client.removeCustomDomain(del.request)),\n ]);\n } else {\n // Delete in reverse order of dependencies\n // StaticWebsites\n await Promise.all(changeSet.deletes.map((del) => client.deleteStaticWebsite(del.request)));\n }\n}\n\ntype CreateStaticWebsite = {\n name: string;\n request: MessageInitShape<typeof CreateStaticWebsiteRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateStaticWebsite = {\n name: string;\n request: MessageInitShape<typeof UpdateStaticWebsiteRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteStaticWebsite = {\n name: string;\n request: MessageInitShape<typeof DeleteStaticWebsiteRequestSchema>;\n};\n\ntype AddCustomDomainEntry = {\n name: string;\n request: MessageInitShape<typeof AddCustomDomainRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype RemoveCustomDomainEntry = {\n name: string;\n request: MessageInitShape<typeof RemoveCustomDomainRequestSchema>;\n};\n\ntype ComparableStaticWebsite = {\n description: string;\n allowedIpAddresses: string[];\n};\n\ntype ComparableStaticWebsiteInput = {\n description?: string;\n allowedIpAddresses?: readonly string[];\n};\n\nfunction customDomainTrn(workspaceId: string, websiteName: string, domain: string) {\n return `trn:v1:workspace:${workspaceId}:staticwebsite:${websiteName}:custom_domain:${domain}`;\n}\n\nfunction normalizeComparableStaticWebsiteShape(\n input: Pick<ComparableStaticWebsite, \"description\" | \"allowedIpAddresses\">,\n): ComparableStaticWebsite {\n return {\n description: input.description,\n allowedIpAddresses: input.allowedIpAddresses.toSorted(),\n };\n}\n\nfunction normalizeComparableStaticWebsite(\n input: ComparableStaticWebsiteInput,\n): ComparableStaticWebsite {\n return normalizeComparableStaticWebsiteShape({\n description: input.description || \"\",\n allowedIpAddresses: [...(input.allowedIpAddresses || [])],\n });\n}\n\nfunction areStaticWebsitesEqual(\n existing: ProtoStaticWebsite,\n desired: ComparableStaticWebsiteInput,\n): boolean {\n return areNormalizedEqual(\n normalizeComparableStaticWebsite(existing),\n normalizeComparableStaticWebsite(desired),\n );\n}\n\n/**\n * Static website names expected to exist after this deploy run.\n * @param context - Planning context\n * @returns Names from the deploy-run scope when set, otherwise the application's own websites\n */\nexport function expectedLocalStaticWebsiteNames(context: PlanContext): ReadonlySet<string> {\n return (\n context.expectedLocalStaticWebsiteNames ??\n new Set(context.application.staticWebsiteServices.map((website) => website.name))\n );\n}\n\n/**\n * Plan static website changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes\n */\nexport async function planStaticWebsite(context: PlanContext) {\n const { client, workspaceId, application, forRemoval } = context;\n const changeSet = createChangeSet<CreateStaticWebsite, UpdateStaticWebsite, DeleteStaticWebsite>(\n \"StaticWebsites\",\n );\n const customDomainChangeSet = createChangeSet<\n AddCustomDomainEntry,\n never,\n RemoveCustomDomainEntry\n >(\"CustomDomains\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingWebsites = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, pageSize) => {\n const { staticwebsites, nextPageToken } = await client.listStaticWebsites({\n workspaceId,\n pageToken,\n pageSize,\n });\n return [staticwebsites, nextPageToken];\n },\n getName: (resource) => resource.name,\n getTrn: (name) => resourceTrn(workspaceId, \"staticwebsite\", name),\n });\n\n // Track owned website names to plan custom domains afterward\n const ownedWebsiteNames = new Set<string>();\n\n const staticWebsiteServices = forRemoval ? [] : application.staticWebsiteServices;\n for (const websiteService of staticWebsiteServices) {\n const config = websiteService;\n const name = websiteService.name;\n const existing = existingWebsites[name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"staticwebsite\", name),\n appName: application.name,\n appId: application.id,\n });\n const desired = normalizeComparableStaticWebsite(config);\n const request = {\n workspaceId,\n staticwebsite: {\n name,\n description: config.description || \"\",\n allowedIpAddresses: config.allowedIpAddresses || [],\n },\n };\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName: application.name,\n appId: application.id,\n resourceType: \"StaticWebsite\",\n resourceName: name,\n conflicts,\n unmanaged,\n });\n\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n areStaticWebsitesEqual(existing.resource as ProtoStaticWebsite, desired)\n ) {\n changeSet.unchanged.push({ name });\n } else {\n changeSet.updates.push({\n name,\n request,\n metaRequest,\n });\n }\n\n if (owned) {\n ownedWebsiteNames.add(name);\n }\n delete existingWebsites[name];\n } else {\n changeSet.creates.push({\n name,\n request,\n metaRequest,\n });\n // New websites are owned by this app\n ownedWebsiteNames.add(name);\n }\n }\n Object.entries(existingWebsites).forEach(([name]) => {\n const entry = existingWebsites[name];\n const label = entry?.label;\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: label,\n appName: application.name,\n appId: application.id,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n name,\n },\n });\n }\n });\n\n // Plan custom domain changes for owned websites\n const desiredDomainsByWebsite = new Map<string, readonly string[]>();\n for (const service of staticWebsiteServices) {\n if (service.customDomains !== undefined && ownedWebsiteNames.has(service.name)) {\n desiredDomainsByWebsite.set(service.name, service.customDomains);\n }\n }\n\n // Fetch existing custom domains and their labels for owned websites that already exist\n type ExistingDomainInfo = { domain: string; allLabels: Record<string, string> | undefined };\n const existingDomainsByWebsite = new Map<string, ExistingDomainInfo[]>();\n const websitesToFetchDomains = [...ownedWebsiteNames].filter(\n (name) => !changeSet.creates.some((c) => c.name === name),\n );\n await Promise.all(\n websitesToFetchDomains.map(async (name) => {\n const domainsWithLabels = await getOrNull(async () => {\n const { customDomains } = await client.listCustomDomains({\n workspaceId,\n staticWebsiteName: name,\n });\n return await Promise.all(\n customDomains.map(async (d) => {\n const { metadata } = await client.getMetadata({\n trn: customDomainTrn(workspaceId, name, d.domain),\n });\n return {\n domain: d.domain,\n allLabels: metadata?.labels,\n };\n }),\n );\n });\n if (domainsWithLabels) {\n existingDomainsByWebsite.set(name, domainsWithLabels);\n }\n }),\n );\n\n // Diff custom domains for each owned website\n for (const name of ownedWebsiteNames) {\n const desired = new Set(desiredDomainsByWebsite.get(name) ?? []);\n const existingDomains = existingDomainsByWebsite.get(name) ?? [];\n const existingSet = new Set(existingDomains.map((d) => d.domain));\n const sdkOwnedDomains = new Set(\n existingDomains\n .filter((d) => isOwnedByApp(d.allLabels, application.name, application.id))\n .map((d) => d.domain),\n );\n\n for (const domain of desired) {\n if (!existingSet.has(domain)) {\n const metaRequest = await buildMetaRequest({\n trn: customDomainTrn(workspaceId, name, domain),\n appName: application.name,\n appId: application.id,\n });\n customDomainChangeSet.creates.push({\n name: domain,\n request: { workspaceId, staticWebsiteName: name, domain },\n metaRequest,\n });\n } else {\n customDomainChangeSet.unchanged.push({ name: domain });\n }\n }\n\n // Only remove SDK-owned domains not in desired if customDomains is explicitly specified\n if (desiredDomainsByWebsite.has(name)) {\n for (const domain of sdkOwnedDomains) {\n if (!desired.has(domain)) {\n customDomainChangeSet.deletes.push({\n name: domain,\n request: { workspaceId, domain },\n });\n }\n }\n }\n }\n\n return { changeSet, customDomainChangeSet, conflicts, unmanaged, resourceOwners };\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n type CreateAIGatewayRequestSchema,\n type DeleteAIGatewayRequestSchema,\n type UpdateAIGatewayRequestSchema,\n} from \"@tailor-platform/tailor-proto/aigateway_pb\";\nimport { resolveStaticWebsiteUrls, type OperatorClient } from \"#/cli/shared/client\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport { expectedLocalStaticWebsiteNames } from \"./staticwebsite\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { AIGateway as ProtoAIGateway } from \"@tailor-platform/tailor-proto/aigateway_resource_pb\";\n\n/**\n * Apply AI Gateway changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned AI Gateway changes\n * @param phase - Apply phase\n * @returns Promise that resolves when AI Gateways are applied\n */\nexport async function applyAIGateway(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planAIGateway>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n) {\n const { changeSet } = result;\n if (phase === \"create-update\") {\n await Promise.all([\n ...changeSet.creates.map(async (create) => {\n create.request.cors = await resolveStaticWebsiteUrls(\n client,\n assertDefined(create.request.workspaceId, \"request missing workspaceId\"),\n create.request.cors,\n \"AIGateway CORS\",\n );\n await client.createAIGateway(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n update.request.cors = await resolveStaticWebsiteUrls(\n client,\n assertDefined(update.request.workspaceId, \"request missing workspaceId\"),\n update.request.cors,\n \"AIGateway CORS\",\n );\n await client.updateAIGateway(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n } else {\n await Promise.all(changeSet.deletes.map((del) => client.deleteAIGateway(del.request)));\n }\n}\n\ntype CreateAIGateway = {\n name: string;\n request: MessageInitShape<typeof CreateAIGatewayRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateAIGateway = {\n name: string;\n request: MessageInitShape<typeof UpdateAIGatewayRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteAIGateway = {\n name: string;\n request: MessageInitShape<typeof DeleteAIGatewayRequestSchema>;\n};\n\ntype ComparableAIGateway = {\n authNamespace: string;\n cors: string[];\n};\n\ntype ComparableAIGatewayInput = {\n authNamespace?: string;\n cors?: readonly string[];\n};\n\nfunction normalizeComparableAIGatewayShape(\n input: Pick<ComparableAIGateway, \"authNamespace\" | \"cors\">,\n): ComparableAIGateway {\n return {\n authNamespace: input.authNamespace,\n cors: input.cors.toSorted(),\n };\n}\n\nfunction normalizeComparableAIGateway(input: ComparableAIGatewayInput): ComparableAIGateway {\n return normalizeComparableAIGatewayShape({\n authNamespace: input.authNamespace || \"\",\n cors: [...(input.cors || [])],\n });\n}\n\nfunction areAIGatewaysEqual(existing: ProtoAIGateway, desired: ComparableAIGatewayInput): boolean {\n return areNormalizedEqual(\n normalizeComparableAIGateway(existing),\n normalizeComparableAIGateway(desired),\n );\n}\n\n/**\n * Plan AI Gateway changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes\n */\nexport async function planAIGateway(context: PlanContext) {\n const { client, workspaceId, application, forRemoval } = context;\n const changeSet = createChangeSet<CreateAIGateway, UpdateAIGateway, DeleteAIGateway>(\n \"AIGateways\",\n );\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingGateways = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, pageSize) => {\n const { aigateways, nextPageToken } = await client.listAIGateways({\n workspaceId,\n pageToken,\n pageSize,\n });\n return [aigateways, nextPageToken];\n },\n getName: (resource) => resource.name,\n getTrn: (name) => resourceTrn(workspaceId, \"aigateway\", name),\n });\n\n const aiGatewayServices = forRemoval ? [] : application.aiGatewayServices;\n const expectedLocalWebsites = expectedLocalStaticWebsiteNames(context);\n for (const gatewayService of aiGatewayServices) {\n const config = gatewayService;\n const name = gatewayService.name;\n const existing = existingGateways[name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"aigateway\", name),\n appName: application.name,\n appId: application.id,\n });\n const resolvedCors = await resolveStaticWebsiteUrls(\n client,\n workspaceId,\n config.cors ? [...config.cors] : [],\n \"AIGateway CORS\",\n { expectedLocalNames: expectedLocalWebsites },\n );\n const desired = normalizeComparableAIGateway({ ...config, cors: resolvedCors });\n const request = {\n workspaceId,\n aigatewayName: name,\n authNamespace: config.authNamespace,\n cors: config.cors ? [...config.cors] : [],\n };\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName: application.name,\n appId: application.id,\n resourceType: \"AIGateway\",\n resourceName: name,\n conflicts,\n unmanaged,\n });\n\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n areAIGatewaysEqual(existing.resource as ProtoAIGateway, desired)\n ) {\n changeSet.unchanged.push({ name });\n } else {\n changeSet.updates.push({\n name,\n request,\n metaRequest,\n });\n }\n delete existingGateways[name];\n } else {\n changeSet.creates.push({\n name,\n request,\n metaRequest,\n });\n }\n }\n Object.entries(existingGateways).forEach(([name, entry]) => {\n const label = entry?.label;\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: label,\n appName: application.name,\n appId: application.id,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n aigatewayName: name,\n },\n });\n }\n });\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n type Application as ProtoApplication,\n Subgraph_ServiceType,\n type SubgraphSchema,\n} from \"@tailor-platform/tailor-proto/application_resource_pb\";\nimport {\n fetchAllTolerant,\n getOrNull,\n resolveStaticWebsiteUrls,\n type OperatorClient,\n} from \"#/cli/shared/client\";\nimport { symbols } from \"#/cli/shared/logger\";\nimport { HTTP_METHODS } from \"#/parser/service/http-adapter/index\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n type MetadataLabelWrite,\n resourceTrn,\n sdkNameLabelKey,\n writeMetadataLabels,\n} from \"./label\";\nimport { trackDesiredResourceOwnership, trackRemainingResourceOwner } from \"./owned-resource\";\nimport { expectedLocalStaticWebsiteNames } from \"./staticwebsite\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { Application } from \"#/cli/services/application\";\nimport type { HttpAdapterBundleResult } from \"#/cli/services/http-adapter/bundler\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type {\n DeleteApplicationRequestSchema,\n CreateApplicationRequestSchema,\n UpdateApplicationRequestSchema,\n} from \"@tailor-platform/tailor-proto/application_pb\";\nimport type { HttpAdapterSchema } from \"@tailor-platform/tailor-proto/http_adapter_resource_pb\";\n\n/**\n * Apply application changes for the given phase.\n * @param client - Operator client instance\n * @param changeSet - Planned application changes\n * @param phase - Apply phase\n * @returns Promise that resolves when applications are applied\n */\nexport async function applyApplication(\n client: OperatorClient,\n changeSet: Awaited<ReturnType<typeof planApplication>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n) {\n if (phase === \"create-update\") {\n // Re-issue updateApplication for unchanged apps too, so the platform\n // re-composes the gateway schema synchronously on every deploy.\n const updates = [...changeSet.updates, ...changeSet.unchanged];\n await Promise.all([\n ...changeSet.creates.map(async (create) => {\n create.request.cors = await resolveStaticWebsiteUrls(\n client,\n assertDefined(create.request.workspaceId, \"request missing workspaceId\"),\n create.request.cors,\n \"CORS\",\n );\n await client.createApplication(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...updates.map(async (update) => {\n update.request.cors = await resolveStaticWebsiteUrls(\n client,\n assertDefined(update.request.workspaceId, \"request missing workspaceId\"),\n update.request.cors,\n \"CORS\",\n );\n await client.updateApplication(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n } else {\n // Delete in reverse order of dependencies\n // Applications\n await Promise.all(\n changeSet.deletes.map(async (del) => {\n await client.deleteApplication(del.request);\n }),\n );\n }\n}\n\ntype CreateApplication = {\n name: string;\n request: MessageInitShape<typeof CreateApplicationRequestSchema>;\n metaRequest: MetadataLabelWrite;\n /** Per-adapter diff lines shown indented beneath the application entry. */\n details?: string[];\n};\n\ntype UpdateApplication = {\n name: string;\n request: MessageInitShape<typeof UpdateApplicationRequestSchema>;\n metaRequest: MetadataLabelWrite;\n /** Per-adapter diff lines shown indented beneath the application entry. */\n details?: string[];\n};\n\ntype DeleteApplication = {\n name: string;\n request: MessageInitShape<typeof DeleteApplicationRequestSchema>;\n};\n\ntype ComparableHttpAdapter = {\n name: string;\n pathPattern: string;\n methods: string[];\n inputScript: string;\n outputScript: string;\n enabled: boolean;\n priority: number;\n};\n\ntype ComparableApplication = {\n authNamespace: string;\n authIdpConfigName: string;\n cors: string[];\n subgraphs: Array<{\n serviceType: Subgraph_ServiceType;\n serviceNamespace: string;\n }>;\n allowedIpAddresses: string[];\n disableIntrospection: boolean;\n disabled: boolean;\n httpAdapters: ComparableHttpAdapter[];\n};\n\nfunction sortStrings(values: readonly string[] | undefined): string[] {\n return (values ?? []).toSorted();\n}\n\nfunction normalizeSubgraphs(\n subgraphs: ReadonlyArray<MessageInitShape<typeof SubgraphSchema>> | undefined,\n): ComparableApplication[\"subgraphs\"] {\n return [...(subgraphs ?? [])]\n .map((subgraph) => ({\n serviceType: assertDefined(subgraph.serviceType, \"subgraph missing serviceType\"),\n serviceNamespace: subgraph.serviceNamespace ?? \"\",\n }))\n .toSorted((left, right) => {\n if (left.serviceType !== right.serviceType) {\n return left.serviceType - right.serviceType;\n }\n return left.serviceNamespace.localeCompare(right.serviceNamespace);\n });\n}\n\nfunction normalizeHttpAdapters(\n httpAdapters:\n | ReadonlyArray<{\n name?: string;\n pathPattern?: string;\n methods?: string[];\n inputScript?: string;\n outputScript?: string;\n enabled?: boolean;\n priority?: number;\n }>\n | undefined,\n): ComparableHttpAdapter[] {\n return [...(httpAdapters ?? [])]\n .map((adapter) => ({\n name: adapter.name ?? \"\",\n pathPattern: adapter.pathPattern ?? \"\",\n methods: sortStrings(adapter.methods),\n inputScript: adapter.inputScript ?? \"\",\n outputScript: adapter.outputScript ?? \"\",\n // Fallbacks mirror the schema defaults; in practice both sides always\n // carry explicit values (the SDK sets them and proto bools are present).\n enabled: adapter.enabled ?? true,\n priority: adapter.priority ?? 0,\n }))\n .toSorted((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction toComparableApplication(\n input: Pick<\n ComparableApplication,\n | \"authNamespace\"\n | \"authIdpConfigName\"\n | \"cors\"\n | \"subgraphs\"\n | \"allowedIpAddresses\"\n | \"disableIntrospection\"\n | \"disabled\"\n | \"httpAdapters\"\n >,\n): ComparableApplication {\n return {\n authNamespace: input.authNamespace,\n authIdpConfigName: input.authIdpConfigName,\n cors: sortStrings(input.cors),\n subgraphs: [...input.subgraphs],\n allowedIpAddresses: sortStrings(input.allowedIpAddresses),\n disableIntrospection: input.disableIntrospection,\n disabled: input.disabled,\n httpAdapters: [...input.httpAdapters],\n };\n}\n\nfunction normalizeComparableApplication(\n application: Readonly<Application>,\n authNamespace: string | undefined,\n authIdpConfigName: string | undefined,\n cors: string[],\n httpAdapters: ReadonlyArray<MessageInitShape<typeof HttpAdapterSchema>>,\n): ComparableApplication {\n return toComparableApplication({\n authNamespace: authNamespace ?? \"\",\n authIdpConfigName: authIdpConfigName ?? \"\",\n cors,\n subgraphs: normalizeSubgraphs(application.subgraphs.map((subgraph) => protoSubgraph(subgraph))),\n allowedIpAddresses: application.config.allowedIpAddresses ?? [],\n disableIntrospection: application.config.disableIntrospection ?? false,\n disabled: false,\n httpAdapters: normalizeHttpAdapters(httpAdapters),\n });\n}\n\nfunction normalizeComparableExistingApplication(app: ProtoApplication): ComparableApplication {\n return toComparableApplication({\n authNamespace: app.authNamespace,\n authIdpConfigName: app.authIdpConfigName,\n cors: app.cors,\n subgraphs: normalizeSubgraphs(app.subgraphs),\n allowedIpAddresses: app.allowedIpAddresses,\n disableIntrospection: app.disableIntrospection,\n disabled: app.disabled,\n httpAdapters: normalizeHttpAdapters(app.httpAdapters),\n });\n}\n\nfunction areApplicationsEqual(existing: ProtoApplication, desired: ComparableApplication): boolean {\n return areNormalizedEqual(normalizeComparableExistingApplication(existing), desired);\n}\n\n/**\n * Plan application changes based on current and desired state.\n * @param context - Planning context\n * @param httpAdapterBuildResult - Bundled HTTP adapter scripts to embed on the Application\n * @returns Planned changes\n */\nexport async function planApplication(\n context: PlanContext,\n httpAdapterBuildResult?: HttpAdapterBundleResult,\n) {\n const { client, workspaceId, application, forRemoval } = context;\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n const changeSet = createChangeSet<\n CreateApplication,\n UpdateApplication,\n DeleteApplication,\n never,\n UpdateApplication\n >(\"Applications\");\n\n const existingApplications = await fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { applications, nextPageToken } = await client.listApplications({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [applications, nextPageToken];\n });\n\n if (forRemoval) {\n // A same-named app in a shared workspace may belong to another user, so\n // never delete by name alone. Without an id only the same-name app can be\n // ours; with an id, scan all apps to also clean up renamed-away ones.\n const candidates = application.id\n ? existingApplications\n : existingApplications.filter((app) => app.name === application.name);\n const owned = await Promise.all(\n candidates.map(async (app) => {\n const labels = await fetchAppLabels(client, workspaceId, app.name);\n return trackRemainingResourceOwner({\n labels,\n ownerLabel: labels?.[sdkNameLabelKey],\n appName: application.name,\n appId: application.id,\n resourceOwners,\n })\n ? app.name\n : null;\n }),\n );\n for (const name of owned) {\n if (name) {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n applicationName: name,\n },\n });\n }\n }\n return withOwnership(changeSet, conflicts, unmanaged, resourceOwners);\n }\n\n // Skip application create/update when there are no subgraphs\n // (e.g. deploying only static web hosting)\n if (application.subgraphs.length === 0) {\n return withOwnership(changeSet, conflicts, unmanaged, resourceOwners);\n }\n\n let authNamespace: string | undefined;\n let authIdpConfigName: string | undefined;\n if (application.authService) {\n authNamespace = application.authService.config.name;\n\n const idProvider = application.authService.config.idProvider;\n if (idProvider) {\n authIdpConfigName = idProvider.name;\n }\n } else if (application.config.auth) {\n // Prefer peer plans for same-run multi-config deploys; otherwise read remote state.\n authNamespace = application.config.auth.name;\n if (context.externalAuthIdpConfigNames?.has(authNamespace)) {\n authIdpConfigName = context.externalAuthIdpConfigNames.get(authNamespace);\n } else {\n const idpConfigs = await fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { idpConfigs, nextPageToken } = await client.listAuthIDPConfigs({\n workspaceId,\n namespaceName: assertDefined(\n authNamespace,\n \"authNamespace must be set before listing IDP configs\",\n ),\n pageToken,\n pageSize: maxPageSize,\n });\n return [idpConfigs, nextPageToken];\n });\n if (idpConfigs.length > 0) {\n const [firstConfig] = idpConfigs;\n if (firstConfig) {\n authIdpConfigName = firstConfig.name;\n }\n }\n }\n }\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"application\", application.name),\n appName: application.name,\n appId: application.id,\n });\n const existingLabels = await fetchAppLabels(client, workspaceId, application.name);\n const expectedLocalWebsites = expectedLocalStaticWebsiteNames(context);\n const resolvedCors = await resolveStaticWebsiteUrls(\n client,\n workspaceId,\n application.config.cors,\n \"CORS\",\n { expectedLocalNames: expectedLocalWebsites },\n );\n const httpAdapters = buildHttpAdapters(application, httpAdapterBuildResult);\n const desired = normalizeComparableApplication(\n application,\n authNamespace,\n authIdpConfigName,\n resolvedCors,\n httpAdapters,\n );\n const request = {\n workspaceId,\n applicationName: application.name,\n authNamespace,\n authIdpConfigName,\n cors: application.config.cors,\n subgraphs: application.subgraphs.map((subgraph) => protoSubgraph(subgraph)),\n allowedIpAddresses: application.config.allowedIpAddresses,\n disableIntrospection: application.config.disableIntrospection,\n httpAdapters,\n };\n const existing = existingApplications.find((app) => app.name === application.name);\n\n // Detect renames: other apps owned by our id should be deleted before\n // creating/updating the current name (so the old name is freed up).\n if (application.id) {\n const otherApps = existingApplications.filter((app) => app.name !== application.name);\n const renamedAway = await Promise.all(\n otherApps.map(async (app) => {\n const labels = await fetchAppLabels(client, workspaceId, app.name);\n return isOwnedByApp(labels, application.name, application.id) ? app.name : null;\n }),\n );\n for (const name of renamedAway) {\n if (name) {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n applicationName: name,\n },\n });\n }\n }\n }\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existingLabels,\n ownerLabel: existingLabels?.[sdkNameLabelKey],\n appName: application.name,\n appId: application.id,\n resourceType: \"Application\",\n resourceName: application.name,\n conflicts,\n unmanaged,\n });\n const update: UpdateApplication = {\n name: application.name,\n request,\n metaRequest,\n };\n if (\n owned &&\n hasMatchingSdkVersion(existingLabels, metaRequest.labels) &&\n areApplicationsEqual(existing, desired)\n ) {\n // Plan display shows this as unchanged, but apply still re-issues it.\n changeSet.unchanged.push(update);\n } else {\n const details = diffHttpAdapterDisplay(existing.httpAdapters, httpAdapters);\n if (details.length > 0) {\n update.details = details;\n }\n changeSet.updates.push(update);\n }\n } else {\n const details = diffHttpAdapterDisplay(undefined, httpAdapters);\n changeSet.creates.push({\n name: application.name,\n request,\n metaRequest,\n details: details.length > 0 ? details : undefined,\n });\n }\n\n return withOwnership(changeSet, conflicts, unmanaged, resourceOwners);\n}\n\n/**\n * Attach the ownership-tracking fields to the plan's change set.\n *\n * The other resource plans return `{ changeSet, conflicts, ... }`; this one\n * returns the change set itself, so the fields are attached to it. Without\n * them the application is the one managed resource that never reaches\n * `confirmOwnerConflict`, which would let a deploy re-tag — or a `remove`\n * silently skip — an application this config does not own.\n * @param changeSet - The application change set\n * @param conflicts - Resources owned by another application\n * @param unmanaged - Resources carrying no SDK label\n * @param resourceOwners - Owners of the resources that were skipped\n * @returns The change set, with the ownership-tracking fields attached\n */\nfunction withOwnership<T extends object>(\n changeSet: T,\n conflicts: OwnerConflict[],\n unmanaged: UnmanagedResource[],\n resourceOwners: Set<string>,\n): T & { conflicts: OwnerConflict[]; unmanaged: UnmanagedResource[]; resourceOwners: Set<string> } {\n return Object.assign(changeSet, { conflicts, unmanaged, resourceOwners });\n}\n\nasync function fetchAppLabels(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n): Promise<Record<string, string> | undefined> {\n const response = await getOrNull(async () => {\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"application\", appName),\n });\n return metadata;\n });\n return response?.labels;\n}\n\n/**\n * Build per-adapter diff lines for the application plan display. The platform\n * models HTTP adapters as an embedded Application field (no dedicated RPC), so\n * adapter changes surface as an Application update; these lines show which\n * adapter actually changed instead of just `~ <app>`.\n * @param existingAdapters - HTTP adapters currently deployed on the application\n * @param desiredAdapters - HTTP adapters built from the local config\n * @returns Indented diff lines (`+`/`~`/`-` per adapter), sorted by name\n */\nexport function diffHttpAdapterDisplay(\n existingAdapters: ReadonlyArray<MessageInitShape<typeof HttpAdapterSchema>> | undefined,\n desiredAdapters: ReadonlyArray<MessageInitShape<typeof HttpAdapterSchema>>,\n): string[] {\n const existingByName = new Map((existingAdapters ?? []).map((a) => [a.name ?? \"\", a]));\n const desiredByName = new Map(desiredAdapters.map((a) => [a.name ?? \"\", a]));\n const entries: Array<{ name: string; symbol: string }> = [];\n for (const [name, desired] of desiredByName) {\n const existing = existingByName.get(name);\n if (!existing) {\n entries.push({ name, symbol: symbols.create });\n } else if (\n !areNormalizedEqual(normalizeHttpAdapters([existing])[0], normalizeHttpAdapters([desired])[0])\n ) {\n entries.push({ name, symbol: symbols.update });\n }\n }\n for (const name of existingByName.keys()) {\n if (!desiredByName.has(name)) {\n entries.push({ name, symbol: symbols.delete });\n }\n }\n return entries\n .toSorted((left, right) => left.name.localeCompare(right.name))\n .map((entry) => `${entry.symbol} ${entry.name} (httpAdapter)`);\n}\n\nfunction buildHttpAdapters(\n application: Readonly<Application>,\n httpAdapterBuildResult: HttpAdapterBundleResult | undefined,\n): MessageInitShape<typeof HttpAdapterSchema>[] {\n const adapters = application.httpAdapterService?.adapters ?? [];\n if (adapters.length === 0) {\n return [];\n }\n return adapters.map((loaded) => {\n const inputScript = httpAdapterBuildResult?.bundledInputs.get(loaded.adapter.name);\n if (!inputScript) {\n throw new Error(\n `HTTP adapter \"${loaded.adapter.name}\" was loaded but no bundled input script is available`,\n );\n }\n let outputScript = \"\";\n if (loaded.hasOutput) {\n const bundled = httpAdapterBuildResult?.bundledOutputs.get(loaded.adapter.name);\n if (!bundled) {\n throw new Error(\n `HTTP adapter \"${loaded.adapter.name}\" declares an output handler but no bundled output script is available`,\n );\n }\n outputScript = bundled;\n }\n return {\n name: loaded.adapter.name,\n pathPattern: loaded.adapter.pathPattern,\n methods: loaded.methods.map((m) => HTTP_METHODS[m]),\n inputScript,\n outputScript,\n // `enabled`/`priority` are always populated here because\n // HttpAdapterConfigSchema applies their defaults during parse.\n enabled: loaded.adapter.enabled,\n priority: loaded.adapter.priority,\n };\n });\n}\n\nfunction protoSubgraph(\n subgraph: Readonly<{ Type: string; Name: string }>,\n): MessageInitShape<typeof SubgraphSchema> {\n // TODO(remiposo): Make it type-safe\n let serviceType: Subgraph_ServiceType;\n switch (subgraph.Type) {\n case \"tailordb\":\n serviceType = Subgraph_ServiceType.TAILORDB;\n break;\n case \"pipeline\":\n serviceType = Subgraph_ServiceType.PIPELINE;\n break;\n case \"idp\":\n serviceType = Subgraph_ServiceType.IDP;\n break;\n case \"auth\":\n serviceType = Subgraph_ServiceType.AUTH;\n break;\n default:\n throw new Error(`Unknown subgraph type: ${subgraph.Type}`);\n }\n return {\n serviceType,\n serviceNamespace: subgraph.Name,\n };\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport {\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n utimesSync,\n writeFileSync,\n} from \"node:fs\";\nimport pLimit, { type LimitFunction } from \"p-limit\";\nimport * as path from \"pathe\";\nimport { z } from \"zod\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\n\n// strip unknown keys\nconst SecretsStateEntrySchema = z.object({\n hash: z.string(),\n updateTime: z.string().optional(),\n});\n\n// strip unknown keys\nconst SecretsStateSchema = z.object({\n vaults: z.record(z.string(), z.record(z.string(), SecretsStateEntrySchema)),\n connections: z.record(z.string(), z.string()).optional(),\n});\n\n// strip unknown keys\nconst PersistedSecretsStateSchema = z.object({\n version: z.literal(2),\n workspaceId: z.string(),\n applicationKey: z.string(),\n state: SecretsStateSchema,\n});\n\nexport type SecretsState = z.infer<typeof SecretsStateSchema>;\ntype PersistedSecretsState = z.infer<typeof PersistedSecretsStateSchema>;\n\nexport interface SecretsStateScope {\n readonly workspaceId: string;\n readonly applicationId: string | undefined;\n readonly applicationName: string;\n}\n\n/**\n * Get the file path for one workspace and application's secrets state JSON.\n * @param scope - Workspace and application identity for the deployment\n * @returns Absolute path to the scoped state file\n */\nexport function getSecretsStatePath(scope: SecretsStateScope): string {\n const scopeHash = hashValue(JSON.stringify([scope.workspaceId, applicationStateKey(scope)]));\n return path.join(getDistDir(), \"secrets-state\", `${scopeHash}.json`);\n}\n\nfunction loadPersistedSecretsState(scope: SecretsStateScope): PersistedSecretsState | undefined {\n try {\n const raw = readFileSync(getSecretsStatePath(scope), \"utf-8\");\n const persistedState = PersistedSecretsStateSchema.parse(JSON.parse(raw));\n if (\n persistedState.workspaceId !== scope.workspaceId ||\n persistedState.applicationKey !== applicationStateKey(scope)\n ) {\n return undefined;\n }\n return persistedState;\n } catch {\n return undefined;\n }\n}\n\nfunction applicationStateKey(scope: SecretsStateScope): string {\n if (!scope.applicationId) {\n throw new Error(`Application \"${scope.applicationName}\" has no stable id for secrets state`);\n }\n return `id:${scope.applicationId}`;\n}\n\n/**\n * Load secrets hash state for one workspace and application from disk.\n * @param scope - Workspace and application identity for the deployment\n * @returns Persisted state, or empty state if the scope is missing or the file is invalid\n */\nexport function loadSecretsState(scope: SecretsStateScope): SecretsState {\n if (!scope.applicationId) {\n return { vaults: {} };\n }\n return loadPersistedSecretsState(scope)?.state ?? { vaults: {} };\n}\n\n/**\n * Save secrets hash state for one workspace and application to disk.\n * @param scope - Workspace and application identity for the deployment\n * @param state - The secrets state to persist\n */\nexport function saveSecretsState(scope: SecretsStateScope, state: SecretsState): void {\n if (!scope.applicationId) {\n return;\n }\n const filePath = getSecretsStatePath(scope);\n const dir = path.dirname(filePath);\n mkdirSync(dir, { recursive: true });\n // Write via a temp file and rename so concurrent readers never see torn JSON.\n const tempPath = `${filePath}.tmp-${randomUUID()}`;\n writeFileSync(\n tempPath,\n JSON.stringify(\n {\n version: 2,\n workspaceId: scope.workspaceId,\n applicationKey: applicationStateKey(scope),\n state,\n } satisfies PersistedSecretsState,\n null,\n 2,\n ),\n \"utf-8\",\n );\n renameSync(tempPath, filePath);\n}\n\n/**\n * Compute SHA-256 hex digest of a value.\n * @param value - The string to hash\n * @returns Hex-encoded SHA-256 hash\n */\nexport function hashValue(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\n/**\n * Serialize a platform timestamp into the string stored as update evidence.\n * @param updateTime - Timestamp from a Secret Manager list or mutation response\n * @returns Serialized timestamp, or undefined when the platform sent none\n */\nexport function serializeUpdateTime(updateTime: Timestamp | undefined): string | undefined {\n return updateTime === undefined ? undefined : `${updateTime.seconds}.${updateTime.nanos}`;\n}\n\nconst LOCK_POLL_INTERVAL_MS = 100;\nconst LOCK_ACQUIRE_TIMEOUT_MS = 5 * 60 * 1000;\n// A holder refreshes the lock directory mtime while working, so a lock whose\n// mtime is older than the lease can only belong to a crashed or stopped\n// process and is safe to steal.\nconst LOCK_HEARTBEAT_INTERVAL_MS = 10 * 1000;\nconst LOCK_LEASE_MS = 60 * 1000;\n\nconst lockQueues = new Map<string, LimitFunction>();\n\n/**\n * Run a remote-update/state-save sequence exclusively for one target's secrets state.\n *\n * Serializes concurrent deploys to the same workspace and application (across\n * processes sharing the same output directory) so the persisted hash state\n * always reflects the last remote write.\n * @param scope - Workspace and application identity for the deployment\n * @param fn - Critical section performing remote updates and the state save\n * @returns The value returned by fn\n */\nexport async function withSecretsStateLock<T>(\n scope: SecretsStateScope,\n fn: () => Promise<T>,\n): Promise<T> {\n if (!scope.applicationId) {\n return fn();\n }\n const lockPath = `${getSecretsStatePath(scope)}.lock`;\n let queue = lockQueues.get(lockPath);\n if (!queue) {\n queue = pLimit(1);\n lockQueues.set(lockPath, queue);\n }\n return queue(async () => {\n const token = await acquireFileLock(lockPath);\n const heartbeat = setInterval(() => refreshLock(lockPath, token), LOCK_HEARTBEAT_INTERVAL_MS);\n heartbeat.unref();\n try {\n return await fn();\n } finally {\n clearInterval(heartbeat);\n releaseFileLock(lockPath, token);\n }\n });\n}\n\nasync function acquireFileLock(lockPath: string): Promise<string> {\n mkdirSync(path.dirname(lockPath), { recursive: true });\n const token = randomUUID();\n const deadline = Date.now() + LOCK_ACQUIRE_TIMEOUT_MS;\n for (;;) {\n let created = true;\n try {\n mkdirSync(lockPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n created = false;\n }\n if (created) {\n try {\n writeFileSync(\n path.join(lockPath, \"owner.json\"),\n JSON.stringify({ pid: process.pid, token }),\n );\n } catch (error) {\n rmSync(lockPath, { recursive: true, force: true });\n throw error;\n }\n return token;\n }\n if (isLockExpired(lockPath) && stealLock(lockPath)) {\n continue;\n }\n if (Date.now() >= deadline) {\n throw new Error(\n \"Timed out waiting for another deploy to the same workspace and application to finish. \" +\n \"Wait for it to complete and retry; an interrupted deploy recovers automatically \" +\n \"within a minute.\",\n );\n }\n await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_INTERVAL_MS));\n }\n}\n\nfunction isLockExpired(lockPath: string): boolean {\n try {\n return Date.now() - statSync(lockPath).mtimeMs > LOCK_LEASE_MS;\n } catch {\n return false;\n }\n}\n\nfunction readLockToken(lockPath: string): unknown {\n try {\n return (\n JSON.parse(readFileSync(path.join(lockPath, \"owner.json\"), \"utf-8\")) as { token?: unknown }\n ).token;\n } catch {\n return undefined;\n }\n}\n\nfunction refreshLock(lockPath: string, token: string): void {\n if (readLockToken(lockPath) !== token) {\n return;\n }\n const now = new Date();\n try {\n utimesSync(lockPath, now, now);\n } catch {\n // The lock disappeared or was stolen; the release path handles ownership.\n }\n}\n\nfunction releaseFileLock(lockPath: string, token: string): void {\n // Only remove a lock this process still owns, so a holder whose lease\n // expired cannot delete the current holder's lock.\n if (readLockToken(lockPath) !== token) {\n return;\n }\n rmSync(lockPath, { recursive: true, force: true });\n}\n\nfunction stealLock(lockPath: string): boolean {\n // Rename first so concurrent stealers cannot remove a lock that another\n // contender has just re-acquired.\n const trash = `${lockPath}.stale-${process.pid}-${Date.now()}`;\n try {\n renameSync(lockPath, trash);\n } catch {\n return false;\n }\n if (isLockExpired(trash)) {\n rmSync(trash, { recursive: true, force: true });\n return true;\n }\n // A live holder re-acquired or refreshed the lock between the expiry check\n // and the rename; hand it back.\n try {\n renameSync(trash, lockPath);\n } catch {\n rmSync(trash, { recursive: true, force: true });\n }\n return false;\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n AuthConnection_Status,\n AuthConnection_Type,\n} from \"@tailor-platform/tailor-proto/auth_resource_pb\";\nimport { type AuthService } from \"#/cli/services/auth/service\";\nimport { fetchAllTolerant, type OperatorClient } from \"#/cli/shared/client\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { createChangeSet } from \"./change-set\";\nimport {\n buildMetaRequest,\n type MetadataLabelWrite,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n writeMetadataLabels,\n} from \"./label\";\nimport { trackDesiredResourceOwnership, trackRemainingResourceOwner } from \"./owned-resource\";\nimport {\n hashValue,\n loadSecretsState,\n saveSecretsState,\n withSecretsStateLock,\n} from \"./secrets-state\";\nimport type { AuthConnectionConfig } from \"#/types/auth-connection.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase } from \"./phase\";\nimport type {\n CreateAuthConnectionRequestSchema,\n DeleteAuthConnectionRequestSchema,\n UpdateAuthConnectionRequestSchema,\n} from \"@tailor-platform/tailor-proto/auth_pb\";\nimport type { AuthConnection } from \"@tailor-platform/tailor-proto/auth_resource_pb\";\n\ntype CreateConnection = {\n name: string;\n request: MessageInitShape<typeof CreateAuthConnectionRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateConnection = {\n name: string;\n metaRequest: MetadataLabelWrite;\n};\n\ntype MaskedUpdateConnection = {\n name: string;\n updateRequest: MessageInitShape<typeof UpdateAuthConnectionRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteConnection = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthConnectionRequestSchema>;\n};\n\nfunction buildConnectionRequest(\n workspaceId: string,\n name: string,\n config: AuthConnectionConfig,\n): MessageInitShape<typeof CreateAuthConnectionRequestSchema> {\n return {\n workspaceId,\n connection: {\n name,\n type: AuthConnection_Type.OAUTH2,\n config: {\n case: \"oauth2\",\n value: {\n providerUrl: config.providerUrl,\n issuerUrl: config.issuerUrl,\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n authUrl: config.authUrl ?? \"\",\n tokenUrl: config.tokenUrl ?? \"\",\n },\n },\n },\n };\n}\n\nfunction buildUpdateMask(\n existing: AuthConnection,\n desired: AuthConnectionConfig,\n secretChanged: boolean,\n): { paths: string[] } {\n if (existing.config.case !== \"oauth2\") {\n const paths = [\n \"type\",\n \"oauth2.provider_url\",\n \"oauth2.issuer_url\",\n \"oauth2.client_id\",\n \"oauth2.auth_url\",\n \"oauth2.token_url\",\n ];\n if (desired.clientSecret) paths.push(\"oauth2.client_secret\");\n return { paths };\n }\n // The SDK only creates OAUTH2 connections, so no type change is possible here.\n const paths: string[] = [];\n const v = existing.config.value;\n if (v.providerUrl !== desired.providerUrl) paths.push(\"oauth2.provider_url\");\n if (v.issuerUrl !== desired.issuerUrl) paths.push(\"oauth2.issuer_url\");\n if (v.clientId !== desired.clientId) paths.push(\"oauth2.client_id\");\n if (v.authUrl !== (desired.authUrl ?? \"\")) paths.push(\"oauth2.auth_url\");\n if (v.tokenUrl !== (desired.tokenUrl ?? \"\")) paths.push(\"oauth2.token_url\");\n if (secretChanged && desired.clientSecret) paths.push(\"oauth2.client_secret\");\n return { paths };\n}\n\n/**\n * Plan auth connection changes based on current and desired state.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param appName - Application name for ownership\n * @param appId - Stable application id (when managed by SDK)\n * @param auths - Auth services with connection configs\n * @returns Planned changes for auth connections\n */\nexport async function planAuthConnections(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n auths: ReadonlyArray<Readonly<AuthService>>,\n) {\n const stateScope = {\n workspaceId,\n applicationId: appId,\n applicationName: appName,\n };\n const changeSet = createChangeSet<\n CreateConnection,\n UpdateConnection,\n DeleteConnection,\n MaskedUpdateConnection\n >(\"Auth connections\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const desiredConnections: Record<string, AuthConnectionConfig> = {};\n for (const auth of auths) {\n for (const [name, config] of Object.entries(auth.connections)) {\n desiredConnections[name] = config;\n }\n }\n\n const existingList = await fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { connections, nextPageToken } = await client.listAuthConnections({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [connections, nextPageToken];\n });\n\n const existingConnections: WithLabel<AuthConnection> = {};\n await Promise.all(\n existingList.map(async (resource) => {\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"auth_connection\", resource.name),\n });\n existingConnections[resource.name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\n );\n\n const state = loadSecretsState(stateScope);\n\n for (const [name, config] of Object.entries(desiredConnections)) {\n const existing = existingConnections[name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"auth_connection\", name),\n appName,\n appId,\n });\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"Auth connection\",\n resourceName: name,\n conflicts,\n unmanaged,\n });\n\n const currentHash = hashValue(config.clientSecret);\n const storedHash = state.connections?.[name];\n const secretChanged = currentHash !== storedHash;\n const updateMask = buildUpdateMask(existing.resource, config, secretChanged);\n\n if (updateMask.paths.length > 0) {\n changeSet.replaces.push({\n name,\n updateRequest: {\n ...buildConnectionRequest(workspaceId, name, config),\n updateMask,\n } as MessageInitShape<typeof UpdateAuthConnectionRequestSchema>,\n metaRequest,\n });\n } else if (!owned) {\n // The connection itself is unchanged, but this application does not own\n // it yet: it carries no SDK label (just adopted, or created by an SDK\n // that predates ownership labels), or it carries an id this config does\n // not match. Either way the labels have to be written, or the take-over\n // the user just confirmed would not happen and the next deploy would ask\n // the same question again.\n changeSet.updates.push({ name, metaRequest });\n } else {\n changeSet.unchanged.push({ name });\n }\n delete existingConnections[name];\n } else {\n changeSet.creates.push({\n name,\n request: buildConnectionRequest(workspaceId, name, config),\n metaRequest,\n });\n }\n }\n\n for (const [name, entry] of Object.entries(existingConnections)) {\n if (!entry) continue;\n const owned = trackRemainingResourceOwner({\n labels: entry.allLabels,\n ownerLabel: entry.label,\n appName,\n appId,\n resourceOwners,\n });\n // Only delete connections we own. Connections without our label are\n // treated as unowned and left untouched, even if the local secrets-state\n // happens to track them.\n if (owned) {\n changeSet.deletes.push({\n name,\n request: { workspaceId, connectionName: name },\n });\n }\n }\n\n return { changeSet, conflicts, unmanaged, resourceOwners, stateScope };\n}\n\ntype AuthConnectionApplyResult = Pick<\n Awaited<ReturnType<typeof planAuthConnections>>,\n \"changeSet\" | \"stateScope\"\n>;\n\n/**\n * Apply auth connection changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned auth connection changes\n * @param phase - Apply phase\n */\nexport async function applyAuthConnections(\n client: OperatorClient,\n result: AuthConnectionApplyResult,\n phase: Exclude<ApplyPhase, \"delete-services\">,\n) {\n const { changeSet, stateScope } = result;\n\n if (phase === \"create-update\") {\n if (changeSet.creates.length > 0 || changeSet.replaces.length > 0) {\n await withSecretsStateLock(stateScope, async () => {\n await Promise.all(\n changeSet.creates.map(async (create) => {\n await client.createAuthConnection(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n logger.info(\n `Connection \"${create.name}\" was created. Authorize it with:\\n` +\n ` tailor authconnection authorize --name ${create.name}\\n` +\n `Or via the Console: tailor authconnection open`,\n );\n }),\n );\n\n for (const replace of changeSet.replaces) {\n const resp = await client.updateAuthConnection(replace.updateRequest);\n if (resp.connection?.status === AuthConnection_Status.UNAUTHORIZED) {\n logger.warn(\n `Connection \"${replace.name}\" requires re-authorization. Authorize with:\\n` +\n ` tailor authconnection authorize --name ${replace.name}\\n` +\n `Or via the Console: tailor authconnection open`,\n );\n }\n await writeMetadataLabels(client, replace.metaRequest);\n }\n\n const secretReplaces = changeSet.replaces.filter((replace) =>\n replace.updateRequest.updateMask?.paths?.includes(\"oauth2.client_secret\"),\n );\n if (changeSet.creates.length > 0 || secretReplaces.length > 0) {\n const state = loadSecretsState(stateScope);\n if (!state.connections) {\n state.connections = {};\n }\n for (const create of changeSet.creates) {\n const conn = create.request.connection;\n if (conn?.config?.case === \"oauth2\") {\n state.connections[create.name] = hashValue(conn.config.value.clientSecret ?? \"\");\n }\n }\n for (const replace of secretReplaces) {\n const conn = replace.updateRequest.connection;\n if (conn?.config?.case === \"oauth2\") {\n state.connections[replace.name] = hashValue(conn.config.value.clientSecret ?? \"\");\n }\n }\n saveSecretsState(stateScope, state);\n }\n });\n }\n\n // Metadata-only updates: backfill the SDK ownership label on connections\n // whose configuration is otherwise unchanged.\n await Promise.all(\n changeSet.updates.map(async (update) => {\n await writeMetadataLabels(client, update.metaRequest);\n }),\n );\n } else if (changeSet.deletes.length > 0) {\n await withSecretsStateLock(stateScope, async () => {\n await Promise.all(\n changeSet.deletes.map(async (del) => {\n await client.deleteAuthConnection(del.request);\n }),\n );\n\n const state = loadSecretsState(stateScope);\n if (state.connections) {\n for (const del of changeSet.deletes) {\n delete state.connections[del.name];\n }\n saveSecretsState(stateScope, state);\n }\n });\n }\n}\n","import * as crypto from \"node:crypto\";\nimport { createApplyLimiter } from \"#/cli/shared/apply-concurrency\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { resolverBundleKey } from \"#/cli/shared/resolver-bundle-key\";\nimport { createChangeSet, type ChangeSet, type HasName } from \"./change-set\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { Application } from \"#/cli/services/application\";\nimport type { CollectedJob } from \"#/cli/services/workflow/service\";\nimport type { OperatorClient } from \"#/cli/shared/client\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { BundledScripts, FunctionEntry } from \"./function-registry-types\";\nimport type { ApplyPhase } from \"./phase\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type {\n CreateFunctionRegistryRequestSchema,\n UpdateFunctionRegistryRequestSchema,\n} from \"@tailor-platform/tailor-proto/function_registry_pb\";\n\nexport type { BundledScripts, FunctionEntry } from \"./function-registry-types\";\n\nconst CHUNK_SIZE = 64 * 1024; // 64KB\n\ntype CreateFunction = {\n name: string;\n entry: FunctionEntry;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateFunction = {\n name: string;\n entry: FunctionEntry;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteFunction = {\n name: string;\n workspaceId: string;\n};\n\nexport type FunctionRegistryChangeSet = ChangeSet<CreateFunction, UpdateFunction, DeleteFunction>;\n\n/**\n * Compute SHA-256 content hash for a script string.\n * @param content - Script content to hash\n * @returns Hex-encoded SHA-256 hash\n */\nfunction computeContentHash(content: string): string {\n return crypto.createHash(\"sha256\").update(content, \"utf-8\").digest(\"hex\");\n}\n\nexport const RESOLVER_PREFIX = \"resolver--\";\nexport const EXECUTOR_PREFIX = \"executor--\";\nexport const WORKFLOW_PREFIX = \"workflow--\";\nexport const AUTH_HOOK_PREFIX = \"auth-hook--\";\n\n/**\n * Build a function registry name for a resolver.\n * @param namespace - Resolver namespace\n * @param resolverName - Resolver name\n * @returns Function registry name\n */\nexport function resolverFunctionName(namespace: string, resolverName: string): string {\n return `${RESOLVER_PREFIX}${namespace}--${resolverName}`;\n}\n\n/**\n * Build a function registry name for an executor.\n * @param executorName - Executor name\n * @returns Function registry name\n */\nexport function executorFunctionName(executorName: string): string {\n return `${EXECUTOR_PREFIX}${executorName}`;\n}\n\n/**\n * Build a function registry name for a workflow job.\n * @param jobName - Workflow job name\n * @returns Function registry name\n */\nexport function workflowJobFunctionName(jobName: string): string {\n return `${WORKFLOW_PREFIX}${jobName}`;\n}\n\n/**\n * Split function registry changes into grouped buckets by resource-name prefix.\n * @param changeSet - Function registry change set\n * @returns Grouped function registry changes by resource kind\n */\nexport function splitFunctionRegistryChanges<\n C extends HasName,\n U extends HasName,\n D extends HasName,\n R extends HasName,\n>(changeSet: ChangeSet<C, U, D, R>) {\n type Buckets<T> = {\n workflowJob: T[];\n resolver: T[];\n executor: T[];\n authHook: T[];\n other: T[];\n };\n\n function partition<T extends HasName>(items: ReadonlyArray<T>): Buckets<T> {\n const buckets: Buckets<T> = {\n workflowJob: [],\n resolver: [],\n executor: [],\n authHook: [],\n other: [],\n };\n for (const item of items) {\n if (item.name.startsWith(WORKFLOW_PREFIX)) buckets.workflowJob.push(item);\n else if (item.name.startsWith(RESOLVER_PREFIX)) buckets.resolver.push(item);\n else if (item.name.startsWith(EXECUTOR_PREFIX)) buckets.executor.push(item);\n else if (item.name.startsWith(AUTH_HOOK_PREFIX)) buckets.authHook.push(item);\n else buckets.other.push(item);\n }\n return buckets;\n }\n\n const creates = partition(changeSet.creates);\n const updates = partition(changeSet.updates);\n const deletes = partition(changeSet.deletes);\n const replaces = partition(changeSet.replaces);\n const unchanged = partition(changeSet.unchanged);\n\n function collect<K extends keyof Buckets<unknown>>(key: K) {\n return {\n creates: creates[key],\n updates: updates[key],\n deletes: deletes[key],\n replaces: replaces[key],\n unchanged: unchanged[key],\n };\n }\n\n return {\n workflowJobChanges: collect(\"workflowJob\"),\n resolverFunctionChanges: collect(\"resolver\"),\n executorFunctionChanges: collect(\"executor\"),\n authHookFunctionChanges: collect(\"authHook\"),\n otherChanges: collect(\"other\"),\n };\n}\n\n/**\n * Build a function registry name for an auth hook.\n * @param authName - Auth namespace name\n * @param hookPoint - Hook point identifier (e.g. \"before-login\")\n * @returns Function registry name\n */\nexport function authHookFunctionName(authName: string, hookPoint: string): string {\n return `auth-hook--${authName}--${hookPoint}`;\n}\n\n/**\n * Collect all function entries from in-memory bundled scripts for all services.\n * @param application - Application definition\n * @param workflowJobs - Collected workflow jobs from config\n * @param bundledScripts - In-memory bundled code organized by kind\n * @returns Array of function entries to register\n */\nexport function collectFunctionEntries(\n application: Readonly<Application>,\n workflowJobs: CollectedJob[],\n bundledScripts: BundledScripts,\n): FunctionEntry[] {\n const entries: FunctionEntry[] = [];\n\n // Resolvers\n for (const app of application.applications) {\n for (const pipeline of app.resolverServices) {\n for (const resolver of Object.values(pipeline.resolvers)) {\n const content = bundledScripts.resolvers.get(\n resolverBundleKey(pipeline.namespace, resolver.name),\n );\n if (!content) {\n logger.warn(\n `Bundled code not found for resolver: ${pipeline.namespace}/${resolver.name}`,\n );\n continue;\n }\n entries.push({\n name: resolverFunctionName(pipeline.namespace, resolver.name),\n scriptContent: content,\n contentHash: computeContentHash(content),\n description: `Resolver: ${pipeline.namespace}/${resolver.name}`,\n });\n }\n }\n }\n\n // Executors\n if (application.executorService) {\n const executors = application.executorService.executors;\n for (const executor of Object.values(executors)) {\n if (executor.operation.kind === \"function\" || executor.operation.kind === \"jobFunction\") {\n const content = bundledScripts.executors.get(executor.name);\n if (!content) {\n logger.warn(`Bundled code not found for executor: ${executor.name}`);\n continue;\n }\n entries.push({\n name: executorFunctionName(executor.name),\n scriptContent: content,\n contentHash: computeContentHash(content),\n description: `Executor: ${executor.name}`,\n });\n }\n }\n }\n\n // Workflow jobs\n for (const job of workflowJobs) {\n const content = bundledScripts.workflowJobs.get(job.name);\n if (!content) {\n logger.warn(`Bundled code not found for workflow job: ${job.name}`);\n continue;\n }\n entries.push({\n name: workflowJobFunctionName(job.name),\n scriptContent: content,\n contentHash: computeContentHash(content),\n description: `Workflow job: ${job.name}`,\n });\n }\n\n // Auth hooks\n for (const app of application.applications) {\n if (app.authService?.config.hooks?.beforeLogin) {\n const authName = app.authService.config.name;\n const funcName = authHookFunctionName(authName, \"before-login\");\n const content = bundledScripts.authHooks.get(funcName);\n if (!content) {\n logger.warn(`Bundled code not found for auth hook: ${funcName}`);\n continue;\n }\n entries.push({\n name: funcName,\n scriptContent: content,\n contentHash: computeContentHash(content),\n description: `Auth hook: ${authName}/before-login`,\n });\n }\n }\n\n return entries;\n}\n\n/**\n * Filter collected workflow jobs down to the ones actually bundled.\n * @param jobs - All collected workflow jobs\n * @param usedJobNames - Job names that were bundled\n * @returns Bundled workflow jobs only\n */\nexport function filterBundledWorkflowJobs(\n jobs: CollectedJob[],\n usedJobNames: readonly string[],\n): CollectedJob[] {\n const used = new Set(usedJobNames);\n return jobs.filter((job) => used.has(job.name));\n}\n\ntype ExistingFunction = {\n name: string;\n contentHash: string;\n};\n\n/**\n * Plan function registry changes based on current and desired state.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param appName - Application name\n * @param appId - Stable application id (when managed by SDK)\n * @param entries - Desired function entries\n * @returns Planned changes\n */\nexport async function planFunctionRegistry(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n entries: FunctionEntry[],\n) {\n const changeSet: FunctionRegistryChangeSet = createChangeSet<\n CreateFunction,\n UpdateFunction,\n DeleteFunction\n >(\"Function registry\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingMap = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, maxPageSize) => {\n const response = await client.listFunctionRegistries({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [\n response.functions.map(\n (f): ExistingFunction => ({\n name: f.name,\n contentHash: f.contentHash,\n }),\n ),\n response.nextPageToken,\n ];\n },\n getName: (func) => func.name,\n getTrn: (name) => resourceTrn(workspaceId, \"function_registry\", name),\n });\n\n // Process desired entries\n for (const entry of entries) {\n const existing = existingMap[entry.name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"function_registry\", entry.name),\n appName,\n appId,\n });\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"Function registry\",\n resourceName: entry.name,\n conflicts,\n unmanaged,\n });\n\n if (\n existing.resource.contentHash === entry.contentHash &&\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels)\n ) {\n changeSet.unchanged.push({\n name: entry.name,\n });\n } else {\n changeSet.updates.push({\n name: entry.name,\n entry,\n metaRequest,\n });\n }\n delete existingMap[entry.name];\n } else {\n changeSet.creates.push({\n name: entry.name,\n entry,\n metaRequest,\n });\n }\n }\n\n // Remaining entries in existingMap are candidates for deletion\n for (const [name, existing] of Object.entries(existingMap)) {\n if (!existing) continue;\n const owned = trackRemainingResourceOwner({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name,\n workspaceId,\n });\n }\n }\n\n const {\n workflowJobChanges,\n resolverFunctionChanges,\n executorFunctionChanges,\n authHookFunctionChanges,\n } = splitFunctionRegistryChanges(changeSet);\n return {\n changeSet,\n workflowJobChanges,\n resolverFunctionChanges,\n executorFunctionChanges,\n authHookFunctionChanges,\n conflicts,\n unmanaged,\n resourceOwners,\n };\n}\n\n/**\n * Upload a function script to the function registry using client streaming.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param entry - Function entry to upload\n * @param isCreate - Whether this is a create (true) or update (false)\n */\nasync function uploadFunctionScript(\n client: OperatorClient,\n workspaceId: string,\n entry: FunctionEntry,\n isCreate: boolean,\n) {\n const buffer = Buffer.from(entry.scriptContent, \"utf-8\");\n\n const info = {\n workspaceId,\n name: entry.name,\n description: entry.description,\n sizeBytes: BigInt(buffer.length),\n contentHash: entry.contentHash,\n };\n\n if (isCreate) {\n /** @yields {MessageInitShape<typeof CreateFunctionRegistryRequestSchema>} Create request messages (info header followed by content chunks) */\n async function* createStream(): AsyncIterable<\n MessageInitShape<typeof CreateFunctionRegistryRequestSchema>\n > {\n yield { payload: { case: \"info\" as const, value: info } };\n for (let i = 0; i < buffer.length; i += CHUNK_SIZE) {\n yield {\n payload: {\n case: \"chunk\" as const,\n value: buffer.subarray(i, Math.min(i + CHUNK_SIZE, buffer.length)),\n },\n };\n }\n }\n await client.createFunctionRegistry(createStream());\n } else {\n /** @yields {MessageInitShape<typeof UpdateFunctionRegistryRequestSchema>} Update request messages (info header followed by content chunks) */\n async function* updateStream(): AsyncIterable<\n MessageInitShape<typeof UpdateFunctionRegistryRequestSchema>\n > {\n yield { payload: { case: \"info\" as const, value: info } };\n for (let i = 0; i < buffer.length; i += CHUNK_SIZE) {\n yield {\n payload: {\n case: \"chunk\" as const,\n value: buffer.subarray(i, Math.min(i + CHUNK_SIZE, buffer.length)),\n },\n };\n }\n }\n await client.updateFunctionRegistry(updateStream());\n }\n}\n\n/**\n * Apply function registry changes for the given phase.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param result - Planned function registry changes\n * @param phase - Apply phase\n */\nexport async function applyFunctionRegistry(\n client: OperatorClient,\n workspaceId: string,\n result: Awaited<ReturnType<typeof planFunctionRegistry>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n) {\n const { changeSet } = result;\n if (phase === \"create-update\") {\n // Streaming uploads bypass the client's unary concurrency cap, so bound\n // each upload + metadata pair here with the same apply-concurrency budget.\n const limitFunction = createApplyLimiter();\n\n await Promise.all([\n ...changeSet.creates.map((create) =>\n limitFunction(async () => {\n await uploadFunctionScript(client, workspaceId, create.entry, true);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ),\n ...changeSet.updates.map((update) =>\n limitFunction(async () => {\n await uploadFunctionScript(client, workspaceId, update.entry, false);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ),\n ]);\n } else {\n await Promise.all(\n changeSet.deletes.map((del) =>\n client.deleteFunctionRegistry({\n workspaceId: del.workspaceId,\n name: del.name,\n }),\n ),\n );\n }\n}\n","import { styles, symbols } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport {\n AUTH_HOOK_PREFIX,\n EXECUTOR_PREFIX,\n RESOLVER_PREFIX,\n WORKFLOW_PREFIX,\n} from \"./function-registry\";\nimport type { ChangeSet, HasName } from \"./change-set\";\n\nexport type DisplayAction = \"create\" | \"update\" | \"delete\" | \"replace\";\n\nexport type GroupedDisplayEntry = {\n action: DisplayAction;\n symbol: string;\n name: string;\n labels: string[];\n namespace?: string;\n};\n\nexport type RelatedFunctionRegistryChanges = {\n creates: ReadonlyArray<HasName>;\n updates: ReadonlyArray<HasName>;\n deletes: ReadonlyArray<HasName>;\n replaces: ReadonlyArray<HasName>;\n};\n\nexport type RelatedFunctionRegistryNameSets = {\n creates: Set<string>;\n updates: Set<string>;\n deletes: Set<string>;\n replaces: Set<string>;\n};\n\n/**\n * Convert grouped function registry changes into mutable name sets.\n * @param changes - Grouped function registry changes\n * @returns Mutable name sets keyed by action\n */\nexport function createRelatedFunctionRegistryNameSets(\n changes?: RelatedFunctionRegistryChanges,\n): RelatedFunctionRegistryNameSets {\n return {\n creates: new Set(changes?.creates.map((item) => item.name) ?? []),\n updates: new Set(changes?.updates.map((item) => item.name) ?? []),\n deletes: new Set(changes?.deletes.map((item) => item.name) ?? []),\n replaces: new Set(changes?.replaces.map((item) => item.name) ?? []),\n };\n}\n\nexport const ACTION_SYMBOLS = {\n create: symbols.create,\n update: symbols.update,\n delete: symbols.delete,\n replace: symbols.replace,\n} as const satisfies Record<DisplayAction, string>;\n\n/**\n * Convert a plain change set into grouped display entries.\n * @param changeSet - Change set to convert\n * @param labels - Labels to attach to each entry\n * @param getNamespace - Optional callback to extract namespace from an item\n * @returns Display entries in CLI print order\n */\nexport function formatChangeSetEntries(\n changeSet: Pick<\n ChangeSet<HasName, HasName, HasName, HasName>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n labels: string[] = [],\n getNamespace?: (item: HasName) => string | undefined,\n): GroupedDisplayEntry[] {\n function toEntry(action: DisplayAction, item: HasName): GroupedDisplayEntry {\n return {\n action,\n symbol: ACTION_SYMBOLS[action],\n name: item.name,\n labels: [...labels],\n namespace: getNamespace?.(item),\n };\n }\n return [\n ...changeSet.creates.map((item) => toEntry(\"create\", item)),\n ...changeSet.deletes.map((item) => toEntry(\"delete\", item)),\n ...changeSet.updates.map((item) => toEntry(\"update\", item)),\n ...changeSet.replaces.map((item) => toEntry(\"replace\", item)),\n ];\n}\n\nfunction formatGroupedDisplayLine(entry: GroupedDisplayEntry) {\n return entry.labels.length > 0\n ? `${entry.symbol} ${entry.name} (${entry.labels.join(\", \")})`\n : `${entry.symbol} ${entry.name}`;\n}\n\nfunction parseFunctionRegistryName(name: string): { displayName: string; namespace?: string } {\n if (name.startsWith(RESOLVER_PREFIX)) {\n const [, namespace, resolverName] = name.split(\"--\");\n if (namespace && resolverName) {\n return { displayName: resolverName, namespace };\n }\n }\n\n if (name.startsWith(WORKFLOW_PREFIX)) {\n return { displayName: name.slice(WORKFLOW_PREFIX.length) };\n }\n\n if (name.startsWith(EXECUTOR_PREFIX)) {\n return { displayName: name.slice(EXECUTOR_PREFIX.length) };\n }\n\n if (name.startsWith(AUTH_HOOK_PREFIX)) {\n const [, namespace, hookPoint] = name.split(\"--\");\n if (namespace && hookPoint) {\n return { displayName: hookPoint, namespace };\n }\n }\n\n return { displayName: name };\n}\n\n/**\n * Build function-registry-only entries that were not grouped with a parent resource.\n * @param names - Related function registry names keyed by action\n * @param consumed - Function registry names already grouped with parent resources\n * @returns Display entries for ungrouped function registry changes\n */\nexport function buildRemainingFunctionRegistryEntries(\n names: RelatedFunctionRegistryNameSets,\n consumed: RelatedFunctionRegistryNameSets = createRelatedFunctionRegistryNameSets(),\n): GroupedDisplayEntry[] {\n const actions = [\n [\"create\", names.creates, consumed.creates],\n [\"delete\", names.deletes, consumed.deletes],\n [\"update\", names.updates, consumed.updates],\n [\"replace\", names.replaces, consumed.replaces],\n ] as const;\n\n return actions.flatMap(([action, nameSet, consumedSet]) =>\n [...nameSet]\n .filter((name) => !consumedSet.has(name))\n .map((name) => {\n const { displayName, namespace } = parseFunctionRegistryName(name);\n return {\n action,\n symbol: ACTION_SYMBOLS[action],\n name: displayName,\n labels: [\"function\"],\n namespace,\n };\n }),\n );\n}\n\n/**\n * Format change set entries with function registry grouping.\n *\n * For each item in creates/updates/deletes, calls `getFunctionRegistryNames` to\n * derive zero or more function registry names. When a matching function registry\n * change exists for the same action, the item is displayed with both the resource\n * label and \"functionRegistry\". Ungrouped function registry changes are appended.\n * @param resourceLabel - Label for the resource kind (e.g. \"executor\", \"resolver\")\n * @param changeSet - Resource change set with creates/updates/deletes/replaces\n * @param changeSet.creates - Created resources\n * @param changeSet.updates - Updated resources\n * @param changeSet.deletes - Deleted resources\n * @param changeSet.replaces - Replaced resources\n * @param functionRegistryChanges - Related function registry changes\n * @param getFunctionRegistryNames - Derives function registry names from a resource item\n * @param options - Optional display callbacks\n * @param options.getNamespace - Extract namespace from an item for nested display\n * @param options.getDisplayName - Override display name for an item\n * @returns Display entries for CLI output\n */\nexport function formatChangeEntriesWithFunctionRegistry<\n C extends HasName,\n U extends HasName,\n D extends HasName,\n>(\n resourceLabel: string,\n changeSet: {\n creates: ReadonlyArray<C>;\n updates: ReadonlyArray<U>;\n deletes: ReadonlyArray<D>;\n replaces: ReadonlyArray<HasName>;\n },\n functionRegistryChanges: RelatedFunctionRegistryChanges | undefined,\n getFunctionRegistryNames: (item: C | U | D, action: DisplayAction) => string[],\n options?: {\n getNamespace?: (item: C | U | D) => string | undefined;\n getDisplayName?: (item: C | U | D) => string;\n },\n): GroupedDisplayEntry[] {\n const { getNamespace, getDisplayName } = options ?? {};\n const functionNames = createRelatedFunctionRegistryNameSets(functionRegistryChanges);\n const consumed: RelatedFunctionRegistryNameSets = createRelatedFunctionRegistryNameSets();\n\n function processItems(\n items: ReadonlyArray<C | U | D>,\n action: DisplayAction,\n fnNameSet: Set<string>,\n consumedSet: Set<string>,\n ): GroupedDisplayEntry[] {\n return items.map((item) => {\n const names = getFunctionRegistryNames(item, action);\n const hasMatch = names.some((name) => fnNameSet.has(name));\n if (hasMatch) {\n for (const name of names) {\n if (fnNameSet.has(name)) {\n consumedSet.add(name);\n }\n }\n }\n return {\n action,\n symbol: ACTION_SYMBOLS[action],\n name: getDisplayName?.(item) ?? item.name,\n labels: hasMatch ? [resourceLabel, \"function\"] : [resourceLabel],\n namespace: getNamespace?.(item),\n };\n });\n }\n\n return [\n ...processItems(changeSet.creates, \"create\", functionNames.creates, consumed.creates),\n ...processItems(changeSet.deletes, \"delete\", functionNames.deletes, consumed.deletes),\n ...processItems(changeSet.updates, \"update\", functionNames.updates, consumed.updates),\n ...changeSet.replaces.map((item) => ({\n action: \"replace\" as const,\n symbol: ACTION_SYMBOLS[\"replace\"],\n name: getDisplayName?.(item as C | U | D) ?? item.name,\n labels: [resourceLabel],\n namespace: getNamespace?.(item as C | U | D),\n })),\n ...buildRemainingFunctionRegistryEntries(functionNames, consumed),\n ];\n}\n\nexport type NamespaceAction = {\n name: string;\n action: DisplayAction;\n};\n\n/**\n * Extract service-level actions from a change set for namespace header display.\n * @param changeSet - Service change set\n * @returns Array of namespace actions\n */\nexport function extractServiceActions(\n changeSet: Pick<\n ChangeSet<HasName, HasName, HasName, HasName>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n): NamespaceAction[] {\n return [\n ...changeSet.creates.map((item) => ({ name: item.name, action: \"create\" as const })),\n ...changeSet.deletes.map((item) => ({ name: item.name, action: \"delete\" as const })),\n ...changeSet.updates.map((item) => ({ name: item.name, action: \"update\" as const })),\n ...changeSet.replaces.map((item) => ({ name: item.name, action: \"replace\" as const })),\n ];\n}\n\n/**\n * Build display lines for a titled section of grouped entries, nesting by namespace.\n * Service-level changes are shown as the namespace header symbol.\n * Services without child entries are shown as flat entries.\n * @param title - Section title\n * @param entries - Entries to render (should NOT include service entries)\n * @param serviceActions - Optional service-level actions to merge into namespace headers\n * @returns Lines ready for output; empty array when there is nothing to show\n */\nexport function buildGroupedDisplayLines(\n title: string,\n entries: ReadonlyArray<GroupedDisplayEntry>,\n serviceActions?: ReadonlyArray<NamespaceAction>,\n): string[] {\n const serviceMap = new Map<string, DisplayAction>();\n if (serviceActions) {\n for (const sa of serviceActions) {\n serviceMap.set(sa.name, sa.action);\n }\n }\n\n if (entries.length === 0 && serviceMap.size === 0) {\n return [];\n }\n\n const out: string[] = [styles.bold(`${title}:`)];\n\n // Group entries by namespace while preserving order\n const namespaceOrder: (string | undefined)[] = [];\n const byNamespace = new Map<string | undefined, GroupedDisplayEntry[]>();\n for (const entry of entries) {\n const ns = entry.namespace;\n if (!byNamespace.has(ns)) {\n namespaceOrder.push(ns);\n byNamespace.set(ns, []);\n }\n assertDefined(byNamespace.get(ns), \"namespace group missing\").push(entry);\n }\n\n // Track which services have child entries\n const printedServices = new Set<string>();\n\n for (const ns of namespaceOrder) {\n const group = assertDefined(byNamespace.get(ns), \"namespace group missing\");\n if (ns) {\n const svcAction = serviceMap.get(ns);\n const prefix = svcAction ? `${ACTION_SYMBOLS[svcAction]} ` : \"\";\n out.push(` ${prefix}${styles.bold(`${ns}:`)}`);\n printedServices.add(ns);\n for (const entry of group) {\n out.push(` ${formatGroupedDisplayLine(entry)}`);\n }\n } else {\n for (const entry of group) {\n out.push(` ${formatGroupedDisplayLine(entry)}`);\n }\n }\n }\n\n // Append services without child entries as flat entries\n for (const [name, action] of serviceMap) {\n if (!printedServices.has(name)) {\n out.push(` ${ACTION_SYMBOLS[action]} ${name}`);\n }\n }\n\n return out;\n}\n","import type { IdPPermission as RawIdPPermission } from \"#/types/idp.generated\";\nimport type {\n StandardIdPPermission,\n StandardIdPActionPermission,\n StandardIdPPermissionCondition,\n IdPPermissionOperand,\n IdPUserField,\n} from \"./types\";\n\ntype PermissionOperator = \"=\" | \"!=\" | \"in\" | \"not in\";\n\ntype ObjectOperand =\n | { user: string }\n | { idpUser: IdPUserField }\n | { oldIdpUser: IdPUserField }\n | { newIdpUser: IdPUserField };\n\ntype ValueOperand = string | boolean | string[] | boolean[];\n\ntype RawPermissionOperand = ObjectOperand | ValueOperand;\n\ntype PermissionCondition = readonly [\n RawPermissionOperand,\n PermissionOperator,\n RawPermissionOperand,\n];\n\nconst operatorMap: Record<PermissionOperator, string> = {\n \"=\": \"eq\",\n \"!=\": \"ne\",\n in: \"in\",\n \"not in\": \"nin\",\n};\n\nfunction normalizeOperand(operand: RawPermissionOperand): IdPPermissionOperand {\n if (typeof operand === \"object\" && !Array.isArray(operand) && \"user\" in operand) {\n const mapped = operand.user === \"id\" ? \"_id\" : operand.user;\n return { user: mapped };\n }\n return operand as IdPPermissionOperand;\n}\n\nfunction normalizeConditions(\n conditions: readonly PermissionCondition[],\n): StandardIdPPermissionCondition[] {\n return conditions.map((cond) => {\n const [left, operator, right] = cond;\n return [normalizeOperand(left), operatorMap[operator], normalizeOperand(right)];\n }) as StandardIdPPermissionCondition[];\n}\n\nfunction isObjectFormat(\n p: unknown,\n): p is { conditions: unknown; permit?: boolean; description?: string } {\n return typeof p === \"object\" && p !== null && \"conditions\" in p;\n}\n\nfunction isSingleArrayConditionFormat(cond: readonly unknown[]): boolean {\n return cond.length >= 2 && typeof cond[1] === \"string\";\n}\n\n/**\n * Normalize a single IdP action permission into the standard format.\n * @param permission - Raw permission definition\n * @returns Normalized action permission\n */\nexport function normalizeIdPActionPermission(permission: unknown): StandardIdPActionPermission {\n if (isObjectFormat(permission)) {\n const conditions = permission.conditions as\n | PermissionCondition\n | readonly PermissionCondition[];\n return {\n conditions: normalizeConditions(\n isSingleArrayConditionFormat(conditions)\n ? [conditions as PermissionCondition]\n : (conditions as readonly PermissionCondition[]),\n ),\n permit: permission.permit ? \"allow\" : \"deny\",\n description: permission.description,\n };\n }\n\n if (!Array.isArray(permission)) {\n throw new Error(\"Invalid permission format\");\n }\n\n if (isSingleArrayConditionFormat(permission)) {\n const [op1, operator, op2, permit] = [...permission, true] as [\n RawPermissionOperand,\n string,\n RawPermissionOperand,\n boolean,\n ];\n return {\n conditions: normalizeConditions([[op1, operator, op2] as PermissionCondition]),\n permit: permit ? \"allow\" : \"deny\",\n };\n }\n\n const conditions: PermissionCondition[] = [];\n const conditionArray = permission as readonly unknown[];\n let conditionArrayPermit = true;\n\n for (const item of conditionArray) {\n if (typeof item === \"boolean\") {\n conditionArrayPermit = item;\n continue;\n }\n conditions.push(item as PermissionCondition);\n }\n\n return {\n conditions: normalizeConditions(conditions),\n permit: conditionArrayPermit ? \"allow\" : \"deny\",\n };\n}\n\n/**\n * Normalize raw IdP permission into standard form.\n * @param permission - Raw IdP permission from user config\n * @returns Normalized IdP permission\n */\nexport function normalizeIdPPermission(permission: RawIdPPermission): StandardIdPPermission {\n return {\n create: permission.create.map((p) => normalizeIdPActionPermission(p)),\n read: permission.read.map((p) => normalizeIdPActionPermission(p)),\n update: permission.update.map((p) => normalizeIdPActionPermission(p)),\n delete: permission.delete.map((p) => normalizeIdPActionPermission(p)),\n sendPasswordResetEmail: (permission.sendPasswordResetEmail ?? []).map((p) =>\n normalizeIdPActionPermission(p),\n ),\n unenrollMfa: (permission.unenrollMfa ?? []).map((p) => normalizeIdPActionPermission(p)),\n } as StandardIdPPermission;\n}\n\n/**\n * Parse raw IdP permission, returning undefined if not set.\n * @param rawPermission - Raw permission from parsed config\n * @returns Normalized permission or undefined\n */\nexport function parseIdPPermission(\n rawPermission: RawIdPPermission | undefined,\n): StandardIdPPermission | undefined {\n if (!rawPermission) {\n return undefined;\n }\n return normalizeIdPPermission(rawPermission);\n}\n\n/**\n * Find object-format IdP permission rules that omit `permit`.\n *\n * Object-format rules default to `deny` when `permit` is omitted, whereas the\n * array shorthand defaults to `allow`. Omitting `permit` on an object rule is\n * therefore an easy way to accidentally deny access you meant to grant, so the\n * CLI warns about these locations to nudge authors toward setting `permit`\n * explicitly.\n * @param permission - Raw IdP permission from user config\n * @returns Locations of offending rules, e.g. `read[0]`\n */\nexport function findOmittedPermitRules(permission: RawIdPPermission | undefined): string[] {\n if (!permission) {\n return [];\n }\n const locations: string[] = [];\n for (const action of Object.keys(permission) as Array<keyof typeof permission>) {\n permission[action]?.forEach((rule: unknown, index: number) => {\n if (isObjectFormat(rule) && rule.permit === undefined) {\n locations.push(`${String(action)}[${index}]`);\n }\n });\n }\n return locations;\n}\n","import { fromJson, type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport {\n type CreateIdPClientRequestSchema,\n type CreateIdPServiceRequestSchema,\n type DeleteIdPClientRequestSchema,\n type DeleteIdPServiceRequestSchema,\n type UpdateIdPServiceRequestSchema,\n} from \"@tailor-platform/tailor-proto/idp_pb\";\nimport {\n IdPLang,\n IdPPermissionOperator,\n IdPPermissionPermit,\n type IdPPermissionConditionSchema as ProtoIdPPermissionConditionSchema,\n type IdPPermissionOperandSchema as ProtoIdPPermissionOperandSchema,\n type IdPPermissionPolicySchema as ProtoIdPPermissionPolicySchema,\n type IdPPermissionSchema as ProtoIdPPermissionSchema,\n type IdPService as ProtoIdPService,\n} from \"@tailor-platform/tailor-proto/idp_resource_pb\";\nimport {\n fetchAllTolerant,\n getOrNull,\n resolveStaticWebsiteUrls,\n type OperatorClient,\n} from \"#/cli/shared/client\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { publishEventsConflict, resolvePublishEvents } from \"#/cli/shared/publish-events\";\nimport { findOmittedPermitRules, parseIdPPermission } from \"#/parser/service/idp/permission\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport {\n addDependencyRecords,\n buildMetaRequest,\n type DependentAppsByResource,\n eventSourceKey,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport { expectedLocalStaticWebsiteNames } from \"./staticwebsite\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type {\n IdPPermissionOperand,\n StandardIdPActionPermission,\n StandardIdPPermission,\n StandardIdPPermissionCondition,\n} from \"#/parser/service/idp/types\";\nimport type { IdP, IdPLang as IdPLangInput } from \"#/types/idp.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\n\ntype IdPServiceMutationRequest = {\n workspaceId?: string;\n namespaceName?: string;\n userAuthPolicy?: { allowedReturnOrigins?: string[] } | undefined;\n};\n\nasync function resolveServiceReturnOrigins(\n client: OperatorClient,\n request: IdPServiceMutationRequest,\n): Promise<void> {\n const policy = request.userAuthPolicy;\n const originals = policy?.allowedReturnOrigins;\n if (!policy || !originals?.length) {\n return;\n }\n const resolved = await resolveStaticWebsiteUrls(\n client,\n assertDefined(request.workspaceId, \"request missing workspaceId\"),\n originals,\n `IdP service \"${request.namespaceName ?? \"\"}\" allowedReturnOrigins`,\n );\n // resolveStaticWebsiteUrls warn-and-drops unresolvable entries, which is fine\n // for CORS but would silently clear an authoritative field here (UpdateIdP is\n // a full replacement, and `enable_mfa: true` requires ≥1 origin). Fail fast.\n if (resolved.length !== originals.length) {\n throw new Error(\n `IdP service \"${request.namespaceName ?? \"\"}\" allowedReturnOrigins: ` +\n `${originals.length - resolved.length} of ${originals.length} entries could not be resolved. ` +\n `Check that each \"<name>:url\" entry refers to a deployed static website.`,\n );\n }\n policy.allowedReturnOrigins = resolved;\n}\n\n/**\n * Build the vault name for an IdP client.\n * @param namespaceName - IdP namespace name\n * @param clientName - IdP client name\n * @returns Vault name\n */\nexport function idpClientVaultName(namespaceName: string, clientName: string) {\n return `idp-${namespaceName}-${clientName}`;\n}\n\n/**\n * Build the secret name for an IdP client.\n * @param namespaceName - IdP namespace name\n * @param clientName - IdP client name\n * @returns Secret name\n */\nexport function idpClientSecretName(namespaceName: string, clientName: string) {\n return `client-secret-${namespaceName}-${clientName}`;\n}\n\n/**\n * Apply IdP-related changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned IdP changes\n * @param phase - Apply phase\n * @returns Promise that resolves when IdP changes are applied\n */\nexport async function applyIdP(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planIdP>>,\n phase: Exclude<ApplyPhase, \"delete\"> = \"create-update\",\n) {\n const { changeSet } = result;\n if (phase === \"create-update\") {\n // Services. An unchanged service still gets its labels written, because its\n // dependency records can change while its definition does not.\n await Promise.all([\n ...changeSet.service.creates.map(async (create) => {\n await resolveServiceReturnOrigins(client, create.request);\n await client.createIdPService(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.service.updates.map(async (update) => {\n await resolveServiceReturnOrigins(client, update.request);\n await client.updateIdPService(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ...changeSet.service.unchanged.flatMap((entry) =>\n entry.metaRequest ? [writeMetadataLabels(client, entry.metaRequest)] : [],\n ),\n ]);\n\n // Clients\n await Promise.all([\n ...changeSet.client.creates.map(async (create) => {\n const resp = await client.createIdPClient(create.request);\n\n // Create the secret manager vault and secret\n const vaultName = idpClientVaultName(\n assertDefined(create.request.namespaceName, \"request missing namespaceName\"),\n create.request.client?.name || \"\",\n );\n const secretName = idpClientSecretName(\n assertDefined(create.request.namespaceName, \"request missing namespaceName\"),\n create.request.client?.name || \"\",\n );\n await client.createSecretManagerVault({\n workspaceId: create.request.workspaceId,\n secretmanagerVaultName: vaultName,\n });\n await client.createSecretManagerSecret({\n workspaceId: create.request.workspaceId,\n secretmanagerVaultName: vaultName,\n secretmanagerSecretName: secretName,\n secretmanagerSecretValue: resp.client?.clientSecret,\n });\n }),\n ...changeSet.client.updates.map(async (update) => {\n // Ensure the vault and secret exist\n const vaultName = idpClientVaultName(update.namespaceName, update.name);\n const secretName = idpClientSecretName(update.namespaceName, update.name);\n const vault = await getOrNull(async () => {\n return await client.getSecretManagerVault({\n workspaceId: update.workspaceId,\n secretmanagerVaultName: vaultName,\n });\n });\n if (vault) return;\n await client.createSecretManagerVault({\n workspaceId: update.workspaceId,\n secretmanagerVaultName: vaultName,\n });\n await client.createSecretManagerSecret({\n workspaceId: update.workspaceId,\n secretmanagerVaultName: vaultName,\n secretmanagerSecretName: secretName,\n secretmanagerSecretValue: update.clientSecret,\n });\n }),\n ]);\n } else if (phase === \"delete-resources\") {\n // Delete in reverse order of dependencies\n // Clients\n await Promise.all(\n changeSet.client.deletes.map(async (del) => {\n await client.deleteIdPClient(del.request);\n\n // Delete the secret manager vault and secret\n const vaultName = `idp-${del.request.namespaceName}-${del.request.name}`;\n await client.deleteSecretManagerVault({\n workspaceId: del.request.workspaceId,\n secretmanagerVaultName: vaultName,\n });\n }),\n );\n } else {\n // Services only\n await Promise.all(changeSet.service.deletes.map((del) => client.deleteIdPService(del.request)));\n }\n}\n\n/**\n * Plan IdP-related changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes and metadata\n */\nexport async function planIdP(context: PlanContext) {\n const {\n client,\n workspaceId,\n application,\n forRemoval,\n forceApplyAll = false,\n idpUserTriggerTargets,\n dependentApps,\n runAppIds,\n } = context;\n const idps = forRemoval ? [] : application.idpServices;\n const expectedLocalWebsites = expectedLocalStaticWebsiteNames(context);\n const {\n changeSet: serviceChangeSet,\n conflicts,\n unmanaged,\n resourceOwners,\n } = await planServices(\n client,\n workspaceId,\n application.name,\n application.id,\n idps,\n idpUserTriggerTargets ?? new Set<string>(),\n expectedLocalWebsites,\n { dependentApps, runAppIds },\n );\n const deletedServices = serviceChangeSet.deletes.map((del) => del.name);\n const clientChangeSet = await planClients(\n client,\n workspaceId,\n idps,\n deletedServices,\n forceApplyAll,\n );\n\n return {\n changeSet: {\n service: serviceChangeSet,\n client: clientChangeSet,\n },\n conflicts,\n unmanaged,\n resourceOwners,\n };\n}\n\ntype CreateService = {\n name: string;\n request: MessageInitShape<typeof CreateIdPServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateService = {\n name: string;\n request: MessageInitShape<typeof UpdateIdPServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteService = {\n name: string;\n request: MessageInitShape<typeof DeleteIdPServiceRequestSchema>;\n};\n\n/**\n * An IdP service whose definition is unchanged but whose dependency records are\n * not. The plan shows it as unchanged; apply still writes its labels.\n */\ntype UnchangedService = {\n name: string;\n metaRequest?: MetadataLabelWrite;\n};\n\ntype ComparableIdPService = {\n authorization: string | undefined;\n lang: IdPLang;\n userAuthPolicy: Record<string, unknown> | undefined;\n publishEvents: boolean;\n disableGqlOperations: Record<string, boolean> | undefined;\n emailConfig: Record<string, string> | undefined;\n permission: MessageInitShape<typeof ProtoIdPPermissionSchema> | undefined;\n};\n\nfunction normalizeComparableUserAuthPolicy(\n policy: ProtoIdPService[\"userAuthPolicy\"] | IdP[\"userAuthPolicy\"] | undefined,\n): Record<string, unknown> | undefined {\n return {\n useNonEmailIdentifier: policy?.useNonEmailIdentifier ?? false,\n allowSelfPasswordReset: policy?.allowSelfPasswordReset ?? false,\n passwordRequireUppercase: policy?.passwordRequireUppercase ?? false,\n passwordRequireLowercase: policy?.passwordRequireLowercase ?? false,\n passwordRequireNonAlphanumeric: policy?.passwordRequireNonAlphanumeric ?? false,\n passwordRequireNumeric: policy?.passwordRequireNumeric ?? false,\n // The platform fills an omitted policy with password_min_length 6 and\n // password_max_length 4096 and echoes those back; it also coerces an\n // explicit 0 to the same defaults, which is why these use || (not ??) —\n // every falsy local value must compare equal to the stored defaults.\n passwordMinLength: policy?.passwordMinLength || 6,\n passwordMaxLength: policy?.passwordMaxLength || 4096,\n allowedEmailDomains: (policy?.allowedEmailDomains ?? []).toSorted(),\n allowGoogleOauth: policy?.allowGoogleOauth ?? false,\n disablePasswordAuth: policy?.disablePasswordAuth ?? false,\n allowMicrosoftOauth: policy?.allowMicrosoftOauth ?? false,\n enableMfa: policy?.enableMfa ?? false,\n requireMfa: policy?.requireMfa ?? false,\n allowedReturnOrigins: (policy?.allowedReturnOrigins ?? []).toSorted(),\n mfaIssuer: policy?.mfaIssuer ?? \"\",\n };\n}\n\nfunction normalizeComparableDisableGqlOperations(\n value: ProtoIdPService[\"disableGqlOperations\"] | Record<string, boolean> | undefined,\n): Record<string, boolean> | undefined {\n return {\n create: value?.create ?? false,\n update: value?.update ?? false,\n delete: value?.delete ?? false,\n read: value?.read ?? false,\n sendPasswordResetEmail: value?.sendPasswordResetEmail ?? false,\n requestMfaSettingsUrl: value?.requestMfaSettingsUrl ?? false,\n unenrollMfa: value?.unenrollMfa ?? false,\n };\n}\n\nfunction normalizeComparableEmailConfig(\n value: ProtoIdPService[\"emailConfig\"] | Record<string, string> | undefined,\n): Record<string, string> | undefined {\n return {\n fromName: value?.fromName ?? \"\",\n passwordResetSubject: value?.passwordResetSubject ?? \"\",\n };\n}\n\nfunction normalizeComparableIdPService(\n input: Pick<\n ComparableIdPService,\n | \"authorization\"\n | \"lang\"\n | \"userAuthPolicy\"\n | \"publishEvents\"\n | \"disableGqlOperations\"\n | \"emailConfig\"\n | \"permission\"\n >,\n): ComparableIdPService {\n return {\n authorization: input.authorization || undefined,\n lang: input.lang === IdPLang.UNSPECIFIED ? IdPLang.EN : input.lang,\n userAuthPolicy: input.userAuthPolicy,\n publishEvents: input.publishEvents,\n disableGqlOperations: input.disableGqlOperations,\n emailConfig: input.emailConfig,\n permission: input.permission,\n };\n}\n\nfunction normalizeComparablePermission(\n permission: ProtoIdPService[\"permission\"],\n): MessageInitShape<typeof ProtoIdPPermissionSchema> | undefined {\n if (!permission) {\n return undefined;\n }\n if (\n permission.create.length === 0 &&\n permission.read.length === 0 &&\n permission.update.length === 0 &&\n permission.delete.length === 0 &&\n permission.sendPasswordResetEmail.length === 0 &&\n permission.unenrollMfa.length === 0\n ) {\n return undefined;\n }\n const normalizePolicy = (policy: (typeof permission.create)[number]) => ({\n conditions: policy.conditions.map((c) => ({\n left: c.left ? { kind: c.left.kind } : undefined,\n operator: c.operator,\n right: c.right ? { kind: c.right.kind } : undefined,\n })),\n permit: policy.permit,\n // Platform returns an empty string for an unset description; treat it the same as omitted.\n description: policy.description || undefined,\n });\n return {\n create: permission.create.map(normalizePolicy),\n read: permission.read.map(normalizePolicy),\n update: permission.update.map(normalizePolicy),\n delete: permission.delete.map(normalizePolicy),\n sendPasswordResetEmail: permission.sendPasswordResetEmail.map(normalizePolicy),\n unenrollMfa: permission.unenrollMfa.map(normalizePolicy),\n };\n}\n\nfunction areIdPServicesEqual(existing: ProtoIdPService, desired: ComparableIdPService): boolean {\n return areNormalizedEqual(\n normalizeComparableIdPService({\n authorization: existing.authorization,\n lang: existing.lang,\n userAuthPolicy: normalizeComparableUserAuthPolicy(existing.userAuthPolicy),\n publishEvents: existing.publishUserEvents,\n disableGqlOperations: normalizeComparableDisableGqlOperations(existing.disableGqlOperations),\n emailConfig: normalizeComparableEmailConfig(existing.emailConfig),\n permission: normalizeComparablePermission(existing.permission),\n }),\n desired,\n );\n}\n\nasync function planServices(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n idps: ReadonlyArray<IdP>,\n idpUserTriggerTargets: ReadonlySet<string>,\n expectedLocalWebsites: ReadonlySet<string>,\n records: {\n dependentApps: DependentAppsByResource | undefined;\n runAppIds: ReadonlySet<string> | undefined;\n },\n) {\n const changeSet = createChangeSet<\n CreateService,\n UpdateService,\n DeleteService,\n never,\n UnchangedService\n >(\"IdP services\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingServices = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, maxPageSize) => {\n const { idpServices, nextPageToken } = await client.listIdPServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [idpServices, nextPageToken];\n },\n getName: (resource) => resource.namespace?.name,\n getTrn: (name) => resourceTrn(workspaceId, \"idp\", name),\n });\n\n for (const idp of idps) {\n const namespaceName = idp.name;\n const existing = existingServices[namespaceName];\n const metaRequest = addDependencyRecords(\n await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"idp\", namespaceName),\n appName,\n appId,\n }),\n {\n key: eventSourceKey.idp(namespaceName),\n dependentApps: records.dependentApps,\n runAppIds: records.runAppIds,\n pinned: idp.publishEvents !== undefined,\n },\n );\n let authorization: string | undefined;\n switch (idp.authorization) {\n case \"insecure\":\n authorization = \"true==true\";\n break;\n case \"loggedIn\":\n authorization = \"user != null && size(user.id) > 0\";\n break;\n case undefined:\n authorization = undefined;\n break;\n default:\n authorization = idp.authorization.cel;\n break;\n }\n\n const lang = convertLang(idp.lang);\n const userAuthPolicy = idp.userAuthPolicy;\n const publishEvents = resolvePublishEvents({\n explicit: idp.publishEvents,\n subscribed: idpUserTriggerTargets.has(namespaceName),\n conflict: publishEventsConflict.idpService(namespaceName),\n });\n const emailConfig = idp.emailConfig;\n if (!idp.permission) {\n logger.warn(`IdP service \"${namespaceName}\" has no permission configured.`);\n }\n const omittedPermitLocations = findOmittedPermitRules(idp.permission);\n if (omittedPermitLocations.length > 0) {\n logger.warn(\n `IdP service \"${namespaceName}\" has permission rule(s) ${omittedPermitLocations.join(\", \")} in object form without an explicit \"permit\"; they default to \"deny\". Set permit: true (allow) or permit: false (deny) to silence this warning.`,\n );\n }\n const parsedPermission = parseIdPPermission(idp.permission);\n const protoPermission = parsedPermission ? protoIdPPermission(parsedPermission) : undefined;\n const resolvedReturnOrigins = await resolveStaticWebsiteUrls(\n client,\n workspaceId,\n userAuthPolicy?.allowedReturnOrigins ? [...userAuthPolicy.allowedReturnOrigins] : [],\n `IdP service \"${namespaceName}\" allowedReturnOrigins`,\n { expectedLocalNames: expectedLocalWebsites },\n );\n const userAuthPolicyForCompare = userAuthPolicy\n ? { ...userAuthPolicy, allowedReturnOrigins: resolvedReturnOrigins }\n : userAuthPolicy;\n const desired = normalizeComparableIdPService({\n authorization,\n lang,\n userAuthPolicy: normalizeComparableUserAuthPolicy(userAuthPolicyForCompare),\n publishEvents,\n disableGqlOperations: normalizeComparableDisableGqlOperations(\n convertGqlOperationsToDisable(idp.gqlOperations),\n ),\n emailConfig: normalizeComparableEmailConfig(emailConfig),\n permission: protoPermission,\n });\n const request = {\n workspaceId,\n namespaceName,\n authorization,\n lang,\n userAuthPolicy,\n publishUserEvents: publishEvents,\n disableGqlOperations: convertGqlOperationsToDisable(idp.gqlOperations),\n emailConfig,\n permission: protoPermission,\n };\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"IdP service\",\n resourceName: idp.name,\n conflicts,\n unmanaged,\n });\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n areIdPServicesEqual(existing.resource, desired)\n ) {\n changeSet.unchanged.push({ name: namespaceName, metaRequest });\n } else {\n changeSet.updates.push({\n name: namespaceName,\n request,\n metaRequest,\n });\n }\n delete existingServices[namespaceName];\n } else {\n changeSet.creates.push({\n name: namespaceName,\n request,\n metaRequest,\n });\n }\n }\n Object.entries(existingServices).forEach(([namespaceName]) => {\n const entry = existingServices[namespaceName];\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: entry?.label,\n appName,\n appId,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name: namespaceName,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n });\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n\ntype CreateClient = {\n name: string;\n request: MessageInitShape<typeof CreateIdPClientRequestSchema>;\n};\n\ntype UpdateClient = {\n name: string;\n workspaceId: string;\n namespaceName: string;\n clientSecret: string;\n};\n\ntype DeleteClient = {\n name: string;\n request: MessageInitShape<typeof DeleteIdPClientRequestSchema>;\n};\n\nasync function planClients(\n client: OperatorClient,\n workspaceId: string,\n idps: ReadonlyArray<IdP>,\n deletedServices: string[],\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateClient, UpdateClient, DeleteClient>(\"IdP clients\");\n\n const fetchClients = (namespaceName: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { clients, nextPageToken } = await client.listIdPClients({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [clients, nextPageToken];\n });\n };\n\n const clientsByIdp = await Promise.all(idps.map((idp) => fetchClients(idp.name)));\n for (const [i, idp] of idps.entries()) {\n const namespaceName = idp.name;\n const existingClients = assertDefined(\n clientsByIdp[i],\n \"clientsByIdp missing entry for idp index\",\n );\n const existingNameMap = new Map<string, string>();\n existingClients.forEach((client) => {\n existingNameMap.set(client.name, client.clientSecret);\n });\n for (const name of idp.clients) {\n if (existingNameMap.has(name)) {\n if (forceApplyAll) {\n changeSet.updates.push({\n name,\n workspaceId,\n namespaceName,\n clientSecret: existingNameMap.get(name) ?? \"\",\n });\n } else {\n changeSet.unchanged.push({\n name,\n });\n }\n existingNameMap.delete(name);\n } else {\n changeSet.creates.push({\n name,\n request: {\n workspaceId,\n namespaceName,\n client: {\n name,\n },\n },\n });\n }\n }\n existingNameMap.forEach((_clientSecret, name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName,\n name,\n },\n });\n });\n }\n\n const deletedClientsByService = await Promise.all(\n deletedServices.map((namespaceName) => fetchClients(namespaceName)),\n );\n for (const [i, namespaceName] of deletedServices.entries()) {\n assertDefined(\n deletedClientsByService[i],\n \"deletedClientsByService missing entry for service index\",\n ).forEach((client) => {\n changeSet.deletes.push({\n name: client.name,\n request: {\n workspaceId,\n namespaceName,\n name: client.name,\n },\n });\n });\n }\n return changeSet;\n}\n\nfunction convertLang(lang: IdPLangInput | undefined): IdPLang {\n switch (lang) {\n case \"en\":\n return IdPLang.EN;\n case \"ja\":\n return IdPLang.JA;\n default:\n return IdPLang.UNSPECIFIED;\n }\n}\n\n// Converts gqlOperations (enabled semantics, default true) to\n// disableGqlOperations (disabled semantics) for the Platform API.\n// Undefined fields are treated as true (enabled), matching TailorDB behavior.\nfunction convertGqlOperationsToDisable(\n gqlOperations: IdP[\"gqlOperations\"],\n): Record<string, boolean> | undefined {\n if (!gqlOperations) {\n return undefined;\n }\n return {\n create: gqlOperations.create === false,\n update: gqlOperations.update === false,\n delete: gqlOperations.delete === false,\n read: gqlOperations.read === false,\n sendPasswordResetEmail: gqlOperations.sendPasswordResetEmail === false,\n requestMfaSettingsUrl: gqlOperations.requestMfaSettingsUrl === false,\n unenrollMfa: gqlOperations.unenrollMfa === false,\n };\n}\n\nfunction protoIdPPermission(\n permission: StandardIdPPermission,\n): MessageInitShape<typeof ProtoIdPPermissionSchema> {\n return {\n create: permission.create.map((p) => protoIdPPolicy(p)),\n read: permission.read.map((p) => protoIdPPolicy(p)),\n update: permission.update.map((p) => protoIdPPolicy(p)),\n delete: permission.delete.map((p) => protoIdPPolicy(p)),\n sendPasswordResetEmail: permission.sendPasswordResetEmail.map((p) => protoIdPPolicy(p)),\n unenrollMfa: permission.unenrollMfa.map((p) => protoIdPPolicy(p)),\n };\n}\n\nfunction protoIdPPolicy(\n policy: StandardIdPActionPermission,\n): MessageInitShape<typeof ProtoIdPPermissionPolicySchema> {\n let permit: IdPPermissionPermit;\n switch (policy.permit) {\n case \"allow\":\n permit = IdPPermissionPermit.ALLOW;\n break;\n case \"deny\":\n permit = IdPPermissionPermit.DENY;\n break;\n default:\n throw new Error(`Unknown permission: ${policy.permit satisfies never}`);\n }\n return {\n conditions: policy.conditions.map((cond) => protoIdPCondition(cond)),\n permit,\n description: policy.description,\n };\n}\n\nfunction protoIdPCondition(\n condition: StandardIdPPermissionCondition,\n): MessageInitShape<typeof ProtoIdPPermissionConditionSchema> {\n const [left, operator, right] = condition;\n\n const l = protoIdPOperand(left);\n const r = protoIdPOperand(right);\n let op: IdPPermissionOperator;\n switch (operator) {\n case \"eq\":\n op = IdPPermissionOperator.EQ;\n break;\n case \"ne\":\n op = IdPPermissionOperator.NE;\n break;\n case \"in\":\n op = IdPPermissionOperator.IN;\n break;\n case \"nin\":\n op = IdPPermissionOperator.NIN;\n break;\n default:\n throw new Error(`Unknown operator: ${operator satisfies never}`);\n }\n return {\n left: l,\n operator: op,\n right: r,\n };\n}\n\nfunction protoIdPOperand(\n operand: IdPPermissionOperand,\n): MessageInitShape<typeof ProtoIdPPermissionOperandSchema> {\n if (typeof operand === \"object\" && !Array.isArray(operand)) {\n if (\"user\" in operand) {\n return { kind: { case: \"userField\", value: operand.user } };\n } else if (\"idpUser\" in operand) {\n return { kind: { case: \"idpUserField\", value: operand.idpUser } };\n } else if (\"newIdpUser\" in operand) {\n return { kind: { case: \"newIdpUserField\", value: operand.newIdpUser } };\n } else if (\"oldIdpUser\" in operand) {\n return { kind: { case: \"oldIdpUserField\", value: operand.oldIdpUser } };\n } else {\n throw new Error(`Unknown operand: ${JSON.stringify(operand)}`);\n }\n }\n\n return {\n kind: {\n case: \"value\",\n value: fromJson(ValueSchema, operand),\n },\n };\n}\n","import { fromJson, type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport {\n AuthHookPoint,\n AuthIDPConfig_AuthType,\n AuthOAuth2Client_ClientType,\n AuthOAuth2Client_GrantType,\n AuthSCIMAttribute_Mutability,\n AuthSCIMAttribute_Type,\n AuthSCIMAttribute_Uniqueness,\n AuthSCIMConfig_AuthorizationType,\n type AuthIDPConfig_ConfigSchema,\n TenantProviderConfig_TenantProviderType,\n UserProfileProviderConfig_UserProfileProviderType,\n type AuthIDPConfigSchema,\n type AuthOAuth2ClientSchema,\n type AuthSCIMAttributeSchema,\n type AuthSCIMConfigSchema,\n type AuthSCIMResourceSchema,\n type TenantProviderConfigSchema,\n type UserProfileProviderConfigSchema,\n} from \"@tailor-platform/tailor-proto/auth_resource_pb\";\nimport { type AuthService } from \"#/cli/services/auth/service\";\nimport {\n fetchAllTolerant,\n getOrNull,\n resolveStaticWebsiteUrls,\n type OperatorClient,\n} from \"#/cli/shared/client\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { applyAuthConnections, planAuthConnections } from \"./auth-connection\";\nimport { createChangeSet, type ChangeSet, type HasName } from \"./change-set\";\nimport { areNormalizedEqual, normalizeProtoConfig, normalizeStringArray } from \"./compare\";\nimport { authHookFunctionName } from \"./function-registry\";\nimport {\n formatChangeEntriesWithFunctionRegistry,\n type GroupedDisplayEntry,\n type RelatedFunctionRegistryChanges,\n} from \"./grouped-display\";\nimport { idpClientSecretName, idpClientVaultName } from \"./idp\";\nimport {\n buildMetaRequest,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport { expectedLocalStaticWebsiteNames } from \"./staticwebsite\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { AuthAttributeValue } from \"#/configure/services/auth/types\";\nimport type {\n BuiltinIdP,\n IdProvider as IdProviderConfig,\n OAuth2Client,\n SCIMAttribute,\n SCIMConfig,\n SCIMResource,\n TenantProvider as TenantProviderConfig,\n} from \"#/types/auth.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type {\n CreateAuthHookRequestSchema,\n CreateAuthIDPConfigRequestSchema,\n CreateAuthMachineUserRequestSchema,\n CreateAuthOAuth2ClientRequestSchema,\n CreateAuthSCIMConfigRequestSchema,\n CreateAuthSCIMResourceRequestSchema,\n CreateAuthServiceRequestSchema,\n CreateTenantConfigRequestSchema,\n CreateUserProfileConfigRequestSchema,\n DeleteAuthHookRequestSchema,\n DeleteAuthIDPConfigRequestSchema,\n DeleteAuthMachineUserRequestSchema,\n DeleteAuthOAuth2ClientRequestSchema,\n DeleteAuthSCIMConfigRequestSchema,\n DeleteAuthSCIMResourceRequestSchema,\n DeleteAuthServiceRequestSchema,\n DeleteTenantConfigRequestSchema,\n DeleteUserProfileConfigRequestSchema,\n UpdateAuthHookRequestSchema,\n UpdateAuthIDPConfigRequestSchema,\n UpdateAuthMachineUserRequestSchema,\n UpdateAuthOAuth2ClientRequestSchema,\n UpdateAuthSCIMConfigRequestSchema,\n UpdateAuthSCIMResourceRequestSchema,\n UpdateAuthServiceRequestSchema,\n UpdateTenantConfigRequestSchema,\n UpdateUserProfileConfigRequestSchema,\n} from \"@tailor-platform/tailor-proto/auth_pb\";\n\ntype AuthApplyPhase =\n | Exclude<ApplyPhase, \"delete\">\n | \"create-update-prerequisites\"\n | \"create-update-dependents\";\n\n/**\n * Apply auth-related changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned auth changes\n * @param phase - Apply phase (defaults to \"create-update\")\n * @returns Promise that resolves when auth changes are applied\n */\nexport async function applyAuth(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planAuth>>,\n phase: AuthApplyPhase = \"create-update\",\n) {\n const { changeSet } = result;\n const applyServices = async () => {\n await Promise.all([\n ...changeSet.service.creates.map(async (create) => {\n await client.createAuthService(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.service.updates.map(async (update) => {\n await client.updateAuthService(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n };\n\n const applyMachineUsers = async () => {\n await Promise.all([\n ...changeSet.machineUser.creates.map((create) =>\n client.createAuthMachineUser(create.request),\n ),\n ...changeSet.machineUser.updates.map((update) =>\n client.updateAuthMachineUser(update.request),\n ),\n ]);\n };\n\n const applyUserProfileDeletes = async () => {\n await Promise.all(\n changeSet.userProfileConfig.deletes.map((del) => client.deleteUserProfileConfig(del.request)),\n );\n };\n\n const applyCreateUpdateDependents = async () => {\n await applyAuthConnections(\n client,\n {\n changeSet: changeSet.connection,\n stateScope: result.connectionStateScope,\n },\n \"create-update\",\n );\n\n await Promise.all([\n ...changeSet.idpConfig.creates.map(async (create) => {\n if (create.idpConfig.kind === \"BuiltInIdP\") {\n assertDefined(create.request.idpConfig, \"request missing idpConfig\").config =\n await protoBuiltinIdPConfig(\n client,\n assertDefined(create.request.workspaceId, \"request missing workspaceId\"),\n create.idpConfig,\n );\n }\n return client.createAuthIDPConfig(create.request);\n }),\n ...changeSet.idpConfig.updates.map(async (update) => {\n if (update.idpConfig.kind === \"BuiltInIdP\") {\n assertDefined(update.request.idpConfig, \"request missing idpConfig\").config =\n await protoBuiltinIdPConfig(\n client,\n assertDefined(update.request.workspaceId, \"request missing workspaceId\"),\n update.idpConfig,\n );\n }\n return client.updateAuthIDPConfig(update.request);\n }),\n ]);\n\n await Promise.all([\n ...changeSet.userProfileConfig.creates.map((create) =>\n client.createUserProfileConfig(create.request),\n ),\n ...changeSet.userProfileConfig.updates.map((update) =>\n client.updateUserProfileConfig(update.request),\n ),\n ]);\n\n await Promise.all([\n ...changeSet.tenantConfig.creates.map((create) => client.createTenantConfig(create.request)),\n ...changeSet.tenantConfig.updates.map((update) => client.updateTenantConfig(update.request)),\n ]);\n\n await Promise.all([\n ...changeSet.authHook.creates.map((create) => client.createAuthHook(create.request)),\n ...changeSet.authHook.updates.map((update) => client.updateAuthHook(update.request)),\n ]);\n\n await Promise.all([\n ...changeSet.oauth2Client.creates.map(async (create) => {\n const oauth2Client = assertDefined(\n create.request.oauth2Client,\n \"request missing oauth2Client\",\n );\n oauth2Client.redirectUris = await resolveStaticWebsiteUrls(\n client,\n assertDefined(create.request.workspaceId, \"request missing workspaceId\"),\n oauth2Client.redirectUris,\n \"OAuth2 redirect URIs\",\n );\n return client.createAuthOAuth2Client(create.request);\n }),\n ...changeSet.oauth2Client.updates.map(async (update) => {\n const oauth2Client = assertDefined(\n update.request.oauth2Client,\n \"request missing oauth2Client\",\n );\n oauth2Client.redirectUris = await resolveStaticWebsiteUrls(\n client,\n assertDefined(update.request.workspaceId, \"request missing workspaceId\"),\n oauth2Client.redirectUris,\n \"OAuth2 redirect URIs\",\n );\n return client.updateAuthOAuth2Client(update.request);\n }),\n ]);\n\n for (const replace of changeSet.oauth2Client.replaces) {\n await client.deleteAuthOAuth2Client(replace.deleteRequest);\n const replaceOauth2Client = assertDefined(\n replace.createRequest.oauth2Client,\n \"createRequest missing oauth2Client\",\n );\n replaceOauth2Client.redirectUris = await resolveStaticWebsiteUrls(\n client,\n assertDefined(replace.createRequest.workspaceId, \"createRequest missing workspaceId\"),\n replaceOauth2Client.redirectUris,\n \"OAuth2 redirect URIs\",\n );\n await client.createAuthOAuth2Client(replace.createRequest);\n }\n\n await Promise.all([\n ...changeSet.scim.creates.map((create) => client.createAuthSCIMConfig(create.request)),\n ...changeSet.scim.updates.map((update) => client.updateAuthSCIMConfig(update.request)),\n ]);\n\n await Promise.all([\n ...changeSet.scimResource.creates.map((create) =>\n client.createAuthSCIMResource(create.request),\n ),\n ...changeSet.scimResource.updates.map((update) =>\n client.updateAuthSCIMResource(update.request),\n ),\n ]);\n };\n\n if (phase === \"create-update-prerequisites\" || phase === \"create-update\") {\n await applyServices();\n await applyMachineUsers();\n }\n if (phase === \"create-update-dependents\" || phase === \"create-update\") {\n await applyCreateUpdateDependents();\n }\n if (phase === \"delete-resources\") {\n // Delete in reverse order of dependencies\n // SCIMResources\n await Promise.all(\n changeSet.scimResource.deletes.map((del) => client.deleteAuthSCIMResource(del.request)),\n );\n\n // SCIMConfigs\n await Promise.all(\n changeSet.scim.deletes.map((del) => client.deleteAuthSCIMConfig(del.request)),\n );\n\n // OAuth2Clients\n await Promise.all(\n changeSet.oauth2Client.deletes.map((del) => client.deleteAuthOAuth2Client(del.request)),\n );\n\n // AuthHooks (before machine users, since hooks reference invokers)\n await Promise.all(changeSet.authHook.deletes.map((del) => client.deleteAuthHook(del.request)));\n\n // MachineUsers\n await Promise.all(\n changeSet.machineUser.deletes.map((del) => client.deleteAuthMachineUser(del.request)),\n );\n\n // TenantConfigs\n await Promise.all(\n changeSet.tenantConfig.deletes.map((del) => client.deleteTenantConfig(del.request)),\n );\n\n // UserProfileConfigs\n await applyUserProfileDeletes();\n\n // IdPConfigs\n await Promise.all(\n changeSet.idpConfig.deletes.map((del) => client.deleteAuthIDPConfig(del.request)),\n );\n\n // Auth Connections\n await applyAuthConnections(\n client,\n {\n changeSet: changeSet.connection,\n stateScope: result.connectionStateScope,\n },\n \"delete-resources\",\n );\n } else if (phase === \"delete-services\") {\n // Services only\n await Promise.all(\n changeSet.service.deletes.map((del) => client.deleteAuthService(del.request)),\n );\n }\n}\n\n/**\n * Plan auth-related changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned auth changes and metadata\n */\nexport async function planAuth(context: PlanContext) {\n const { client, workspaceId, application, forRemoval, forceApplyAll = false } = context;\n const auths: Readonly<AuthService>[] = [];\n if (!forRemoval && application.authService) {\n await application.authService.resolveNamespaces();\n auths.push(application.authService);\n }\n const {\n changeSet: serviceChangeSet,\n conflicts,\n unmanaged,\n resourceOwners,\n } = await planServices(\n client,\n workspaceId,\n application.name,\n application.id,\n auths,\n forceApplyAll,\n );\n const deletedServices = serviceChangeSet.deletes.map((del) => del.name);\n const expectedLocalWebsites = expectedLocalStaticWebsiteNames(context);\n const [\n idpConfigChangeSet,\n userProfileConfigChangeSet,\n tenantConfigChangeSet,\n machineUserChangeSet,\n authHookChangeSet,\n oauth2ClientChangeSet,\n scimChangeSet,\n scimResourceChangeSet,\n connectionResult,\n ] = await Promise.all([\n planIdPConfigs(client, workspaceId, auths, deletedServices, forceApplyAll),\n planUserProfileConfigs(client, workspaceId, auths, deletedServices, forceApplyAll),\n planTenantConfigs(client, workspaceId, auths, deletedServices, forceApplyAll),\n planMachineUsers(client, workspaceId, auths, deletedServices, forceApplyAll),\n planAuthHooks(client, workspaceId, auths, deletedServices, forceApplyAll),\n planOAuth2Clients(\n client,\n workspaceId,\n auths,\n deletedServices,\n expectedLocalWebsites,\n forceApplyAll,\n ),\n planSCIMConfigs(client, workspaceId, auths, deletedServices),\n planSCIMResources(client, workspaceId, auths, deletedServices),\n planAuthConnections(client, workspaceId, application.name, application.id, auths),\n ]);\n return {\n changeSet: {\n service: serviceChangeSet,\n idpConfig: idpConfigChangeSet,\n userProfileConfig: userProfileConfigChangeSet,\n tenantConfig: tenantConfigChangeSet,\n machineUser: machineUserChangeSet,\n authHook: authHookChangeSet,\n oauth2Client: oauth2ClientChangeSet,\n scim: scimChangeSet,\n scimResource: scimResourceChangeSet,\n connection: connectionResult.changeSet,\n },\n conflicts: [...conflicts, ...connectionResult.conflicts],\n unmanaged: [...unmanaged, ...connectionResult.unmanaged],\n resourceOwners: new Set([...resourceOwners, ...connectionResult.resourceOwners]),\n connectionStateScope: connectionResult.stateScope,\n };\n}\n\ntype CreateService = {\n name: string;\n request: MessageInitShape<typeof CreateAuthServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateService = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteService = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthServiceRequestSchema>;\n};\n\nasync function planServices(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n auths: ReadonlyArray<Readonly<AuthService>>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateService, UpdateService, DeleteService>(\"Auth services\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingServices = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, maxPageSize) => {\n const { authServices, nextPageToken } = await client.listAuthServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [authServices, nextPageToken];\n },\n getName: (resource) => resource.namespace?.name,\n getTrn: (name) => resourceTrn(workspaceId, \"auth\", name),\n });\n\n for (const auth of auths) {\n const { config } = auth;\n const existing = existingServices[config.name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"auth\", config.name),\n appName,\n appId,\n });\n const request = {\n workspaceId,\n namespaceName: config.name,\n publishSessionEvents: config.publishSessionEvents,\n };\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"Auth service\",\n resourceName: config.name,\n conflicts,\n unmanaged,\n });\n\n if (\n !forceApplyAll &&\n existing.resource.publishSessionEvents === (config.publishSessionEvents ?? false) &&\n owned\n ) {\n changeSet.unchanged.push({ name: config.name });\n } else {\n changeSet.updates.push({\n name: config.name,\n request,\n metaRequest,\n });\n }\n delete existingServices[config.name];\n } else {\n changeSet.creates.push({\n name: config.name,\n request,\n metaRequest,\n });\n }\n }\n Object.entries(existingServices).forEach(([namespaceName]) => {\n const entry = existingServices[namespaceName];\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: entry?.label,\n appName,\n appId,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name: namespaceName,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n });\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n\ntype CreateIdPConfig = {\n name: string;\n idpConfig: Readonly<IdProviderConfig>;\n request: MessageInitShape<typeof CreateAuthIDPConfigRequestSchema>;\n};\n\ntype UpdateIdPConfig = {\n name: string;\n idpConfig: Readonly<IdProviderConfig>;\n request: MessageInitShape<typeof UpdateAuthIDPConfigRequestSchema>;\n};\n\ntype DeleteIdPConfig = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthIDPConfigRequestSchema>;\n};\n\nasync function planIdPConfigs(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateIdPConfig, UpdateIdPConfig, DeleteIdPConfig>(\n \"Auth idpConfigs\",\n );\n\n const fetchIdPConfigs = (namespaceName: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { idpConfigs, nextPageToken } = await client.listAuthIDPConfigs({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [idpConfigs, nextPageToken];\n });\n };\n\n for (const authService of auths) {\n const { config } = authService;\n const existingIdPConfigs = await fetchIdPConfigs(config.name);\n const existingMap = new Map<string, (typeof existingIdPConfigs)[number]>();\n existingIdPConfigs.forEach((idpConfig) => {\n existingMap.set(idpConfig.name, idpConfig);\n });\n const idpConfig = config.idProvider;\n if (idpConfig) {\n const desired = protoIdPConfig(idpConfig);\n const existing = existingMap.get(idpConfig.name);\n if (existing) {\n const desiredComparable = await protoIdPConfigForComparison(\n client,\n workspaceId,\n idpConfig,\n desired,\n );\n if (!desiredComparable) {\n changeSet.updates.push({\n name: idpConfig.name,\n idpConfig,\n request: {\n workspaceId,\n namespaceName: config.name,\n idpConfig: desired,\n },\n });\n existingMap.delete(idpConfig.name);\n continue;\n }\n if (!forceApplyAll && areAuthIdPConfigsEqual(existing, desiredComparable)) {\n changeSet.unchanged.push({ name: idpConfig.name });\n } else {\n changeSet.updates.push({\n name: idpConfig.name,\n idpConfig,\n request: {\n workspaceId,\n namespaceName: config.name,\n idpConfig: desired,\n },\n });\n }\n existingMap.delete(idpConfig.name);\n } else {\n changeSet.creates.push({\n name: idpConfig.name,\n idpConfig,\n request: {\n workspaceId,\n namespaceName: config.name,\n idpConfig: desired,\n },\n });\n }\n }\n existingMap.forEach((_, name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n name,\n },\n });\n });\n }\n\n for (const namespaceName of deletedServices) {\n const existingIdPConfigs = await fetchIdPConfigs(namespaceName);\n existingIdPConfigs.forEach((idpConfig) => {\n changeSet.deletes.push({\n name: idpConfig.name,\n request: {\n workspaceId,\n namespaceName,\n name: idpConfig.name,\n },\n });\n });\n }\n return changeSet;\n}\n\nasync function protoIdPConfigForComparison(\n client: OperatorClient,\n workspaceId: string,\n idpConfig: Readonly<IdProviderConfig>,\n desired: MessageInitShape<typeof AuthIDPConfigSchema>,\n) {\n if (idpConfig.kind !== \"BuiltInIdP\") {\n return desired;\n }\n\n const config = await tryProtoBuiltinIdPConfig(client, workspaceId, idpConfig);\n return config\n ? {\n ...desired,\n config,\n }\n : undefined;\n}\n\nfunction normalizeComparableAuthIdPConfig(idpConfig: {\n name?: string;\n authType?: AuthIDPConfig_AuthType;\n config?: {\n config?: {\n case?: \"oidc\" | \"saml\" | \"idToken\";\n value?: unknown;\n };\n };\n}) {\n const configCase = idpConfig.config?.config?.case;\n const oidcValue =\n configCase === \"oidc\" &&\n typeof idpConfig.config?.config?.value === \"object\" &&\n idpConfig.config.config.value !== null\n ? idpConfig.config.config.value\n : undefined;\n return normalizeProtoConfig({\n name: idpConfig.name,\n authType: idpConfig.authType,\n config:\n configCase === \"oidc\"\n ? {\n config: {\n case: \"oidc\" as const,\n value: {\n ...oidcValue,\n issuerUrl:\n oidcValue && \"issuerUrl\" in oidcValue\n ? oidcValue.issuerUrl || undefined\n : undefined,\n },\n },\n }\n : idpConfig.config,\n });\n}\n\nfunction areAuthIdPConfigsEqual(\n existing: {\n name?: string;\n authType?: AuthIDPConfig_AuthType;\n config?: {\n config?: {\n case?: \"oidc\" | \"saml\" | \"idToken\";\n value?: unknown;\n };\n };\n },\n desired: {\n name?: string;\n authType?: AuthIDPConfig_AuthType;\n config?: {\n config?: {\n case?: \"oidc\" | \"saml\" | \"idToken\";\n value?: unknown;\n };\n };\n },\n) {\n return areNormalizedEqual(\n normalizeComparableAuthIdPConfig(existing),\n normalizeComparableAuthIdPConfig(desired),\n );\n}\n\nfunction protoIdPConfig(idpConfig: IdProviderConfig): MessageInitShape<typeof AuthIDPConfigSchema> {\n switch (idpConfig.kind) {\n case \"IDToken\":\n return {\n name: idpConfig.name,\n authType: AuthIDPConfig_AuthType.ID_TOKEN,\n config: {\n config: {\n case: \"idToken\",\n value: {\n providerUrl: idpConfig.providerURL,\n clientId: idpConfig.clientID,\n issuerUrl: idpConfig.issuerURL,\n usernameClaim: idpConfig.usernameClaim,\n },\n },\n },\n };\n case \"SAML\":\n return {\n name: idpConfig.name,\n authType: AuthIDPConfig_AuthType.SAML,\n config: {\n config: {\n case: \"saml\",\n value: {\n ...(idpConfig.metadataURL !== undefined\n ? { metadataUrl: idpConfig.metadataURL }\n : {\n rawMetadata: assertDefined(\n idpConfig.rawMetadata,\n \"SAML config missing rawMetadata\",\n ),\n }),\n enableSignRequest: idpConfig.enableSignRequest,\n defaultRedirectUrl: idpConfig.defaultRedirectURL,\n },\n },\n },\n };\n case \"OIDC\":\n return {\n name: idpConfig.name,\n authType: AuthIDPConfig_AuthType.OIDC,\n config: {\n config: {\n case: \"oidc\",\n value: {\n clientIdKey: idpConfig.clientID,\n clientSecretKey: {\n vaultName: idpConfig.clientSecret.vaultName,\n secretKey: idpConfig.clientSecret.secretKey,\n },\n providerUrl: idpConfig.providerURL,\n issuerUrl: idpConfig.issuerURL,\n usernameClaim: idpConfig.usernameClaim,\n },\n },\n },\n };\n case \"BuiltInIdP\":\n return {\n name: idpConfig.name,\n authType: AuthIDPConfig_AuthType.OIDC,\n // config is set at apply time\n config: {},\n };\n default:\n throw new Error(`Unexpected idp kind: ${idpConfig satisfies never}`);\n }\n}\n\nasync function protoBuiltinIdPConfig(\n client: OperatorClient,\n workspaceId: string,\n builtinIdPConfig: BuiltinIdP,\n): Promise<MessageInitShape<typeof AuthIDPConfig_ConfigSchema>> {\n const config = await tryProtoBuiltinIdPConfig(client, workspaceId, builtinIdPConfig);\n if (!config) {\n throw new Error(\n `Built-in IdP \"${builtinIdPConfig.namespace}\" not found. Please ensure that idp is configured correctly.`,\n );\n }\n return config;\n}\n\nasync function tryProtoBuiltinIdPConfig(\n client: OperatorClient,\n workspaceId: string,\n builtinIdPConfig: BuiltinIdP,\n): Promise<MessageInitShape<typeof AuthIDPConfig_ConfigSchema> | undefined> {\n const idpService = await getOrNull(async () => {\n return await client.getIdPService({\n workspaceId,\n namespaceName: builtinIdPConfig.namespace,\n });\n });\n if (!idpService) return undefined;\n\n const idpClient = await getOrNull(async () => {\n return await client.getIdPClient({\n workspaceId,\n namespaceName: builtinIdPConfig.namespace,\n name: builtinIdPConfig.clientName,\n });\n });\n if (!idpClient) return undefined;\n\n const vaultName = idpClientVaultName(builtinIdPConfig.namespace, builtinIdPConfig.clientName);\n const secretKey = idpClientSecretName(builtinIdPConfig.namespace, builtinIdPConfig.clientName);\n return {\n config: {\n case: \"oidc\",\n value: {\n clientIdKey: idpClient.client?.clientId,\n clientSecretKey: {\n vaultName,\n secretKey,\n },\n providerUrl: idpService.idpService?.providerUrl,\n usernameClaim: \"name\",\n },\n },\n };\n}\n\ntype CreateUserProfileConfig = {\n name: string;\n request: MessageInitShape<typeof CreateUserProfileConfigRequestSchema>;\n};\n\ntype UpdateUserProfileConfig = {\n name: string;\n request: MessageInitShape<typeof UpdateUserProfileConfigRequestSchema>;\n};\n\ntype DeleteUserProfileConfig = {\n name: string;\n request: MessageInitShape<typeof DeleteUserProfileConfigRequestSchema>;\n};\n\nasync function planUserProfileConfigs(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<\n CreateUserProfileConfig,\n UpdateUserProfileConfig,\n DeleteUserProfileConfig\n >(\"Auth userProfileConfigs\");\n\n for (const auth of auths) {\n const { config } = auth;\n const name = `${config.name}-user-profile-config`;\n const existing = await getOrNull(async () => {\n return await client.getUserProfileConfig({\n workspaceId,\n namespaceName: config.name,\n });\n });\n if (!existing) {\n const userProfileForUpdate = auth.userProfile;\n if (userProfileForUpdate) {\n changeSet.creates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n userProfileProviderConfig: protoUserProfileConfig(userProfileForUpdate),\n },\n });\n }\n continue;\n }\n\n const userProfileForUpdate = auth.userProfile;\n if (userProfileForUpdate) {\n const desired = protoUserProfileConfig(userProfileForUpdate);\n if (\n !forceApplyAll &&\n areUserProfileConfigsEqual(existing.userProfileProviderConfig ?? {}, desired)\n ) {\n changeSet.unchanged.push({ name });\n } else {\n changeSet.updates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n userProfileProviderConfig: desired,\n },\n });\n }\n } else {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n },\n });\n }\n }\n\n for (const namespaceName of deletedServices) {\n const existing = await getOrNull(async () => {\n return await client.getUserProfileConfig({\n workspaceId,\n namespaceName,\n });\n });\n if (!existing) continue;\n changeSet.deletes.push({\n name: `${namespaceName}-user-profile-config`,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n return changeSet;\n}\n\nfunction protoUserProfileConfig(\n userProfile: NonNullable<AuthService[\"userProfile\"]>,\n): MessageInitShape<typeof UserProfileProviderConfigSchema> {\n // Convert attributes from { key: true } to { key: \"key\" }\n const attributeMap = userProfile.attributes\n ? Object.fromEntries(Object.keys(userProfile.attributes).map((key) => [key, key]))\n : undefined;\n\n return {\n provider: \"TAILORDB\",\n providerType: UserProfileProviderConfig_UserProfileProviderType.TAILORDB,\n config: {\n config: {\n case: \"tailordb\",\n value: {\n namespace: userProfile.namespace,\n type: userProfile.type.name,\n usernameField: userProfile.usernameField,\n tenantIdField: undefined,\n attributesFields: userProfile.attributeList,\n attributeMap,\n },\n },\n },\n };\n}\n\ntype CreateTenantConfig = {\n name: string;\n request: MessageInitShape<typeof CreateTenantConfigRequestSchema>;\n};\n\ntype UpdateTenantConfig = {\n name: string;\n request: MessageInitShape<typeof UpdateTenantConfigRequestSchema>;\n};\n\ntype DeleteTenantConfig = {\n name: string;\n request: MessageInitShape<typeof DeleteTenantConfigRequestSchema>;\n};\n\nasync function planTenantConfigs(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateTenantConfig, UpdateTenantConfig, DeleteTenantConfig>(\n \"Auth tenantConfigs\",\n );\n\n for (const auth of auths) {\n const { config } = auth;\n const name = `${config.name}-tenant-config`;\n const existing = await getOrNull(async () => {\n return await client.getTenantConfig({\n workspaceId,\n namespaceName: config.name,\n });\n });\n if (!existing) {\n if (config.tenantProvider) {\n changeSet.creates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n tenantProviderConfig: protoTenantConfig(config.tenantProvider),\n },\n });\n }\n continue;\n }\n\n if (config.tenantProvider) {\n const desired = protoTenantConfig(config.tenantProvider);\n if (!forceApplyAll && areTenantProviderConfigsEqual(existing.tenantProviderConfig, desired)) {\n changeSet.unchanged.push({ name });\n } else {\n changeSet.updates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n tenantProviderConfig: desired,\n },\n });\n }\n } else {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n },\n });\n }\n }\n\n for (const namespaceName of deletedServices) {\n const existing = await getOrNull(async () => {\n return await client.getTenantConfig({\n workspaceId,\n namespaceName,\n });\n });\n if (!existing) continue;\n changeSet.deletes.push({\n name: `${namespaceName}-tenant-config`,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n return changeSet;\n}\n\nfunction protoTenantConfig(\n tenantConfig: TenantProviderConfig,\n): MessageInitShape<typeof TenantProviderConfigSchema> {\n return {\n providerType: TenantProviderConfig_TenantProviderType.TAILORDB,\n config: {\n config: {\n case: \"tailordb\",\n value: {\n namespace: tenantConfig.namespace,\n type: tenantConfig.type,\n signatureField: tenantConfig.signatureField,\n },\n },\n },\n };\n}\n\ntype CreateMachineUser = {\n name: string;\n request: MessageInitShape<typeof CreateAuthMachineUserRequestSchema>;\n};\n\ntype UpdateMachineUser = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthMachineUserRequestSchema>;\n};\n\ntype DeleteMachineUser = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthMachineUserRequestSchema>;\n};\n\nasync function planMachineUsers(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateMachineUser, UpdateMachineUser, DeleteMachineUser>(\n \"Auth machineUsers\",\n );\n\n const fetchMachineUsers = (authNamespace: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { machineUsers, nextPageToken } = await client.listAuthMachineUsers({\n workspaceId,\n authNamespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [machineUsers, nextPageToken];\n });\n };\n\n for (const auth of auths) {\n const { config } = auth;\n const existingMachineUsers = await fetchMachineUsers(config.name);\n const existingMap = new Map<string, (typeof existingMachineUsers)[number]>();\n existingMachineUsers.forEach((machineUser) => {\n existingMap.set(machineUser.name, machineUser);\n });\n for (const machineUsername of Object.keys(config.machineUsers ?? {})) {\n const machineUser = config.machineUsers?.[machineUsername];\n if (!machineUser) {\n continue;\n }\n const desiredMachineUser = {\n attributes: machineUser.attributeList,\n attributeMap: machineUser.attributes\n ? protoMachineUserAttributeMap(machineUser.attributes)\n : undefined,\n };\n const existing = existingMap.get(machineUsername);\n if (existing) {\n if (!forceApplyAll && areMachineUsersEqual(existing, desiredMachineUser)) {\n changeSet.unchanged.push({ name: machineUsername });\n } else {\n changeSet.updates.push({\n name: machineUsername,\n request: {\n workspaceId,\n authNamespace: config.name,\n name: machineUsername,\n attributes: machineUser.attributeList,\n attributeMap: desiredMachineUser.attributeMap,\n },\n });\n }\n existingMap.delete(machineUsername);\n } else {\n changeSet.creates.push({\n name: machineUsername,\n request: {\n workspaceId,\n authNamespace: config.name,\n name: machineUsername,\n attributes: machineUser.attributeList,\n attributeMap: desiredMachineUser.attributeMap,\n },\n });\n }\n }\n existingMap.forEach((_, name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n authNamespace: config.name,\n name,\n },\n });\n });\n }\n\n for (const namespaceName of deletedServices) {\n const existingMachineUsers = await fetchMachineUsers(namespaceName);\n existingMachineUsers.forEach((machineUser) => {\n changeSet.deletes.push({\n name: machineUser.name,\n request: {\n workspaceId,\n authNamespace: namespaceName,\n name: machineUser.name,\n },\n });\n });\n }\n return changeSet;\n}\n\nfunction protoMachineUserAttributeMap(\n attributeMap: Record<string, AuthAttributeValue>,\n): Record<string, MessageInitShape<typeof ValueSchema>> {\n const ret: Record<string, MessageInitShape<typeof ValueSchema>> = {};\n for (const [key, value] of Object.entries(attributeMap)) {\n ret[key] = fromJson(ValueSchema, value ?? null);\n }\n return ret;\n}\n\nfunction normalizeComparableUserProfileConfig(\n config:\n | MessageInitShape<typeof UserProfileProviderConfigSchema>\n | {\n providerType?: UserProfileProviderConfig_UserProfileProviderType;\n config?: {\n config?: { case?: string; value?: Record<string, unknown> };\n };\n },\n) {\n const comparableConfig = config.config?.config;\n const tailorDBConfig = comparableConfig?.case === \"tailordb\" ? comparableConfig.value : undefined;\n\n return normalizeProtoConfig({\n providerType: config.providerType,\n config: {\n config: {\n case: comparableConfig?.case,\n value: tailorDBConfig\n ? {\n ...tailorDBConfig,\n tenantIdField: tailorDBConfig.tenantIdField || undefined,\n attributesFields: normalizeStringArray(\n tailorDBConfig.attributesFields as readonly string[] | undefined,\n ),\n attributeMap: normalizeProtoConfig(tailorDBConfig.attributeMap),\n }\n : comparableConfig?.value,\n },\n },\n });\n}\n\nfunction areUserProfileConfigsEqual(\n existing: {\n providerType?: UserProfileProviderConfig_UserProfileProviderType;\n config?: { config?: { case?: string; value?: Record<string, unknown> } };\n },\n desired: MessageInitShape<typeof UserProfileProviderConfigSchema>,\n) {\n return areNormalizedEqual(\n normalizeComparableUserProfileConfig(existing),\n normalizeComparableUserProfileConfig(desired),\n );\n}\n\nfunction normalizeComparableTenantProviderConfig(\n config:\n | MessageInitShape<typeof TenantProviderConfigSchema>\n | undefined\n | {\n providerType?: TenantProviderConfig_TenantProviderType;\n config?: {\n config?: { case?: string; value?: Record<string, unknown> };\n };\n },\n) {\n return normalizeProtoConfig(config);\n}\n\nfunction areTenantProviderConfigsEqual(\n existing:\n | MessageInitShape<typeof TenantProviderConfigSchema>\n | undefined\n | {\n providerType?: TenantProviderConfig_TenantProviderType;\n config?: {\n config?: { case?: string; value?: Record<string, unknown> };\n };\n },\n desired: MessageInitShape<typeof TenantProviderConfigSchema>,\n) {\n return areNormalizedEqual(\n normalizeComparableTenantProviderConfig(existing),\n normalizeComparableTenantProviderConfig(desired),\n );\n}\n\nfunction normalizeComparableMachineUser(input: {\n attributes?: readonly string[];\n attributeMap?: Record<string, MessageInitShape<typeof ValueSchema>>;\n}) {\n return normalizeProtoConfig({\n attributes: normalizeStringArray(input.attributes),\n attributeMap: normalizeProtoConfig(input.attributeMap ?? {}),\n });\n}\n\nfunction areMachineUsersEqual(\n existing: {\n attributes?: readonly string[];\n attributeMap?: Record<string, MessageInitShape<typeof ValueSchema>>;\n },\n desired: {\n attributes?: readonly string[];\n attributeMap?: Record<string, MessageInitShape<typeof ValueSchema>>;\n },\n) {\n return areNormalizedEqual(\n normalizeComparableMachineUser(existing),\n normalizeComparableMachineUser(desired),\n );\n}\n\nfunction normalizeComparableOAuth2Client(\n client:\n | MessageInitShape<typeof AuthOAuth2ClientSchema>\n | {\n name?: string;\n description?: string;\n grantTypes?: readonly AuthOAuth2Client_GrantType[];\n redirectUris?: readonly string[];\n clientType?: AuthOAuth2Client_ClientType;\n accessTokenLifetime?: number;\n refreshTokenLifetime?: number;\n requireDpop?: boolean;\n },\n) {\n const accessTokenLifetime = oauth2LifetimeToSeconds(client.accessTokenLifetime);\n const refreshTokenLifetime = oauth2LifetimeToSeconds(client.refreshTokenLifetime);\n\n return normalizeProtoConfig({\n ...client,\n // Platform returns an empty string for an unset description; treat it the same as omitted.\n description: client.description || undefined,\n redirectUris: normalizeStringArray(client.redirectUris),\n grantTypes: (client.grantTypes ?? []).toSorted((left, right) => left - right),\n accessTokenLifetime: accessTokenLifetime ?? 86400,\n refreshTokenLifetime: refreshTokenLifetime ?? 604800,\n requireDpop: client.requireDpop ?? false,\n });\n}\n\nfunction oauth2LifetimeToSeconds(\n lifetime:\n | number\n | {\n seconds?: bigint;\n }\n | undefined,\n) {\n if (typeof lifetime === \"number\") {\n return lifetime;\n }\n\n if (lifetime?.seconds != null) {\n return Number(lifetime.seconds);\n }\n\n return undefined;\n}\n\nfunction areOAuth2ClientsEqual(\n existing: {\n name: string;\n description?: string;\n grantTypes?: readonly AuthOAuth2Client_GrantType[];\n redirectUris?: readonly string[];\n clientType?: AuthOAuth2Client_ClientType;\n accessTokenLifetime?: number;\n refreshTokenLifetime?: number;\n requireDpop?: boolean;\n },\n desired:\n | MessageInitShape<typeof AuthOAuth2ClientSchema>\n | {\n name?: string;\n description?: string;\n grantTypes?: readonly AuthOAuth2Client_GrantType[];\n redirectUris?: readonly string[];\n clientType?: AuthOAuth2Client_ClientType;\n accessTokenLifetime?: number;\n refreshTokenLifetime?: number;\n requireDpop?: boolean;\n },\n) {\n return areNormalizedEqual(\n normalizeComparableOAuth2Client(existing),\n normalizeComparableOAuth2Client(desired),\n );\n}\n\ntype CreateOAuth2Clients = {\n name: string;\n request: MessageInitShape<typeof CreateAuthOAuth2ClientRequestSchema>;\n};\n\ntype UpdateOAuth2Client = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthOAuth2ClientRequestSchema>;\n};\n\ntype DeleteOAuth2Client = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthOAuth2ClientRequestSchema>;\n};\n\ntype ReplaceOAuth2Client = {\n name: string;\n deleteRequest: MessageInitShape<typeof DeleteAuthOAuth2ClientRequestSchema>;\n createRequest: MessageInitShape<typeof CreateAuthOAuth2ClientRequestSchema>;\n};\n\nasync function planOAuth2Clients(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n expectedLocalWebsites: ReadonlySet<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<\n CreateOAuth2Clients,\n UpdateOAuth2Client,\n DeleteOAuth2Client,\n ReplaceOAuth2Client\n >(\"Auth oauth2Clients\");\n\n const fetchOAuth2Clients = (namespaceName: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { oauth2Clients, nextPageToken } = await client.listAuthOAuth2Clients({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [oauth2Clients, nextPageToken];\n });\n };\n\n for (const auth of auths) {\n const { config } = auth;\n const existingOAuth2Clients = await fetchOAuth2Clients(config.name);\n const existingClientsMap = new Map<string, (typeof existingOAuth2Clients)[number]>();\n existingOAuth2Clients.forEach((oauth2Client) => {\n existingClientsMap.set(oauth2Client.name, oauth2Client);\n });\n for (const oauth2ClientName of Object.keys(config.oauth2Clients ?? {})) {\n const oauth2Client = config.oauth2Clients?.[oauth2ClientName];\n if (!oauth2Client) {\n continue;\n }\n const newOAuth2Client = protoOAuth2Client(oauth2ClientName, oauth2Client);\n const resolvedRedirectUris = await resolveStaticWebsiteUrls(\n client,\n workspaceId,\n newOAuth2Client.redirectUris ?? [],\n \"OAuth2 redirect URIs\",\n { expectedLocalNames: expectedLocalWebsites },\n );\n if (existingClientsMap.has(oauth2ClientName)) {\n const existingClient = assertDefined(\n existingClientsMap.get(oauth2ClientName),\n \"existingClientsMap missing entry for oauth2ClientName\",\n );\n if (existingClient.clientType !== newOAuth2Client.clientType) {\n // Client type changed: need to replace (delete then create)\n changeSet.replaces.push({\n name: oauth2ClientName,\n deleteRequest: {\n workspaceId,\n namespaceName: config.name,\n name: oauth2ClientName,\n },\n createRequest: {\n workspaceId,\n namespaceName: config.name,\n oauth2Client: newOAuth2Client,\n },\n });\n } else {\n const desiredComparable = {\n ...newOAuth2Client,\n redirectUris: resolvedRedirectUris,\n accessTokenLifetime: oauth2LifetimeToSeconds(newOAuth2Client.accessTokenLifetime),\n refreshTokenLifetime: oauth2LifetimeToSeconds(newOAuth2Client.refreshTokenLifetime),\n };\n const existingComparable = {\n name: existingClient.name,\n description: existingClient.description,\n grantTypes: existingClient.grantTypes,\n redirectUris: existingClient.redirectUris,\n clientType: existingClient.clientType,\n accessTokenLifetime: oauth2LifetimeToSeconds(existingClient.accessTokenLifetime),\n refreshTokenLifetime: oauth2LifetimeToSeconds(existingClient.refreshTokenLifetime),\n requireDpop: existingClient.requireDpop,\n };\n if (!forceApplyAll && areOAuth2ClientsEqual(existingComparable, desiredComparable)) {\n changeSet.unchanged.push({ name: oauth2ClientName });\n } else {\n changeSet.updates.push({\n name: oauth2ClientName,\n request: {\n workspaceId,\n namespaceName: config.name,\n oauth2Client: newOAuth2Client,\n },\n });\n }\n }\n existingClientsMap.delete(oauth2ClientName);\n } else {\n changeSet.creates.push({\n name: oauth2ClientName,\n request: {\n workspaceId,\n namespaceName: config.name,\n oauth2Client: newOAuth2Client,\n },\n });\n }\n }\n existingClientsMap.forEach((_, name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n name,\n },\n });\n });\n }\n\n for (const namespaceName of deletedServices) {\n const existingOAuth2Clients = await fetchOAuth2Clients(namespaceName);\n existingOAuth2Clients.forEach((oauth2Client) => {\n changeSet.deletes.push({\n name: oauth2Client.name,\n request: {\n workspaceId,\n namespaceName,\n name: oauth2Client.name,\n },\n });\n });\n }\n\n return changeSet;\n}\n\nfunction protoOAuth2Client(\n oauth2ClientName: string,\n oauth2Client: OAuth2Client,\n): MessageInitShape<typeof AuthOAuth2ClientSchema> {\n // `oauth2Client` is already parsed output: AuthConfigSchema.parse (wired in\n // application.ts) validated it and transformed the numeric token lifetimes\n // into Duration ({ seconds, nanos }). Consume it directly instead of\n // re-parsing, which would reject the already-transformed lifetimes.\n return {\n name: oauth2ClientName,\n description: oauth2Client.description,\n grantTypes: oauth2Client.grantTypes.map((grantType) => {\n switch (grantType) {\n case \"authorization_code\":\n return AuthOAuth2Client_GrantType.AUTHORIZATION_CODE;\n case \"refresh_token\":\n return AuthOAuth2Client_GrantType.REFRESH_TOKEN;\n default:\n throw new Error(`Unknown OAuth2 client grant type: ${grantType satisfies never}`);\n }\n }),\n redirectUris: oauth2Client.redirectURIs,\n clientType: (\n {\n confidential: AuthOAuth2Client_ClientType.CONFIDENTIAL,\n public: AuthOAuth2Client_ClientType.PUBLIC,\n browser: AuthOAuth2Client_ClientType.BROWSER,\n } satisfies Record<NonNullable<OAuth2Client[\"clientType\"]>, AuthOAuth2Client_ClientType>\n )[oauth2Client.clientType ?? \"confidential\"],\n accessTokenLifetime: oauth2Client.accessTokenLifetimeSeconds,\n refreshTokenLifetime: oauth2Client.refreshTokenLifetimeSeconds,\n requireDpop: oauth2Client.requireDpop,\n };\n}\n\ntype CreateSCIMConfig = {\n name: string;\n request: MessageInitShape<typeof CreateAuthSCIMConfigRequestSchema>;\n};\n\ntype UpdateSCIMConfig = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthSCIMConfigRequestSchema>;\n};\n\ntype DeleteSCIMConfig = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthSCIMConfigRequestSchema>;\n};\n\nasync function planSCIMConfigs(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n) {\n const changeSet = createChangeSet<CreateSCIMConfig, UpdateSCIMConfig, DeleteSCIMConfig>(\n \"Auth scimConfigs\",\n );\n\n for (const auth of auths) {\n const { config } = auth;\n const name = `${config.name}-scim-config`;\n const existing = await getOrNull(async () => {\n return await client.getAuthSCIMConfig({\n workspaceId,\n namespaceName: config.name,\n });\n });\n if (!existing) {\n if (config.scim) {\n changeSet.creates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n scimConfig: protoSCIMConfig(config.scim),\n },\n });\n }\n } else if (config.scim) {\n changeSet.updates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n scimConfig: protoSCIMConfig(config.scim),\n },\n });\n } else {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n },\n });\n }\n }\n\n for (const namespaceName of deletedServices) {\n const existing = await getOrNull(async () => {\n return await client.getAuthSCIMConfig({\n workspaceId,\n namespaceName,\n });\n });\n if (!existing) continue;\n changeSet.deletes.push({\n name: `${namespaceName}-scim-config`,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n return changeSet;\n}\n\nfunction protoSCIMConfig(scimConfig: SCIMConfig): MessageInitShape<typeof AuthSCIMConfigSchema> {\n let authorizationType;\n switch (scimConfig.authorization.type) {\n case \"bearer\":\n authorizationType = AuthSCIMConfig_AuthorizationType.BEARER;\n break;\n case \"oauth2\":\n authorizationType = AuthSCIMConfig_AuthorizationType.OAUTH2;\n break;\n default:\n throw new Error(\n `Unknown SCIM authorization type: ${scimConfig.authorization.type satisfies never}`,\n );\n }\n\n return {\n machineUserName: scimConfig.machineUserName,\n authorizationType,\n authorizationConfig: {\n case: \"bearerSecret\",\n value: {\n vaultName: scimConfig.authorization.bearerSecret?.vaultName,\n secretKey: scimConfig.authorization.bearerSecret?.secretKey,\n },\n },\n };\n}\n\ntype CreateSCIMResource = {\n name: string;\n request: MessageInitShape<typeof CreateAuthSCIMResourceRequestSchema>;\n};\n\ntype UpdateSCIMResource = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthSCIMResourceRequestSchema>;\n};\n\ntype DeleteSCIMResource = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthSCIMResourceRequestSchema>;\n};\n\nasync function planSCIMResources(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n) {\n const changeSet = createChangeSet<CreateSCIMResource, UpdateSCIMResource, DeleteSCIMResource>(\n \"Auth scimResources\",\n );\n\n const fetchSCIMResources = async (namespaceName: string) => {\n const response = await getOrNull(async () => {\n const { scimResources } = await client.getAuthSCIMResources({\n workspaceId,\n namespaceName,\n });\n return scimResources;\n });\n return response ?? [];\n };\n\n for (const auth of auths) {\n const { config } = auth;\n const existingSCIMResources = await fetchSCIMResources(config.name);\n const existingNameSet = new Set<string>();\n existingSCIMResources.forEach((scimResource) => {\n existingNameSet.add(scimResource.name);\n });\n for (const scimResource of config.scim?.resources ?? []) {\n if (existingNameSet.has(scimResource.name)) {\n changeSet.updates.push({\n name: scimResource.name,\n request: {\n workspaceId,\n namespaceName: config.name,\n scimResource: protoSCIMResource(scimResource),\n },\n });\n existingNameSet.delete(scimResource.name);\n } else {\n changeSet.creates.push({\n name: scimResource.name,\n request: {\n workspaceId,\n namespaceName: config.name,\n scimResource: protoSCIMResource(scimResource),\n },\n });\n }\n }\n existingNameSet.forEach((name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n name,\n },\n });\n });\n }\n\n for (const namespaceName of deletedServices) {\n const existingSCIMResources = await fetchSCIMResources(namespaceName);\n existingSCIMResources.forEach((scimResource) => {\n changeSet.deletes.push({\n name: scimResource.name,\n request: {\n workspaceId,\n namespaceName,\n name: scimResource.name,\n },\n });\n });\n }\n return changeSet;\n}\n\nfunction protoSCIMResource(\n scimResource: SCIMResource,\n): MessageInitShape<typeof AuthSCIMResourceSchema> {\n return {\n name: scimResource.name,\n tailorDbNamespace: scimResource.tailorDBNamespace,\n tailorDbType: scimResource.tailorDBType,\n coreSchema: {\n name: scimResource.coreSchema.name,\n attributes: scimResource.coreSchema.attributes.map((attr) => protoSCIMAttribute(attr)),\n },\n attributeMapping: scimResource.attributeMapping.map((attr) => ({\n tailorDbField: attr.tailorDBField,\n scimPath: attr.scimPath,\n })),\n };\n}\n\nfunction protoSCIMAttribute(attr: SCIMAttribute): MessageInitShape<typeof AuthSCIMAttributeSchema> {\n let typ;\n switch (attr.type) {\n case \"string\":\n typ = AuthSCIMAttribute_Type.STRING;\n break;\n case \"number\":\n typ = AuthSCIMAttribute_Type.NUMBER;\n break;\n case \"boolean\":\n typ = AuthSCIMAttribute_Type.BOOLEAN;\n break;\n case \"datetime\":\n typ = AuthSCIMAttribute_Type.DATETIME;\n break;\n case \"complex\":\n typ = AuthSCIMAttribute_Type.COMPLEX;\n break;\n default:\n throw new Error(`Unknown SCIM attribute type: ${attr.type satisfies never}`);\n }\n let mutability;\n if (attr.mutability) {\n switch (attr.mutability) {\n case \"readOnly\":\n mutability = AuthSCIMAttribute_Mutability.READ_ONLY;\n break;\n case \"readWrite\":\n mutability = AuthSCIMAttribute_Mutability.READ_WRITE;\n break;\n case \"writeOnly\":\n mutability = AuthSCIMAttribute_Mutability.WRITE_ONLY;\n break;\n default:\n throw new Error(`Unknown SCIM attribute mutability: ${attr.mutability satisfies never}`);\n }\n }\n let uniqueness;\n if (attr.uniqueness) {\n switch (attr.uniqueness) {\n case \"none\":\n uniqueness = AuthSCIMAttribute_Uniqueness.NONE;\n break;\n case \"server\":\n uniqueness = AuthSCIMAttribute_Uniqueness.SERVER;\n break;\n case \"global\":\n uniqueness = AuthSCIMAttribute_Uniqueness.GLOBAL;\n break;\n default:\n throw new Error(`Unknown SCIM attribute uniqueness: ${attr.uniqueness satisfies never}`);\n }\n }\n return {\n type: typ,\n name: attr.name,\n description: attr.description,\n mutability,\n required: attr.required,\n multiValued: attr.multiValued,\n uniqueness,\n canonicalValues: attr.canonicalValues ?? undefined,\n subAttributes: attr.subAttributes?.map((attr) => protoSCIMAttribute(attr)),\n };\n}\n\ntype CreateAuthHook = {\n name: string;\n request: MessageInitShape<typeof CreateAuthHookRequestSchema>;\n};\n\ntype UpdateAuthHook = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthHookRequestSchema>;\n};\n\ntype DeleteAuthHook = {\n name: string;\n request: MessageInitShape<typeof DeleteAuthHookRequestSchema>;\n};\n\nfunction areAuthHooksEqual(\n existing: {\n scriptRef?: string;\n invoker?: {\n namespace?: string;\n machineUserName?: string;\n };\n },\n desired: {\n scriptRef?: string;\n invoker?: {\n namespace?: string;\n machineUserName?: string;\n };\n },\n): boolean {\n return areNormalizedEqual(\n {\n scriptRef: existing.scriptRef ?? \"\",\n invoker: existing.invoker\n ? {\n namespace: existing.invoker.namespace ?? \"\",\n machineUserName: existing.invoker.machineUserName ?? \"\",\n }\n : undefined,\n },\n {\n scriptRef: desired.scriptRef ?? \"\",\n invoker: desired.invoker\n ? {\n namespace: desired.invoker.namespace ?? \"\",\n machineUserName: desired.invoker.machineUserName ?? \"\",\n }\n : undefined,\n },\n );\n}\n\n/**\n * Format auth hook changes for grouped dry-run display.\n * @param changeSet - Auth hook changes\n * @param functionRegistryAuthHookChanges - Related function registry changes for auth hooks\n * @returns Display entries for auth hook output\n */\nexport function formatAuthHookChangeEntries(\n changeSet: Pick<\n ChangeSet<HasName, HasName, HasName>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n functionRegistryAuthHookChanges?: RelatedFunctionRegistryChanges,\n): GroupedDisplayEntry[] {\n return formatChangeEntriesWithFunctionRegistry(\n \"authHook\",\n changeSet,\n functionRegistryAuthHookChanges,\n (item) => {\n const [namespace, hookPoint] = item.name.split(\"/\");\n return namespace && hookPoint ? [authHookFunctionName(namespace, hookPoint)] : [];\n },\n {\n getNamespace: (item) => item.name.split(\"/\")[0],\n getDisplayName: (item) => item.name.split(\"/\")[1] ?? item.name,\n },\n );\n}\n\nasync function planAuthHooks(\n client: OperatorClient,\n workspaceId: string,\n auths: ReadonlyArray<Readonly<AuthService>>,\n deletedServices: ReadonlyArray<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateAuthHook, UpdateAuthHook, DeleteAuthHook>(\"Auth hooks\");\n\n for (const auth of auths) {\n const { config } = auth;\n const beforeLogin = config.hooks?.beforeLogin;\n\n const existingHook:\n | {\n scriptRef?: string;\n invoker?: {\n namespace?: string;\n machineUserName?: string;\n };\n }\n | undefined = await getOrNull(async () => {\n const { hook } = await client.getAuthHook({\n workspaceId,\n namespaceName: config.name,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n });\n return hook;\n });\n\n if (beforeLogin) {\n const hookRequest = {\n workspaceId,\n namespaceName: config.name,\n hook: {\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n scriptRef: authHookFunctionName(config.name, \"before-login\"),\n invoker: {\n namespace: config.name,\n machineUserName: beforeLogin.invoker,\n },\n },\n };\n\n if (existingHook) {\n if (!forceApplyAll && areAuthHooksEqual(existingHook, hookRequest.hook)) {\n changeSet.unchanged.push({\n name: `${config.name}/before-login`,\n });\n } else {\n changeSet.updates.push({\n name: `${config.name}/before-login`,\n request: hookRequest,\n });\n }\n } else {\n changeSet.creates.push({\n name: `${config.name}/before-login`,\n request: hookRequest,\n });\n }\n } else if (existingHook) {\n changeSet.deletes.push({\n name: `${config.name}/before-login`,\n request: {\n workspaceId,\n namespaceName: config.name,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n },\n });\n }\n }\n\n for (const namespaceName of deletedServices) {\n const existingHookResponse = await getOrNull(async () => {\n return await client.getAuthHook({\n workspaceId,\n namespaceName,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n });\n });\n if (existingHookResponse) {\n changeSet.deletes.push({\n name: `${namespaceName}/before-login`,\n request: {\n workspaceId,\n namespaceName,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n },\n });\n }\n }\n\n return changeSet;\n}\n","import type { AuthInvoker } from \"#/types/auth.generated\";\n\n/**\n * Normalize an invoker value to the object form required by the proto payload.\n *\n * Accepts either:\n * - `undefined` — returns undefined\n * - a plain string (machine user name) — expands to `{ namespace, machineUserName }` using `authNamespace`\n * - an internal object `{ namespace, machineUserName }` — returned as-is\n * @param invoker - String machine user name or internal object form\n * @param authNamespace - Auth service namespace (required when invoker is a string)\n * @param context - Contextual label used in error messages (e.g. `resolver \"foo\"`)\n * @returns Object form of the invoker, or undefined\n */\nexport function normalizeInvoker(\n invoker: string | AuthInvoker | undefined,\n authNamespace: string | undefined,\n context: string,\n): { namespace: string; machineUserName: string } | undefined {\n if (invoker === undefined) return undefined;\n if (typeof invoker === \"string\") {\n if (!authNamespace) {\n throw new Error(\n `${context} uses a string invoker (\"${invoker}\"), but no Auth service is configured. ` +\n `Configure an Auth service before using invoker.`,\n );\n }\n return { namespace: authNamespace, machineUserName: invoker };\n }\n return invoker;\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n type CreateExecutorExecutorRequestSchema,\n type DeleteExecutorExecutorRequestSchema,\n type UpdateExecutorExecutorRequestSchema,\n} from \"@tailor-platform/tailor-proto/executor_pb\";\nimport {\n type ExecutorExecutorSchema,\n type ExecutorTargetConfigSchema,\n ExecutorTargetType,\n type ExecutorTargetWebhookHeaderSchema,\n type ExecutorTriggerConfigSchema,\n type ExecutorTriggerEventConfigSchema,\n ExecutorTriggerType,\n} from \"@tailor-platform/tailor-proto/executor_resource_pb\";\nimport { getApplicationAuthNamespace } from \"#/cli/shared/auth-namespace\";\nimport { type OperatorClient } from \"#/cli/shared/client\";\nimport { buildExecutorArgsExpr } from \"#/cli/shared/runtime-exprs\";\nimport { stringifyFunction } from \"#/parser/service/tailordb/index\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet, type ChangeSet } from \"./change-set\";\nimport { areNormalizedEqual, normalizeProtoConfig } from \"./compare\";\nimport { executorFunctionName } from \"./function-registry\";\nimport {\n formatChangeEntriesWithFunctionRegistry,\n type GroupedDisplayEntry,\n type RelatedFunctionRegistryChanges,\n} from \"./grouped-display\";\nimport { normalizeInvoker } from \"./invoker\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { Application } from \"#/cli/services/application\";\nimport type { Executor } from \"#/types/executor.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\n\n/**\n * Apply executor-related changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned executor changes\n * @param phase - Apply phase (defaults to \"create-update\")\n * @returns Promise that resolves when executors are applied\n */\nexport async function applyExecutor(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planExecutor>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n) {\n const { changeSet } = result;\n if (phase === \"create-update\") {\n // Executors\n await Promise.all([\n ...changeSet.creates.map(async (create) => {\n await client.createExecutorExecutor(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n await client.updateExecutorExecutor(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n } else {\n // Delete in reverse order of dependencies\n // Executors\n await Promise.all(changeSet.deletes.map((del) => client.deleteExecutorExecutor(del.request)));\n }\n}\n\ntype CreateExecutor = {\n name: string;\n request: MessageInitShape<typeof CreateExecutorExecutorRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateExecutor = {\n name: string;\n request: MessageInitShape<typeof UpdateExecutorExecutorRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteExecutor = {\n name: string;\n request: MessageInitShape<typeof DeleteExecutorExecutorRequestSchema>;\n};\n\n/**\n * Plan executor-related changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes\n */\nexport async function planExecutor(context: PlanContext) {\n const { client, workspaceId, application, forRemoval } = context;\n const changeSet = createChangeSet<CreateExecutor, UpdateExecutor, DeleteExecutor>(\"Executors\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingExecutors = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, pageSize) => {\n const { executors, nextPageToken } = await client.listExecutorExecutors({\n workspaceId,\n pageToken,\n pageSize,\n });\n return [executors, nextPageToken];\n },\n getName: (resource) => resource.name,\n getTrn: (name) => resourceTrn(workspaceId, \"executor\", name),\n });\n\n const executors = forRemoval ? {} : ((await application.executorService?.loadExecutors()) ?? {});\n for (const executor of Object.values(executors)) {\n const existing = existingExecutors[executor.name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"executor\", executor.name),\n appName: application.name,\n appId: application.id,\n });\n const desiredExecutor = protoExecutor(context, executor);\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName: application.name,\n appId: application.id,\n resourceType: \"Executor\",\n resourceName: executor.name,\n conflicts,\n unmanaged,\n });\n\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n areExecutorsEqual(existing.resource, desiredExecutor)\n ) {\n changeSet.unchanged.push({ name: executor.name });\n } else {\n changeSet.updates.push({\n name: executor.name,\n request: {\n workspaceId,\n executor: desiredExecutor,\n },\n metaRequest,\n });\n }\n delete existingExecutors[executor.name];\n } else {\n changeSet.creates.push({\n name: executor.name,\n request: {\n workspaceId,\n executor: desiredExecutor,\n },\n metaRequest,\n });\n }\n }\n Object.entries(existingExecutors).forEach(([name]) => {\n const entry = existingExecutors[name];\n const label = entry?.label;\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: label,\n appName: application.name,\n appId: application.id,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n name,\n },\n });\n }\n });\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n\ntype ExecutorDisplayEntry = GroupedDisplayEntry;\n\nfunction isFunctionBackedExecutor(\n executor: MessageInitShape<typeof ExecutorExecutorSchema> | undefined,\n) {\n return (\n executor?.targetType === ExecutorTargetType.FUNCTION ||\n executor?.targetType === ExecutorTargetType.JOB_FUNCTION\n );\n}\n\n/**\n * Build desired executor configs keyed by executor name from create/update changes.\n * @param changeSet - Executor create/update changes\n * @returns Executor configs keyed by name\n */\nexport function buildPlannedExecutorsByName(\n changeSet: Pick<ChangeSet<CreateExecutor, UpdateExecutor, DeleteExecutor>, \"creates\" | \"updates\">,\n): Record<string, MessageInitShape<typeof ExecutorExecutorSchema> | undefined> {\n return Object.fromEntries(\n [...changeSet.creates, ...changeSet.updates].map((item) => [item.name, item.request.executor]),\n );\n}\n\n/**\n * Format executor changes for grouped dry-run display.\n * @param changeSet - Executor changes\n * @param executors - Desired executor configs keyed by name\n * @param functionRegistryExecutorChanges - Related function registry changes for executors\n * @returns Display entries for executor output\n */\nexport function formatExecutorChangeEntries(\n changeSet: Pick<\n ChangeSet<CreateExecutor, UpdateExecutor, DeleteExecutor>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n executors: Record<string, MessageInitShape<typeof ExecutorExecutorSchema> | undefined>,\n functionRegistryExecutorChanges?: RelatedFunctionRegistryChanges,\n): ExecutorDisplayEntry[] {\n return formatChangeEntriesWithFunctionRegistry(\n \"executor\",\n changeSet,\n functionRegistryExecutorChanges,\n (item, action) => {\n if (action === \"delete\") {\n return [executorFunctionName(item.name)];\n }\n const executor = executors[item.name];\n return executor && isFunctionBackedExecutor(executor)\n ? [executorFunctionName(item.name)]\n : [];\n },\n );\n}\n\nfunction normalizeComparableExecutor(executor: MessageInitShape<typeof ExecutorExecutorSchema>) {\n const normalized = normalizeProtoConfig(executor);\n const webhookHeaders =\n normalized.targetConfig?.config?.case === \"webhook\"\n ? (normalized.targetConfig.config.value.headers ?? []).toSorted((left, right) =>\n (left.key ?? \"\").localeCompare(right.key ?? \"\"),\n )\n : undefined;\n const triggerConfig =\n normalized.triggerConfig?.config?.case === \"incomingWebhook\"\n ? {\n ...normalized.triggerConfig,\n config: {\n ...normalized.triggerConfig.config,\n value: {\n ...normalized.triggerConfig.config.value,\n // secret is server-managed, so omit it from comparison\n secret: undefined,\n },\n },\n }\n : normalized.triggerConfig?.config?.case === \"event\"\n ? {\n ...normalized.triggerConfig,\n config: {\n ...normalized.triggerConfig.config,\n value: {\n ...normalized.triggerConfig.config.value,\n // The platform fills this field in responses even though the SDK never sets it.\n eventType: undefined,\n },\n },\n }\n : normalized.triggerConfig;\n return {\n name: normalized.name,\n description: normalized.description ?? \"\",\n disabled: normalized.disabled ?? false,\n triggerType: normalized.triggerType,\n triggerConfig,\n targetType: normalized.targetType,\n targetConfig:\n normalized.targetConfig?.config?.case === \"webhook\"\n ? {\n ...normalized.targetConfig,\n config: {\n ...normalized.targetConfig.config,\n value: {\n ...normalized.targetConfig.config.value,\n headers: webhookHeaders,\n },\n },\n }\n : normalized.targetConfig?.config?.case === \"function\"\n ? {\n ...normalized.targetConfig,\n config: {\n ...normalized.targetConfig.config,\n value: {\n ...normalized.targetConfig.config.value,\n script: undefined,\n },\n },\n }\n : normalized.targetConfig,\n };\n}\n\nfunction areExecutorsEqual(\n existing: MessageInitShape<typeof ExecutorExecutorSchema>,\n desired: MessageInitShape<typeof ExecutorExecutorSchema>,\n): boolean {\n return areNormalizedEqual(\n normalizeComparableExecutor(existing),\n normalizeComparableExecutor(desired),\n );\n}\n\n/**\n * Resolve a resource's namespace from same-run peer configs, throwing when the\n * name is claimed by more than one namespace in the deploy run.\n * @param sameRunNamespaces - Namespaces keyed by resource name across the deploy run\n * @param resourceName - Resource name to resolve\n * @param resourceLabel - Resource label used in error messages\n * @returns The owning namespace, or undefined when the name is unknown\n */\nexport function resolveSameRunNamespace(\n sameRunNamespaces: ReadonlyMap<string, string | undefined> | undefined,\n resourceName: string,\n resourceLabel: string,\n): string | undefined {\n if (!sameRunNamespaces?.has(resourceName)) {\n return undefined;\n }\n const namespace = sameRunNamespaces.get(resourceName);\n if (!namespace) {\n throw new Error(\n `${resourceLabel} \"${resourceName}\" is defined in multiple namespaces in this deploy run. ` +\n `Move the trigger to the application that owns it or use unique names.`,\n );\n }\n return namespace;\n}\n\n/**\n * Find the local TailorDB namespace that declares the given type.\n * @param application - Loaded application\n * @param typeName - TailorDB type name to look up\n * @returns The declaring namespace, or undefined when no local service has it\n */\nexport function findTailorDBNamespace(\n application: Readonly<Application>,\n typeName: string,\n): string | undefined {\n return application.tailorDBServices.find((service) => Object.hasOwn(service.types, typeName))\n ?.namespace;\n}\n\n/**\n * Find the local resolver namespace that declares the given resolver.\n * @param application - Loaded application\n * @param resolverName - Resolver name to look up\n * @returns The declaring namespace, or undefined when no local service has it\n */\nexport function findResolverNamespace(\n application: Readonly<Application>,\n resolverName: string,\n): string | undefined {\n return application.resolverServices.find((service) =>\n Object.values(service.resolvers).some((resolver) => resolver.name === resolverName),\n )?.namespace;\n}\n\nfunction resolveNamespace(params: {\n resourceLabel: string;\n resourceName: string;\n localNamespaces: ReadonlyArray<string>;\n findLocalNamespace: () => string | undefined;\n sameRunNamespaces?: ReadonlyMap<string, string | undefined>;\n}): string {\n const { resourceLabel, resourceName, localNamespaces, findLocalNamespace, sameRunNamespaces } =\n params;\n const localNamespace = findLocalNamespace();\n if (localNamespace !== undefined) {\n return localNamespace;\n }\n const sameRunNamespace = resolveSameRunNamespace(sameRunNamespaces, resourceName, resourceLabel);\n if (sameRunNamespace !== undefined) {\n return sameRunNamespace;\n }\n const sameRunAvailableNamespaces = sameRunNamespaces\n ? [...new Set([...sameRunNamespaces.values()].filter((value) => value !== undefined))]\n : [];\n const availableNamespaces = [...localNamespaces, ...sameRunAvailableNamespaces];\n throw new Error(\n `${resourceLabel} \"${resourceName}\" not found in any namespace. Available namespaces: ${availableNamespaces.join(\", \")}`,\n );\n}\n\nfunction resolveTailorDBNamespace(\n application: Readonly<Application>,\n typeName: string,\n sameRunNamespaces?: ReadonlyMap<string, string | undefined>,\n): string {\n return resolveNamespace({\n resourceLabel: \"TailorDB type\",\n resourceName: typeName,\n localNamespaces: application.tailorDBServices.map((service) => service.namespace),\n findLocalNamespace: () => findTailorDBNamespace(application, typeName),\n sameRunNamespaces,\n });\n}\n\nfunction resolveResolverNamespace(\n application: Readonly<Application>,\n resolverName: string,\n sameRunNamespaces?: ReadonlyMap<string, string | undefined>,\n): string {\n return resolveNamespace({\n resourceLabel: \"Resolver\",\n resourceName: resolverName,\n localNamespaces: application.resolverServices.map((service) => service.namespace),\n findLocalNamespace: () => findResolverNamespace(application, resolverName),\n sameRunNamespaces,\n });\n}\n\n/**\n * Collect IdP names declared by the application, including external IdP\n * subgraphs.\n * @param application - Loaded application\n * @returns IdP names visible from the application config\n */\nexport function collectApplicationIdpNames(\n application: Readonly<Application>,\n): ReadonlySet<string> {\n const names = new Set(application.idpServices.map((idp) => idp.name));\n for (const subgraph of application.subgraphs) {\n if (subgraph.Type === \"idp\") {\n names.add(subgraph.Name);\n }\n }\n return names;\n}\n\nfunction resolveIdpNamespace(\n application: Readonly<Application>,\n executorName: string,\n idpName: string | undefined,\n sameRunIdpNames?: ReadonlySet<string>,\n): string {\n const localIdpNames = collectApplicationIdpNames(application);\n if (idpName !== undefined) {\n const candidateNames = sameRunIdpNames ?? localIdpNames;\n if (!candidateNames.has(idpName)) {\n const available = [...candidateNames].join(\", \");\n throw new Error(\n `Executor \"${executorName}\" specifies IdP \"${idpName}\" in its idpUser trigger, ` +\n `but no IdP with that name is configured. Available IdPs: ${available}`,\n );\n }\n return idpName;\n }\n if (localIdpNames.size === 0) {\n throw new Error(`Executor \"${executorName}\" uses an idpUser trigger but no IdP is configured.`);\n }\n if (localIdpNames.size > 1) {\n const available = [...localIdpNames].join(\", \");\n throw new Error(\n `Executor \"${executorName}\" uses an idpUser trigger but the project defines multiple IdPs ` +\n `(${available}). Specify which IdP to subscribe to via the trigger's \"idp\" option.`,\n );\n }\n return assertDefined([...localIdpNames][0], \"idp service missing\");\n}\n\nfunction resolveAuthNamespace(application: Readonly<Application>): string {\n const authNamespace = getApplicationAuthNamespace(application);\n if (!authNamespace) {\n throw new Error(\"No Auth service configured\");\n }\n return authNamespace;\n}\n\nfunction protoExecutor(\n context: PlanContext,\n executor: Executor,\n): MessageInitShape<typeof ExecutorExecutorSchema> {\n const { application } = context;\n const appName = application.name;\n const env = application.env;\n const trigger = executor.trigger;\n let triggerType: ExecutorTriggerType;\n let triggerConfig: MessageInitShape<typeof ExecutorTriggerConfigSchema>;\n\n const argsExpr = buildExecutorArgsExpr(trigger.kind, env);\n\n function typedEventTrigger(\n typedConfig: MessageInitShape<typeof ExecutorTriggerEventConfigSchema>[\"typedConfig\"],\n ): MessageInitShape<typeof ExecutorTriggerConfigSchema> {\n return { config: { case: \"event\", value: { typedConfig } } };\n }\n\n switch (trigger.kind) {\n case \"schedule\":\n triggerType = ExecutorTriggerType.SCHEDULE;\n triggerConfig = {\n config: {\n case: \"schedule\",\n value: {\n timezone: trigger.timezone,\n frequency: trigger.cron,\n },\n },\n };\n break;\n case \"tailordb\":\n triggerType = ExecutorTriggerType.EVENT;\n triggerConfig = typedEventTrigger({\n case: \"tailordb\",\n value: {\n eventTypes: trigger.events,\n namespaceName: resolveTailorDBNamespace(\n application,\n trigger.typeName,\n context.tailorDBTypeNamespaces,\n ),\n typeName: trigger.typeName,\n ...(trigger.condition\n ? { condition: { expr: `(${stringifyFunction(trigger.condition)})(${argsExpr})` } }\n : {}),\n },\n });\n break;\n case \"resolverExecuted\":\n triggerType = ExecutorTriggerType.EVENT;\n triggerConfig = typedEventTrigger({\n case: \"pipeline\",\n value: {\n eventTypes: [\"pipeline.resolver.executed\"],\n namespaceName: resolveResolverNamespace(\n application,\n trigger.resolverName,\n context.resolverNamespaces,\n ),\n resolverName: trigger.resolverName,\n ...(trigger.condition\n ? { condition: { expr: `(${stringifyFunction(trigger.condition)})(${argsExpr})` } }\n : {}),\n },\n });\n break;\n case \"incomingWebhook\":\n triggerType = ExecutorTriggerType.INCOMING_WEBHOOK;\n triggerConfig = {\n config: {\n case: \"incomingWebhook\",\n value: trigger.response\n ? {\n response: {\n ...(trigger.response.body\n ? {\n body: {\n expr: `(${stringifyFunction(trigger.response.body)})(${argsExpr})`,\n },\n }\n : {}),\n ...(trigger.response.statusCode != null\n ? { statusCode: trigger.response.statusCode }\n : {}),\n },\n }\n : {},\n },\n };\n break;\n case \"idpUser\":\n triggerType = ExecutorTriggerType.EVENT;\n triggerConfig = typedEventTrigger({\n case: \"idp\",\n value: {\n eventTypes: trigger.events,\n namespaceName: resolveIdpNamespace(\n application,\n executor.name,\n trigger.idp,\n context.idpNames,\n ),\n },\n });\n break;\n case \"authAccessToken\":\n triggerType = ExecutorTriggerType.EVENT;\n triggerConfig = typedEventTrigger({\n case: \"auth\",\n value: {\n eventTypes: trigger.events,\n namespaceName: resolveAuthNamespace(application),\n },\n });\n break;\n case \"workflowExecution\":\n case \"workflowJobExecution\":\n triggerType = ExecutorTriggerType.EVENT;\n triggerConfig = typedEventTrigger({\n case: \"workflow\",\n value: {\n eventTypes: trigger.events,\n workflowName: trigger.workflowName,\n ...(trigger.condition\n ? { condition: { expr: `(${stringifyFunction(trigger.condition)})(${argsExpr})` } }\n : {}),\n },\n });\n break;\n default:\n throw new Error(`Unknown trigger: ${trigger satisfies never}`);\n }\n\n const target = executor.operation;\n let targetType: ExecutorTargetType;\n let targetConfig: MessageInitShape<typeof ExecutorTargetConfigSchema>;\n\n const authNamespace = getApplicationAuthNamespace(application);\n const invokerContext = `Executor \"${executor.name}\"`;\n\n switch (target.kind) {\n case \"webhook\": {\n targetType = ExecutorTargetType.WEBHOOK;\n targetConfig = {\n config: {\n case: \"webhook\",\n value: {\n url: {\n expr: `(${stringifyFunction(target.url)})(${argsExpr})`,\n },\n headers: target.headers\n ? Object.entries(target.headers).map(([key, v]) => {\n let value: MessageInitShape<typeof ExecutorTargetWebhookHeaderSchema>[\"value\"];\n if (typeof v === \"string\") {\n value = {\n case: \"rawValue\",\n value: v,\n };\n } else {\n value = {\n case: \"secretValue\",\n value: {\n vaultName: v.vault,\n secretKey: v.key,\n },\n };\n }\n return { key, value };\n })\n : undefined,\n body: target.requestBody\n ? {\n expr: `(${stringifyFunction(target.requestBody)})(${argsExpr})`,\n }\n : undefined,\n },\n },\n };\n break;\n }\n case \"graphql\": {\n targetType = ExecutorTargetType.TAILOR_GRAPHQL;\n targetConfig = {\n config: {\n case: \"tailorGraphql\",\n value: {\n appName: target.appName ?? appName,\n query: target.query,\n variables: target.variables\n ? {\n expr: `(${stringifyFunction(target.variables)})(${argsExpr})`,\n }\n : undefined,\n invoker: normalizeInvoker(target.invoker, authNamespace, invokerContext),\n },\n },\n };\n break;\n }\n case \"function\":\n case \"jobFunction\": {\n if (target.kind === \"function\") {\n targetType = ExecutorTargetType.FUNCTION;\n } else {\n targetType = ExecutorTargetType.JOB_FUNCTION;\n }\n\n targetConfig = {\n config: {\n case: \"function\",\n value: {\n name: \"operation\",\n scriptRef: executorFunctionName(executor.name),\n variables: {\n expr: argsExpr,\n },\n invoker: normalizeInvoker(target.invoker, authNamespace, invokerContext),\n },\n },\n };\n break;\n }\n case \"workflow\": {\n targetType = ExecutorTargetType.WORKFLOW;\n targetConfig = {\n config: {\n case: \"workflow\",\n value: {\n workflowName: target.workflowName,\n variables:\n target.args !== undefined\n ? typeof target.args === \"function\"\n ? { expr: `(${stringifyFunction(target.args)})(${argsExpr})` }\n : { expr: JSON.stringify(target.args) }\n : undefined,\n invoker: normalizeInvoker(target.invoker, authNamespace, invokerContext),\n },\n },\n };\n break;\n }\n default:\n throw new Error(`Unknown target: ${target satisfies never}`);\n }\n\n return {\n name: executor.name,\n description: executor.description,\n disabled: executor.disabled,\n triggerType,\n triggerConfig,\n targetType,\n targetConfig,\n };\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n type CreatePipelineResolverRequestSchema,\n type CreatePipelineServiceRequestSchema,\n type DeletePipelineResolverRequestSchema,\n type DeletePipelineServiceRequestSchema,\n type UpdatePipelineResolverRequestSchema,\n type UpdatePipelineServiceRequestSchema,\n} from \"@tailor-platform/tailor-proto/pipeline_pb\";\nimport {\n type PipelineResolver_FieldSchema,\n PipelineResolver_OperationType,\n type PipelineResolver_PipelineSchema,\n type PipelineResolver_TypeSchema,\n type PipelineResolverSchema,\n} from \"@tailor-platform/tailor-proto/pipeline_resource_pb\";\nimport * as inflection from \"inflection\";\nimport { type ResolverService } from \"#/cli/services/resolver/service\";\nimport { getApplicationAuthNamespace } from \"#/cli/shared/auth-namespace\";\nimport { fetchAllTolerant, type OperatorClient } from \"#/cli/shared/client\";\nimport {\n assertNoPublishEventsConflict,\n publishEventsConflict,\n resolvePublishEvents,\n} from \"#/cli/shared/publish-events\";\nimport { buildResolverOperationHookExpr } from \"#/cli/shared/runtime-exprs\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet, type ChangeSet } from \"./change-set\";\nimport { areNormalizedEqual, normalizeProtoConfig } from \"./compare\";\nimport { resolverFunctionName } from \"./function-registry\";\nimport {\n formatChangeEntriesWithFunctionRegistry,\n type GroupedDisplayEntry,\n type RelatedFunctionRegistryChanges,\n} from \"./grouped-display\";\nimport { normalizeInvoker } from \"./invoker\";\nimport {\n addDependencyRecords,\n buildMetaRequest,\n type DependentAppsByResource,\n eventSourceKey,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resolverTrn,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { Executor } from \"#/types/executor.generated\";\nimport type { TailorField } from \"#/types/field.generated\";\nimport type { Resolver } from \"#/types/resolver.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\n\n// Scalar type mapping for field type conversion\nconst SCALAR_TYPE_MAP = {\n uuid: { kind: \"ScalarType\", name: \"ID\" },\n string: { kind: \"ScalarType\", name: \"String\" },\n integer: { kind: \"ScalarType\", name: \"Int\" },\n float: { kind: \"ScalarType\", name: \"Float\" },\n decimal: { kind: \"CustomScalarType\", name: \"Decimal\" },\n boolean: { kind: \"ScalarType\", name: \"Boolean\" },\n date: { kind: \"CustomScalarType\", name: \"Date\" },\n datetime: { kind: \"CustomScalarType\", name: \"DateTime\" },\n time: { kind: \"CustomScalarType\", name: \"Time\" },\n} as const satisfies Record<\n Exclude<TailorField[\"type\"], \"enum\" | \"nested\">,\n { kind: \"ScalarType\" | \"CustomScalarType\"; name: string }\n>;\n\n/**\n * Apply resolver pipeline changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned pipeline changes\n * @param phase - Apply phase\n * @returns Promise that resolves when pipeline changes are applied\n */\nexport async function applyPipeline(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planPipeline>>,\n phase: Exclude<ApplyPhase, \"delete\"> = \"create-update\",\n) {\n const { changeSet } = result;\n if (phase === \"create-update\") {\n // Services\n await Promise.all([\n ...changeSet.service.creates.map(async (create) => {\n await client.createPipelineService(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.service.updates.map(async (update) => {\n await client.updatePipelineService(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n\n // Resolvers. An unchanged resolver still gets its labels written, because its\n // dependency records can change while its definition does not.\n await Promise.all([\n ...changeSet.resolver.creates.map(async (create) => {\n await client.createPipelineResolver(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.resolver.updates.map(async (update) => {\n await client.updatePipelineResolver(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ...changeSet.resolver.unchanged.flatMap((entry) =>\n entry.metaRequest ? [writeMetadataLabels(client, entry.metaRequest)] : [],\n ),\n ]);\n } else if (phase === \"delete-resources\") {\n // Delete in reverse order of dependencies\n // Resolvers\n await Promise.all(\n changeSet.resolver.deletes.map((del) => client.deletePipelineResolver(del.request)),\n );\n } else {\n // Services only\n await Promise.all(\n changeSet.service.deletes.map((del) => client.deletePipelineService(del.request)),\n );\n }\n}\n\n/**\n * Plan resolver pipeline changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes\n */\nexport async function planPipeline(context: PlanContext) {\n const { client, workspaceId, application, forRemoval, forceApplyAll = false } = context;\n const pipelines: Readonly<ResolverService>[] = [];\n if (!forRemoval) {\n for (const pipeline of application.resolverServices) {\n await pipeline.loadResolvers();\n pipelines.push(pipeline);\n }\n }\n const executors = forRemoval\n ? []\n : Object.values((await application.executorService?.loadExecutors()) ?? {});\n\n const {\n changeSet: serviceChangeSet,\n conflicts,\n unmanaged,\n resourceOwners,\n } = await planServices(client, workspaceId, application.name, application.id, pipelines);\n const deletedServices = serviceChangeSet.deletes.map((del) => del.name);\n const { changeSet: resolverChangeSet } = await planResolvers(\n client,\n workspaceId,\n pipelines,\n executors,\n context.executorUsedResolvers ?? new Set<string>(),\n deletedServices,\n application.env,\n getApplicationAuthNamespace(application),\n forceApplyAll,\n {\n appName: application.name,\n appId: application.id,\n dependentApps: context.dependentApps,\n runAppIds: context.runAppIds,\n },\n );\n\n return {\n changeSet: {\n service: serviceChangeSet,\n resolver: resolverChangeSet,\n },\n conflicts,\n unmanaged,\n resourceOwners,\n };\n}\n\ntype CreateService = {\n name: string;\n request: MessageInitShape<typeof CreatePipelineServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateService = {\n name: string;\n request: MessageInitShape<typeof UpdatePipelineServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteService = {\n name: string;\n request: MessageInitShape<typeof DeletePipelineServiceRequestSchema>;\n};\n\nasync function planServices(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n pipelines: ReadonlyArray<Readonly<ResolverService>>,\n) {\n const changeSet = createChangeSet<CreateService, UpdateService, DeleteService>(\n \"Pipeline services\",\n );\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingServices = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, maxPageSize) => {\n const { pipelineServices, nextPageToken } = await client.listPipelineServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [pipelineServices, nextPageToken];\n },\n getName: (resource) => resource.namespace?.name,\n getTrn: (name) => resourceTrn(workspaceId, \"pipeline\", name),\n });\n\n for (const pipeline of pipelines) {\n const existing = existingServices[pipeline.namespace];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"pipeline\", pipeline.namespace),\n appName,\n appId,\n });\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"Pipeline service\",\n resourceName: pipeline.namespace,\n conflicts,\n unmanaged,\n });\n\n if (owned && hasMatchingSdkVersion(existing.allLabels, metaRequest.labels)) {\n changeSet.unchanged.push({ name: pipeline.namespace });\n } else {\n changeSet.updates.push({\n name: pipeline.namespace,\n request: {\n workspaceId,\n namespaceName: pipeline.namespace,\n },\n metaRequest,\n });\n }\n delete existingServices[pipeline.namespace];\n } else {\n changeSet.creates.push({\n name: pipeline.namespace,\n request: {\n workspaceId,\n namespaceName: pipeline.namespace,\n },\n metaRequest,\n });\n }\n }\n Object.entries(existingServices).forEach(([namespaceName]) => {\n const entry = existingServices[namespaceName];\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: entry?.label,\n appName,\n appId,\n resourceOwners,\n });\n // Only delete services managed by this application (by name or stable id)\n if (owned) {\n changeSet.deletes.push({\n name: namespaceName,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n });\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n\ntype CreateResolver = {\n name: string;\n request: MessageInitShape<typeof CreatePipelineResolverRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateResolver = {\n name: string;\n request: MessageInitShape<typeof UpdatePipelineResolverRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\n/**\n * A resolver whose definition is unchanged but whose dependency records are not.\n * The plan shows it as unchanged; apply still writes its labels.\n */\ntype UnchangedResolver = {\n name: string;\n metaRequest?: MetadataLabelWrite;\n};\n\ntype DeleteResolver = {\n name: string;\n request: MessageInitShape<typeof DeletePipelineResolverRequestSchema>;\n};\n\n/** What planResolvers needs to record dependencies on each resolver. */\ntype ResolverRecordInputs = {\n appName?: string;\n appId?: string;\n dependentApps?: DependentAppsByResource;\n runAppIds?: ReadonlySet<string>;\n};\n\nasync function planResolvers(\n client: OperatorClient,\n workspaceId: string,\n pipelines: ReadonlyArray<Readonly<ResolverService>>,\n executors: ReadonlyArray<Executor>,\n initialExecutorUsedResolvers: ReadonlySet<string>,\n deletedServices: ReadonlyArray<string>,\n env: Record<string, string | number | boolean>,\n authNamespace: string | undefined,\n forceApplyAll = false,\n records: ResolverRecordInputs = {},\n) {\n const changeSet = createChangeSet<\n CreateResolver,\n UpdateResolver,\n DeleteResolver,\n never,\n UnchangedResolver\n >(\"Pipeline resolvers\");\n const { appName, appId, dependentApps, runAppIds } = records;\n\n /**\n * Build one resolver's metadata write, carrying the dependency records that\n * belong to it. The resolver is what publishes, so the record lives there.\n * @param namespace - Namespace holding the resolver\n * @param resolver - Resolver being planned\n * @returns The resolver's metadata write\n */\n const resolverMetaRequest = async (\n namespace: string,\n resolver: { name: string; publishEvents?: boolean },\n ) => {\n const trn = resolverTrn(workspaceId, namespace, resolver.name);\n return addDependencyRecords(await buildMetaRequest({ trn, appName: appName ?? \"\", appId }), {\n key: eventSourceKey.resolver(namespace, resolver.name),\n dependentApps,\n runAppIds,\n pinned: resolver.publishEvents !== undefined,\n });\n };\n\n const fetchResolvers = (namespaceName: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { pipelineResolvers, nextPageToken } = await client.listPipelineResolvers({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [pipelineResolvers, nextPageToken];\n });\n };\n\n const executorUsedResolvers = new Set(initialExecutorUsedResolvers);\n for (const executor of executors) {\n if (executor.trigger.kind === \"resolverExecuted\") {\n executorUsedResolvers.add(executor.trigger.resolverName);\n }\n }\n\n // Reject a conflicting opt-out before any request, not partway through.\n for (const pipeline of pipelines) {\n for (const resolver of Object.values(pipeline.resolvers)) {\n assertNoPublishEventsConflict({\n explicit: resolver.publishEvents,\n subscribed: executorUsedResolvers.has(resolver.name),\n conflict: publishEventsConflict.resolver(resolver.name),\n });\n }\n }\n\n for (const pipeline of pipelines) {\n const existingResolvers = await fetchResolvers(pipeline.namespace);\n const existingResolversMap = new Map(\n existingResolvers.map((resolver) => [resolver.name, resolver]),\n );\n for (const resolver of Object.values(pipeline.resolvers)) {\n const desiredResolver = processResolver(\n pipeline.namespace,\n resolver,\n executorUsedResolvers,\n env,\n authNamespace,\n );\n const existingResolver = existingResolversMap.get(resolver.name);\n const metaRequest = await resolverMetaRequest(pipeline.namespace, resolver);\n if (existingResolver) {\n const { pipelineResolver: existingResolverDetail } = await client.getPipelineResolver({\n workspaceId,\n namespaceName: pipeline.namespace,\n resolverName: resolver.name,\n });\n if (\n !forceApplyAll &&\n existingResolverDetail &&\n areResolversEqual(existingResolverDetail, desiredResolver)\n ) {\n // The definition matches, but the records may not, so the labels still go.\n changeSet.unchanged.push({ name: resolver.name, metaRequest });\n } else {\n changeSet.updates.push({\n name: resolver.name,\n request: {\n workspaceId,\n namespaceName: pipeline.namespace,\n pipelineResolver: desiredResolver,\n },\n metaRequest,\n });\n }\n existingResolversMap.delete(resolver.name);\n } else {\n changeSet.creates.push({\n name: resolver.name,\n request: {\n workspaceId,\n namespaceName: pipeline.namespace,\n pipelineResolver: desiredResolver,\n },\n metaRequest,\n });\n }\n }\n existingResolversMap.forEach((_resolver, name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: pipeline.namespace,\n resolverName: name,\n },\n });\n });\n }\n\n for (const namespaceName of deletedServices) {\n const existingResolvers = await fetchResolvers(namespaceName);\n existingResolvers.forEach((resolver) => {\n changeSet.deletes.push({\n name: resolver.name,\n request: {\n workspaceId,\n namespaceName,\n resolverName: resolver.name,\n },\n });\n });\n }\n return { changeSet };\n}\n\ntype ResolverDisplayEntry = GroupedDisplayEntry;\n\n/**\n * Format resolver changes for grouped dry-run display.\n * @param changeSet - Resolver changes\n * @param resolverFunctionChanges - Related function registry changes for resolvers\n * @returns Display entries for resolver output\n */\nexport function formatResolverChangeEntries(\n changeSet: Pick<\n ChangeSet<CreateResolver, UpdateResolver, DeleteResolver>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n resolverFunctionChanges?: RelatedFunctionRegistryChanges,\n): ResolverDisplayEntry[] {\n return formatChangeEntriesWithFunctionRegistry(\n \"resolver\",\n changeSet,\n resolverFunctionChanges,\n (item) => {\n const namespace = item.request.namespaceName;\n return namespace ? [resolverFunctionName(namespace, item.name)] : [];\n },\n {\n getNamespace: (item) => item.request.namespaceName,\n },\n );\n}\n\nfunction normalizeComparableResolver(resolver: MessageInitShape<typeof PipelineResolverSchema>) {\n const normalized = normalizeProtoConfig(resolver);\n return {\n name: normalized.name,\n description: normalized.description ?? \"\",\n authorization: normalized.authorization ?? \"\",\n operationType: normalized.operationType,\n publishExecutionEvents: normalized.publishExecutionEvents ?? false,\n inputs: normalizeComparableFields(normalized.inputs),\n response: normalizeComparableField(normalized.response),\n pipelines: normalizeComparablePipelines(normalized.pipelines),\n };\n}\n\nfunction areResolversEqual(\n existing: MessageInitShape<typeof PipelineResolverSchema>,\n desired: MessageInitShape<typeof PipelineResolverSchema>,\n): boolean {\n return areNormalizedEqual(\n normalizeComparableResolver(existing),\n normalizeComparableResolver(desired),\n );\n}\n\nfunction normalizeComparablePipelines(\n pipelines: MessageInitShape<typeof PipelineResolverSchema>[\"pipelines\"],\n): Array<{\n name: string;\n operationName: string;\n description: string;\n operationType: PipelineResolver_OperationType | undefined;\n operationSourceRef: string;\n operationHook: string;\n postScript: string;\n skipOperationOnError: boolean;\n invoker:\n | NonNullable<MessageInitShape<typeof PipelineResolverSchema>[\"pipelines\"]>[number][\"invoker\"]\n | undefined;\n}> {\n return (pipelines ?? []).map((pipeline) => ({\n name: pipeline.name ?? \"\",\n operationName: pipeline.operationName ?? \"\",\n description: pipeline.description ?? \"\",\n operationType: pipeline.operationType,\n operationSourceRef: pipeline.operationSourceRef ?? \"\",\n operationHook: pipeline.operationHook?.expr ?? \"\",\n postScript: pipeline.postScript ?? \"\",\n skipOperationOnError: pipeline.skipOperationOnError ?? false,\n invoker: pipeline.invoker ?? undefined,\n }));\n}\n\nfunction normalizeComparableFields(\n fields: MessageInitShape<typeof PipelineResolverSchema>[\"inputs\"],\n): Array<ReturnType<typeof normalizeComparableField>> {\n return (fields ?? []).map((field) => normalizeComparableField(field));\n}\n\nfunction normalizeComparableField(\n field: MessageInitShape<typeof PipelineResolver_FieldSchema> | undefined,\n):\n | {\n name: string;\n array: boolean;\n required: boolean;\n description: string;\n type: ReturnType<typeof normalizeComparableType>;\n }\n | undefined {\n if (!field) {\n return undefined;\n }\n return {\n name: field.name ?? \"\",\n array: field.array ?? false,\n required: field.required ?? true,\n description: field.description ?? \"\",\n type: normalizeComparableType(field.type),\n };\n}\n\nfunction normalizeComparableType(\n type: MessageInitShape<typeof PipelineResolver_TypeSchema> | undefined,\n):\n | {\n kind: string;\n name: string;\n required: boolean;\n description: string;\n allowedValues: unknown[];\n fields: Array<ReturnType<typeof normalizeComparableField>>;\n }\n | undefined {\n if (!type) {\n return undefined;\n }\n return {\n kind: type.kind ?? \"\",\n name: type.name ?? \"\",\n required: type.required ?? true,\n description: type.description ?? \"\",\n allowedValues: type.allowedValues ?? [],\n fields: (type.fields ?? []).map((field) => normalizeComparableField(field)),\n };\n}\n\nfunction processResolver(\n namespace: string,\n resolver: Resolver,\n executorUsedResolvers: ReadonlySet<string>,\n env: Record<string, string | number | boolean>,\n authNamespace: string | undefined,\n): MessageInitShape<typeof PipelineResolverSchema> {\n const pipelines: MessageInitShape<typeof PipelineResolver_PipelineSchema>[] = [\n {\n name: \"body\",\n operationName: \"body\",\n description: `${resolver.name} function body`,\n operationType: PipelineResolver_OperationType.FUNCTION,\n operationSourceRef: resolverFunctionName(namespace, resolver.name),\n operationHook: {\n expr: buildResolverOperationHookExpr(env),\n },\n postScript: `args.body`,\n invoker: normalizeInvoker(resolver.invoker, authNamespace, `Resolver \"${resolver.name}\"`),\n },\n ];\n\n const typeBaseName = inflection.camelize(resolver.name);\n\n // Build inputs\n const inputs: MessageInitShape<typeof PipelineResolver_FieldSchema>[] = resolver.input\n ? protoFields(resolver.input, `${typeBaseName}Input`, true)\n : [];\n\n // Build response\n const response: MessageInitShape<typeof PipelineResolver_FieldSchema> = assertDefined(\n protoFields({ \"\": resolver.output }, `${typeBaseName}Output`, false)[0],\n \"resolver output field missing\",\n );\n\n // Build description (combine resolver description and output description)\n const resolverDescription = resolver.description || `${resolver.name} resolver`;\n const outputDescription = resolver.output.metadata.description;\n const combinedDescription = outputDescription\n ? `${resolverDescription}\\n\\nReturns:\\n${outputDescription}`\n : resolverDescription;\n\n const publishExecutionEvents = resolvePublishEvents({\n explicit: resolver.publishEvents,\n subscribed: executorUsedResolvers.has(resolver.name),\n conflict: publishEventsConflict.resolver(resolver.name),\n });\n\n return {\n authorization: \"true==true\",\n description: combinedDescription,\n inputs,\n name: resolver.name,\n operationType: resolver.operation,\n response,\n pipelines,\n publishExecutionEvents,\n };\n}\n\nfunction protoFields(\n fields: Record<string, TailorField>,\n baseName: string,\n isInput: boolean,\n): MessageInitShape<typeof PipelineResolver_FieldSchema>[] {\n return Object.entries(fields).map(([fieldName, field]) => {\n let type: MessageInitShape<typeof PipelineResolver_TypeSchema>;\n const hasCreateHook = isInput && field.metadata.hooks?.create !== undefined;\n const required = hasCreateHook ? false : (field.metadata.required ?? true);\n\n if (field.type === \"nested\") {\n const typeName = field.metadata.typeName ?? `${baseName}${inflection.camelize(fieldName)}`;\n type = {\n kind: \"UserDefined\",\n name: typeName,\n description: field.metadata.description ?? \"\",\n required,\n fields: protoFields(field.fields, typeName, isInput),\n };\n } else if (field.type === \"enum\") {\n const typeName = field.metadata.typeName ?? `${baseName}${inflection.camelize(fieldName)}`;\n type = {\n kind: \"EnumType\",\n name: typeName,\n required,\n allowedValues: field.metadata.allowedValues,\n };\n } else {\n type = { ...SCALAR_TYPE_MAP[field.type], required };\n }\n\n return {\n name: fieldName,\n description: field.metadata.description,\n array: field.metadata.array ?? false,\n required,\n type,\n };\n });\n}\n","import { fetchAllTolerant, type OperatorClient } from \"#/cli/shared/client\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet } from \"./change-set\";\nimport { buildMetaRequest, hasMatchingSdkVersion, resourceTrn, writeMetadataLabels } from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport {\n hashValue,\n loadSecretsState,\n saveSecretsState,\n serializeUpdateTime,\n withSecretsStateLock,\n} from \"./secrets-state\";\nimport type { ApplyPhase, PlanContext } from \"#/cli/commands/deploy/types\";\nimport type { Application } from \"#/cli/services/application\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type {\n CreateSecretManagerSecretRequestSchema,\n CreateSecretManagerVaultRequestSchema,\n UpdateSecretManagerSecretRequestSchema,\n} from \"@tailor-platform/tailor-proto/secret_manager_pb\";\n\ntype CreateVault = {\n name: string;\n workspaceId: string;\n};\n\ntype ExistingVault = {\n name: string;\n workspaceId: string;\n};\n\ntype DeleteVault = {\n name: string;\n workspaceId: string;\n};\n\ntype CreateSecret = {\n name: string;\n secretName: string;\n workspaceId: string;\n vaultName: string;\n value: string;\n};\n\ntype UpdateSecret = {\n name: string;\n secretName: string;\n workspaceId: string;\n vaultName: string;\n value: string;\n};\n\ntype DeleteSecret = {\n name: string;\n secretName: string;\n workspaceId: string;\n vaultName: string;\n};\n\n/**\n * Build the CreateSecretManagerVault request for a planned vault create.\n * @param create - Planned vault create\n * @returns Request init shape\n */\nexport function vaultCreateRequest(\n create: CreateVault,\n): MessageInitShape<typeof CreateSecretManagerVaultRequestSchema> {\n return {\n workspaceId: create.workspaceId,\n secretmanagerVaultName: create.name,\n };\n}\n\n/**\n * Build the CreateSecretManagerSecret request for a planned secret create.\n * @param create - Planned secret create\n * @returns Request init shape\n */\nexport function secretCreateRequest(\n create: CreateSecret,\n): MessageInitShape<typeof CreateSecretManagerSecretRequestSchema> {\n return {\n workspaceId: create.workspaceId,\n secretmanagerVaultName: create.vaultName,\n secretmanagerSecretName: create.secretName,\n secretmanagerSecretValue: create.value,\n };\n}\n\n/**\n * Build the UpdateSecretManagerSecret request for a planned secret update.\n * @param update - Planned secret update\n * @returns Request init shape\n */\nexport function secretUpdateRequest(\n update: UpdateSecret,\n): MessageInitShape<typeof UpdateSecretManagerSecretRequestSchema> {\n return {\n workspaceId: update.workspaceId,\n secretmanagerVaultName: update.vaultName,\n secretmanagerSecretName: update.secretName,\n secretmanagerSecretValue: update.value,\n };\n}\n\n/**\n * Plan secret manager changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes for vaults and secrets\n */\nexport async function planSecretManager(context: PlanContext) {\n const { client, workspaceId, application, forRemoval, forceApplyAll = false } = context;\n const secretVaults = forRemoval ? [] : application.secrets;\n\n const vaultChangeSet = createChangeSet<CreateVault, ExistingVault, DeleteVault>(\n \"Secret Manager vaults\",\n );\n const secretChangeSet = createChangeSet<CreateSecret, UpdateSecret, DeleteSecret>(\n \"Secret Manager secrets\",\n );\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n // Fetch all existing vaults with metadata to track managed resources\n const existingVaults = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, maxPageSize) => {\n const { vaults, nextPageToken } = await client.listSecretManagerVaults({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [vaults, nextPageToken];\n },\n getName: (resource) => resource.name,\n getTrn: (name) => resourceTrn(workspaceId, \"vault\", name),\n });\n\n const stateScope = {\n workspaceId,\n applicationId: application.id,\n applicationName: application.name,\n };\n const state = loadSecretsState(stateScope);\n const skippedSecrets: string[] = [];\n\n await Promise.all(\n secretVaults.map(async (vault) => {\n const vaultName = vault.vaultName;\n const existing = existingVaults[vaultName];\n\n if (existing) {\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"vault\", vaultName),\n appName: application.name,\n appId: application.id,\n });\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName: application.name,\n appId: application.id,\n resourceType: \"Secret Manager vault\",\n resourceName: vaultName,\n conflicts,\n unmanaged,\n });\n if (owned && hasMatchingSdkVersion(existing.allLabels, metaRequest.labels)) {\n vaultChangeSet.unchanged.push({ name: vaultName });\n } else {\n vaultChangeSet.updates.push({\n name: vaultName,\n workspaceId,\n });\n }\n delete existingVaults[vaultName];\n } else {\n vaultChangeSet.creates.push({\n name: vaultName,\n workspaceId,\n });\n }\n\n // Fetch existing secrets in this vault\n const existingSecretTimes = new Map<string, string | undefined>();\n if (existing) {\n const secrets = await fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { secrets, nextPageToken } = await client.listSecretManagerSecrets({\n workspaceId,\n secretmanagerVaultName: vaultName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [secrets, nextPageToken];\n });\n for (const secret of secrets) {\n existingSecretTimes.set(secret.name, serializeUpdateTime(secret.updateTime));\n }\n }\n\n const existingSet = new Set(existingSecretTimes.keys());\n\n // Diff secrets\n for (const secret of vault.secrets) {\n if (secret.value == null) {\n // Nullish value: skip create/update/delete for this secret\n existingSet.delete(secret.name);\n skippedSecrets.push(`${vaultName}/${secret.name}`);\n continue;\n }\n\n if (existingSet.has(secret.name)) {\n const stored = state.vaults[vaultName]?.[secret.name];\n const remoteUpdateTime = existingSecretTimes.get(secret.name);\n // Skip only when the stored hash matches and the remote updateTime\n // proves no other writer changed the secret since that hash was saved.\n const unchanged =\n stored !== undefined &&\n stored.hash === hashValue(secret.value) &&\n stored.updateTime !== undefined &&\n stored.updateTime === remoteUpdateTime;\n if (forceApplyAll || !unchanged) {\n secretChangeSet.updates.push({\n name: `${vaultName}/${secret.name}`,\n secretName: secret.name,\n workspaceId,\n vaultName,\n value: secret.value,\n });\n }\n existingSet.delete(secret.name);\n } else {\n secretChangeSet.creates.push({\n name: `${vaultName}/${secret.name}`,\n secretName: secret.name,\n workspaceId,\n vaultName,\n value: secret.value,\n });\n }\n }\n\n // Remaining in existingSet are orphans - mark for deletion\n for (const orphanName of existingSet) {\n secretChangeSet.deletes.push({\n name: `${vaultName}/${orphanName}`,\n secretName: orphanName,\n workspaceId,\n vaultName,\n });\n }\n }),\n );\n\n // Remaining existing vaults not in config - mark managed ones for deletion\n for (const [name, entry] of Object.entries(existingVaults)) {\n if (!entry) continue;\n const owned = trackRemainingResourceOwner({\n labels: entry.allLabels,\n ownerLabel: entry.label,\n appName: application.name,\n appId: application.id,\n resourceOwners,\n });\n if (owned) {\n // Delete secrets inside the vault before deleting the vault itself\n const secrets = await fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { secrets, nextPageToken } = await client.listSecretManagerSecrets({\n workspaceId,\n secretmanagerVaultName: name,\n pageToken,\n pageSize: maxPageSize,\n });\n return [secrets, nextPageToken];\n });\n for (const secret of secrets) {\n secretChangeSet.deletes.push({\n name: `${name}/${secret.name}`,\n secretName: secret.name,\n workspaceId,\n vaultName: name,\n });\n }\n\n vaultChangeSet.deletes.push({\n name,\n workspaceId,\n });\n }\n }\n\n return {\n vaultChangeSet,\n secretChangeSet,\n skippedSecrets,\n conflicts,\n unmanaged,\n resourceOwners,\n stateScope,\n };\n}\n\n/**\n * Apply secret manager changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned secret changes\n * @param phase - Apply phase\n * @param application - Application used for ownership metadata and hash state persistence\n * @returns Promise that resolves when secret changes are applied\n */\nexport async function applySecretManager(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planSecretManager>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n application?: Readonly<Application>,\n) {\n const { vaultChangeSet, secretChangeSet, stateScope } = result;\n\n if (phase === \"create-update\") {\n // Create vaults first and set metadata\n await Promise.all(\n vaultChangeSet.creates.map(async (create) => {\n await client.createSecretManagerVault(vaultCreateRequest(create));\n if (application) {\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(create.workspaceId, \"vault\", create.name),\n appName: application.name,\n appId: application.id,\n });\n await writeMetadataLabels(client, metaRequest);\n }\n }),\n );\n\n // Update metadata for existing vaults\n if (application) {\n await Promise.all(\n vaultChangeSet.updates.map(async (update) => {\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(update.workspaceId, \"vault\", update.name),\n appName: application.name,\n appId: application.id,\n });\n await writeMetadataLabels(client, metaRequest);\n }),\n );\n }\n\n const secretHashUpdates = [...secretChangeSet.creates, ...secretChangeSet.updates];\n if (secretHashUpdates.length > 0) {\n await withSecretsStateLock(stateScope, async () => {\n // Evidence must come from this deploy's own mutation responses; pairing\n // the hash with a re-listed timestamp could adopt another writer's.\n const appliedUpdateTimes = new Map<string, string | undefined>();\n\n // Create new secrets\n await Promise.all(\n secretChangeSet.creates.map(async (create) => {\n const response = await client.createSecretManagerSecret(secretCreateRequest(create));\n appliedUpdateTimes.set(create.name, serializeUpdateTime(response.secret?.updateTime));\n }),\n );\n\n // Update existing secrets\n await Promise.all(\n secretChangeSet.updates.map(async (update) => {\n const response = await client.updateSecretManagerSecret(secretUpdateRequest(update));\n appliedUpdateTimes.set(update.name, serializeUpdateTime(response.secret?.updateTime));\n }),\n );\n\n if (application) {\n const state = loadSecretsState(stateScope);\n for (const secret of secretHashUpdates) {\n if (!Object.hasOwn(state.vaults, secret.vaultName)) {\n state.vaults[secret.vaultName] = {};\n }\n const updateTime = appliedUpdateTimes.get(secret.name);\n assertDefined(state.vaults[secret.vaultName], \"vault state entry missing\")[\n secret.secretName\n ] = {\n hash: hashValue(secret.value),\n ...(updateTime === undefined ? {} : { updateTime }),\n };\n }\n saveSecretsState(stateScope, state);\n }\n });\n }\n } else if (secretChangeSet.deletes.length > 0 || vaultChangeSet.deletes.length > 0) {\n await withSecretsStateLock(stateScope, async () => {\n // Delete orphan secrets\n await Promise.all(\n secretChangeSet.deletes.map((del) =>\n client.deleteSecretManagerSecret({\n workspaceId: del.workspaceId,\n secretmanagerVaultName: del.vaultName,\n secretmanagerSecretName: del.secretName,\n }),\n ),\n );\n\n // Delete orphan vaults\n await Promise.all(\n vaultChangeSet.deletes.map((del) =>\n client.deleteSecretManagerVault({\n workspaceId: del.workspaceId,\n secretmanagerVaultName: del.name,\n }),\n ),\n );\n\n // Remove deleted secrets and vaults from hash state\n const state = loadSecretsState(stateScope);\n for (const del of secretChangeSet.deletes) {\n if (Object.hasOwn(state.vaults, del.vaultName)) {\n delete assertDefined(state.vaults[del.vaultName], \"vault state entry missing\")[\n del.secretName\n ];\n if (\n Object.keys(assertDefined(state.vaults[del.vaultName], \"vault state entry missing\"))\n .length === 0\n ) {\n delete state.vaults[del.vaultName];\n }\n }\n }\n for (const del of vaultChangeSet.deletes) {\n delete state.vaults[del.name];\n }\n saveSecretsState(stateScope, state);\n });\n }\n}\n","/**\n * Migration configuration utilities\n */\n\nimport * as path from \"pathe\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type { AppConfig } from \"#/configure/config/types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Namespace with migrations configuration\n */\nexport interface NamespaceWithMigrations {\n namespace: string;\n migrationsDir: string;\n}\n\n// ============================================================================\n// Config Helpers\n// ============================================================================\n\nfunction hasMigrationConfig(dbConfig: unknown): dbConfig is { migration: { directory: string } } {\n if (typeof dbConfig !== \"object\" || dbConfig === null) return false;\n if (!(\"migration\" in dbConfig)) return false;\n\n const migration = (dbConfig as { migration: unknown }).migration;\n if (typeof migration !== \"object\" || migration === null) return false;\n if (!(\"directory\" in migration)) return false;\n\n return typeof (migration as { directory: unknown }).directory === \"string\";\n}\n\n/**\n * Get namespaces that have migrations configured\n * @param {AppConfig} config - Application configuration\n * @param {string} configDir - Configuration directory path\n * @returns {NamespaceWithMigrations[]} Array of namespaces with migrations configured\n */\nexport function getNamespacesWithMigrations(\n config: AppConfig,\n configDir: string,\n): NamespaceWithMigrations[] {\n const result: NamespaceWithMigrations[] = [];\n\n for (const namespace of Object.keys(config.db ?? {})) {\n const dbConfig = config.db?.[namespace];\n if (!hasMigrationConfig(dbConfig)) continue;\n\n const migrationsDir = path.resolve(configDir, dbConfig.migration.directory);\n result.push({ namespace, migrationsDir });\n }\n\n return result;\n}\n\n/**\n * Select the single target namespace for a migration command\n * @param {NamespaceWithMigrations[]} namespacesWithMigrations - Namespaces with migrations configured\n * @param {string | undefined} requested - Namespace requested via --namespace, if any\n * @returns {NamespaceWithMigrations} The selected namespace\n */\nexport function selectTargetNamespace(\n namespacesWithMigrations: NamespaceWithMigrations[],\n requested: string | undefined,\n): NamespaceWithMigrations {\n if (namespacesWithMigrations.length === 0) {\n throw new Error(\"No TailorDB services with migrations configuration found\");\n }\n if (requested) {\n const found = namespacesWithMigrations.find((ns) => ns.namespace === requested);\n if (!found) {\n throw new Error(`Namespace \"${requested}\" not found or does not have migrations configured`);\n }\n return found;\n }\n if (namespacesWithMigrations.length > 1) {\n throw new Error(\n `Multiple TailorDB services found. Please specify namespace with --namespace flag: ${namespacesWithMigrations\n .map((ns) => ns.namespace)\n .join(\", \")}`,\n );\n }\n return assertDefined(namespacesWithMigrations[0], \"namespace with migrations missing\");\n}\n","import { createHash } from \"node:crypto\";\n\n// Platform-injected record map for type-level hook/validate scripts.\nconst INPUT = \"_input\";\nconst NEW_RECORD = \"_newRecord\";\nconst OLD_RECORD = \"_oldRecord\";\n// Shared operation timestamp bound once per script execution.\nconst NOW = \"_now\";\n\nconst SOURCE_HASH_PREFIX = \"// @sdk-source-hash:\";\n\nconst TIME_TYPES = new Set([\"datetime\", \"date\", \"time\"]);\n\ntype HookOperation = \"create\" | \"update\";\n\ninterface ScriptRef {\n expr: string;\n}\n\n/**\n * Minimal structural shape shared by parser `OperatorFieldConfig` and migration\n * `SnapshotFieldConfig`. Only the parts needed to aggregate type-level scripts.\n */\nexport interface ScriptFieldConfig {\n type: string;\n array?: boolean;\n hooks?: {\n create?: ScriptRef;\n update?: ScriptRef;\n };\n validate?: { script?: ScriptRef; errorMessage: string }[];\n default?: unknown;\n fields?: Record<string, ScriptFieldConfig>;\n}\n\nexport interface TypeScripts {\n typeHook?: { create?: ScriptRef; update?: ScriptRef };\n typeValidate?: { create?: ScriptRef; update?: ScriptRef };\n}\n\nconst key = (name: string) => JSON.stringify(name);\n\nfunction collectFieldScriptSources(fields: Record<string, ScriptFieldConfig>): [string, unknown][] {\n const entries: [string, unknown][] = [];\n\n for (const [name, config] of Object.entries(fields).toSorted(([a], [b]) => a.localeCompare(b))) {\n const data: Record<string, unknown> = {};\n\n if (config.hooks?.create?.expr) data.hc = config.hooks.create.expr;\n if (config.hooks?.update?.expr) data.hu = config.hooks.update.expr;\n if (config.validate?.some((v) => v.script?.expr)) {\n data.v = config.validate\n .filter((v) => v.script?.expr)\n .map((v) => [v.script?.expr, v.errorMessage]);\n }\n if (config.default !== undefined) {\n data.d = config.default instanceof Date ? config.default.toISOString() : config.default;\n data.t = config.type;\n }\n\n if (config.fields) {\n const nested = collectFieldScriptSources(config.fields);\n if (nested.length > 0) {\n data.f = nested;\n data.a = !!config.array;\n }\n }\n\n if (Object.keys(data).length > 0) {\n entries.push([name, data]);\n }\n }\n\n return entries;\n}\n\nexport function computeSourceScriptHash(\n fields: Record<string, ScriptFieldConfig>,\n options?: {\n typeHookExpr?: { create?: string; update?: string };\n typeValidateExpr?: string;\n },\n): string | undefined {\n const fieldSources = collectFieldScriptSources(fields);\n const hasTypeScripts =\n fieldSources.length > 0 ||\n options?.typeHookExpr?.create ||\n options?.typeHookExpr?.update ||\n options?.typeValidateExpr;\n\n if (!hasTypeScripts) return undefined;\n\n const payload: unknown[] = [fieldSources];\n if (options?.typeHookExpr?.create) payload.push([\"thc\", options.typeHookExpr.create]);\n if (options?.typeHookExpr?.update) payload.push([\"thu\", options.typeHookExpr.update]);\n if (options?.typeValidateExpr) payload.push([\"tve\", options.typeValidateExpr]);\n\n return createHash(\"sha256\").update(JSON.stringify(payload)).digest(\"hex\").slice(0, 16);\n}\n\nexport function extractSourceScriptHash(expr: string): string | undefined {\n const match = expr.match(/\\/\\/ @sdk-source-hash:([0-9a-f]+)\\s*$/);\n return match?.[1];\n}\n\nconst isNestedType = (config: ScriptFieldConfig): boolean =>\n config.type === \"nested\" && config.fields !== undefined;\n\nfunction serializeDefault(value: unknown, fieldType: string): string {\n if (value === \"now\" && TIME_TYPES.has(fieldType)) return NOW;\n if (value instanceof Date) return `new Date(${JSON.stringify(value.toISOString())})`;\n return JSON.stringify(value);\n}\n\n/**\n * Build the object literal that reconstructs one record level with hook\n * overrides and defaults applied. For create, defaults are appended as\n * `?? defaultValue` after the hook expression (field hook → default).\n * Returns null when no field under this level has a hook or default for\n * the operation.\n * @param {Record<string, ScriptFieldConfig>} fields - Field configurations\n * @param {string} accessExpr - JS expression to access the parent object\n * @param {string} oldAccessExpr - JS expression to access the old record parent\n * @param {HookOperation} operation - Hook operation type\n * @param {boolean} nested - Whether building inside a nested field (rejects defaults)\n * @returns {string | null} Object literal expression or null\n */\nfunction buildHookObject(\n fields: Record<string, ScriptFieldConfig>,\n accessExpr: string,\n oldAccessExpr: string,\n operation: HookOperation,\n nested = false,\n): string | null {\n const parts: string[] = [];\n\n for (const [name, config] of Object.entries(fields)) {\n const access = `${accessExpr}[${key(name)}]`;\n const oldAccess = `${oldAccessExpr}?.[${key(name)}]`;\n if (isNestedType(config) && config.fields) {\n if (config.array) {\n const inner = buildHookObject(config.fields, \"__el\", \"undefined\", operation, true);\n if (inner !== null) {\n parts.push(\n `${key(name)}: (${access} || []).map((__el) => Object.assign({}, __el, ${inner}))`,\n );\n }\n } else {\n const inner = buildHookObject(\n config.fields,\n `(${access} || {})`,\n oldAccess,\n operation,\n true,\n );\n if (inner !== null) {\n parts.push(`${key(name)}: Object.assign({}, ${access}, ${inner})`);\n }\n }\n continue;\n }\n\n const hook = config.hooks?.[operation];\n if (nested && config.default !== undefined) {\n throw new Error(`.default() cannot be used on nested inner field \"${name}\"`);\n }\n const hasDefault = operation === \"create\" && config.default !== undefined;\n\n if (hook && hasDefault) {\n parts.push(\n `${key(name)}: ((_value) => (${hook.expr}))(${access}) ?? ${serializeDefault(config.default, config.type)}`,\n );\n } else if (hook && operation === \"create\") {\n parts.push(`${key(name)}: ((_value) => (${hook.expr}))(${access})`);\n } else if (hook) {\n parts.push(\n `${key(name)}: ((_value, _oldValue) => (${hook.expr}))(${access}, ${oldAccess} ?? null)`,\n );\n } else if (hasDefault) {\n parts.push(`${key(name)}: ${access} ?? ${serializeDefault(config.default, config.type)}`);\n }\n }\n\n if (parts.length === 0) return null;\n return `{ ${parts.join(\", \")} }`;\n}\n\n/**\n * Build validation statements for one record level.\n * Each leaf field with validators contributes a block that runs every\n * validator and records all failing messages keyed by dotted field path.\n * @param {Record<string, ScriptFieldConfig>} fields - Field configurations\n * @param {string} accessExpr - JS expression to access the parent object\n * @param {string} keyPrefix - Dotted path prefix for error keys\n * @returns {string[]} Array of validation statement strings\n */\nfunction buildValidateStatements(\n fields: Record<string, ScriptFieldConfig>,\n accessExpr: string,\n keyPrefix: string,\n): string[] {\n const statements: string[] = [];\n\n for (const [name, config] of Object.entries(fields)) {\n const access = `${accessExpr}[${key(name)}]`;\n const fieldPath = keyPrefix ? `${keyPrefix}.${name}` : name;\n\n const validators = (config.validate ?? []).filter((v) => v.script?.expr);\n if (validators.length > 0) {\n const checks = validators\n .map(\n (v) =>\n `{ const __r = (${v.script?.expr}); if (typeof __r === \"string\") { __errs[${key(fieldPath)}] = __r; } }`,\n )\n .join(\"\\n\");\n statements.push(`{ const _value = ${access};\\n${checks}\\n}`);\n }\n\n if (isNestedType(config) && config.fields) {\n if (config.array) {\n const innerParts: string[] = [];\n for (const [innerName, innerConfig] of Object.entries(config.fields)) {\n const innerValidators = (innerConfig.validate ?? []).filter((v) => v.script?.expr);\n if (innerValidators.length > 0) {\n const errorKeyExpr = `${JSON.stringify(fieldPath + \"[\")} + __idx + ${JSON.stringify(\"].\" + innerName)}`;\n const checks = innerValidators\n .map(\n (v) =>\n `{ const __r = (${v.script?.expr}); if (typeof __r === \"string\") { __errs[${errorKeyExpr}] = __r; } }`,\n )\n .join(\"\\n\");\n innerParts.push(`{ const _value = __el[${key(innerName)}];\\n${checks}\\n}`);\n }\n }\n if (innerParts.length > 0) {\n statements.push(\n `(${access} || []).forEach((__el, __idx) => {\\n${innerParts.join(\"\\n\")}\\n});`,\n );\n }\n } else {\n const nested = buildValidateStatements(config.fields, access, fieldPath);\n if (nested.length > 0) {\n statements.push(`if (${access} != null) {\\n${nested.join(\"\\n\")}\\n}`);\n }\n }\n }\n }\n\n return statements;\n}\n\nfunction wrapHook(objectExpr: string): string {\n return `((_invoker) => { const ${NOW} = new Date(); return ${objectExpr}; })(typeof _invoker !== \"undefined\" ? _invoker : undefined)`;\n}\n\nfunction wrapValidate(statements: string[], typeValidateExpr?: string): string {\n const issuesFn = typeValidateExpr ? \" const __issues = (f, m) => { __errs[f] = m; };\" : \"\";\n const typeValidateStmt = typeValidateExpr ? ` ${typeValidateExpr};` : \"\";\n return `((_invoker) => { const __errs = {};${issuesFn}\\n${statements.join(\"\\n\")}${typeValidateStmt}\\nreturn __errs; })(typeof _invoker !== \"undefined\" ? _invoker : undefined)`;\n}\n\n/**\n * Aggregate every field's create/update hook, default, and validate into\n * type-level scripts. Hooks compute a single shared timestamp (`now`) per\n * operation, so all fields touched in one create/update observe the same\n * instant. Defaults are applied after hooks on create only. Validators\n * run with the same rules on create and update.\n * @param fields - Per-field script configuration\n * @param options - Optional type-level hook/validate expressions\n * @returns Aggregated type-level scripts\n */\nexport function buildTypeScripts(\n fields: Record<string, ScriptFieldConfig>,\n options?: {\n typeHookExpr?: { create?: string; update?: string };\n typeValidateExpr?: string;\n },\n): TypeScripts {\n const result: TypeScripts = {};\n const typeHookExpr = options?.typeHookExpr;\n const typeValidateExpr = options?.typeValidateExpr;\n\n const hash = computeSourceScriptHash(fields, options);\n const hashSuffix = hash ? ` ${SOURCE_HASH_PREFIX}${hash}` : \"\";\n\n const hook: { create?: ScriptRef; update?: ScriptRef } = {};\n for (const operation of [\"create\", \"update\"] as const) {\n const perFieldExpr = buildHookObject(fields, INPUT, OLD_RECORD, operation);\n const typeLevelExpr = typeHookExpr?.[operation];\n let expr: string | undefined;\n if (perFieldExpr !== null && typeLevelExpr) {\n expr = `((_invoker) => { const ${NOW} = new Date(); const __fl = ${perFieldExpr}; return Object.assign({}, __fl, ((${INPUT}) => ${typeLevelExpr})(Object.assign({}, ${INPUT}, __fl))); })(typeof _invoker !== \"undefined\" ? _invoker : undefined)`;\n } else if (typeLevelExpr) {\n expr = wrapHook(typeLevelExpr);\n } else if (perFieldExpr !== null) {\n expr = wrapHook(perFieldExpr);\n }\n\n if (expr) {\n hook[operation] = { expr: expr + hashSuffix };\n }\n }\n if (hook.create || hook.update) {\n result.typeHook = hook;\n }\n\n const statements = buildValidateStatements(fields, NEW_RECORD, \"\");\n if (statements.length > 0 || typeValidateExpr) {\n const expr = wrapValidate(statements, typeValidateExpr) + hashSuffix;\n result.typeValidate = { create: { expr }, update: { expr } };\n }\n\n return result;\n}\n","/**\n * Diff calculator and formatter for TailorDB schema migrations\n *\n * This module provides utilities for formatting and displaying migration diffs.\n * The actual diff calculation is performed by snapshot.ts.\n */\n\nimport type {\n SnapshotFieldConfig,\n SnapshotGqlPermission,\n SnapshotIndexConfig,\n SnapshotRecordPermission,\n SnapshotRelationship,\n TailorDBSnapshotType,\n} from \"./snapshot-types\";\n\n// ============================================================================\n// Diff Types\n// ============================================================================\n\n/**\n * Current schema snapshot format version\n */\nexport const SCHEMA_SNAPSHOT_VERSION = 2 as const;\n\n/** Oldest migration file format this SDK can replay. */\nexport const MIN_SUPPORTED_MIGRATION_FILE_VERSION = 1 as const;\n\n/**\n * Change kind in migration diff\n */\nexport type DiffChangeKind = DiffChange[\"kind\"];\n\n/**\n * Properties shared by all diff change variants\n */\ninterface DiffChangeBase {\n typeName: string;\n reason?: string;\n}\n\n/**\n * Type-level settings patch carried by legacy `type_modified` changes.\n * Current SDK versions no longer produce this kind, but persisted\n * diff.json files written by older versions may still contain it.\n */\nexport interface TypeSettingsPatch {\n indexes?: Record<string, SnapshotIndexConfig>;\n files?: Record<string, string>;\n}\n\n/** Type-level settings and metadata state used by current diffs. */\nexport interface SnapshotTypeSettingsState {\n description?: string;\n pluralForm: string;\n settings?: TailorDBSnapshotType[\"settings\"];\n}\n\n/**\n * Permission state carried by `permission_modified` changes.\n */\nexport interface SnapshotPermissionState {\n recordPermission?: SnapshotRecordPermission;\n gqlPermission?: SnapshotGqlPermission;\n}\n\n/** A new type was added to the schema. */\nexport interface TypeAddedChange extends DiffChangeBase {\n kind: \"type_added\";\n after: TailorDBSnapshotType;\n}\n\n/** An existing type was removed from the schema. */\nexport interface TypeRemovedChange extends DiffChangeBase {\n kind: \"type_removed\";\n before: TailorDBSnapshotType;\n}\n\n/**\n * Legacy type-level settings change. Kept for backward compatibility with\n * diff.json files written by older SDK versions; `before`/`after` may be\n * absent in those files, hence optional.\n */\nexport interface TypeModifiedChange extends DiffChangeBase {\n kind: \"type_modified\";\n before?: TypeSettingsPatch;\n after?: TypeSettingsPatch;\n}\n\n/** Type-level settings or metadata changed. */\nexport interface TypeSettingsModifiedChange extends DiffChangeBase {\n kind: \"type_settings_modified\";\n before: SnapshotTypeSettingsState;\n after: SnapshotTypeSettingsState;\n}\n\n/** A field was added to a type. */\nexport interface FieldAddedChange extends DiffChangeBase {\n kind: \"field_added\";\n fieldName: string;\n after: SnapshotFieldConfig;\n}\n\n/** A field was removed from a type. */\nexport interface FieldRemovedChange extends DiffChangeBase {\n kind: \"field_removed\";\n fieldName: string;\n before: SnapshotFieldConfig;\n}\n\n/** A field configuration was modified. */\nexport interface FieldModifiedChange extends DiffChangeBase {\n kind: \"field_modified\";\n fieldName: string;\n before: SnapshotFieldConfig;\n after: SnapshotFieldConfig;\n}\n\n/** A field type changed and must remain on the previous type until Post-phase. */\nexport interface FieldTypeModifiedChange extends DiffChangeBase {\n kind: \"field_type_modified\";\n fieldName: string;\n before: SnapshotFieldConfig;\n after: SnapshotFieldConfig;\n}\n\n/** An index was added to a type. */\nexport interface IndexAddedChange extends DiffChangeBase {\n kind: \"index_added\";\n indexName: string;\n after: SnapshotIndexConfig;\n}\n\n/** An index was removed from a type. */\nexport interface IndexRemovedChange extends DiffChangeBase {\n kind: \"index_removed\";\n indexName: string;\n before: SnapshotIndexConfig;\n}\n\n/** An index configuration was modified. */\nexport interface IndexModifiedChange extends DiffChangeBase {\n kind: \"index_modified\";\n indexName: string;\n before: SnapshotIndexConfig;\n after: SnapshotIndexConfig;\n}\n\n/** A file field was added to a type. `before`/`after` hold the description. */\nexport interface FileAddedChange extends DiffChangeBase {\n kind: \"file_added\";\n fieldName: string;\n after: string;\n}\n\n/** A file field was removed from a type. */\nexport interface FileRemovedChange extends DiffChangeBase {\n kind: \"file_removed\";\n fieldName: string;\n before: string;\n}\n\n/** A file field description was modified. */\nexport interface FileModifiedChange extends DiffChangeBase {\n kind: \"file_modified\";\n fieldName: string;\n before: string;\n after: string;\n}\n\n/**\n * A relationship was added to a type. `relationshipType` is optional for\n * backward compatibility: diff.json files written by older SDK versions\n * predate the field.\n */\nexport interface RelationshipAddedChange extends DiffChangeBase {\n kind: \"relationship_added\";\n relationshipName: string;\n relationshipType?: \"forward\" | \"backward\";\n after: SnapshotRelationship;\n}\n\n/** A relationship was removed from a type. */\nexport interface RelationshipRemovedChange extends DiffChangeBase {\n kind: \"relationship_removed\";\n relationshipName: string;\n relationshipType?: \"forward\" | \"backward\";\n before: SnapshotRelationship;\n}\n\n/** A relationship configuration was modified. */\nexport interface RelationshipModifiedChange extends DiffChangeBase {\n kind: \"relationship_modified\";\n relationshipName: string;\n relationshipType?: \"forward\" | \"backward\";\n before: SnapshotRelationship;\n after: SnapshotRelationship;\n}\n\n/**\n * Type-level permissions were modified. `before`/`after` are optional for\n * robustness against hand-edited or legacy diff.json files; consumers guard\n * on their presence.\n */\nexport interface PermissionModifiedChange extends DiffChangeBase {\n kind: \"permission_modified\";\n before?: SnapshotPermissionState;\n after?: SnapshotPermissionState;\n}\n\n/** Type-level hook/validate script state for diff tracking. */\nexport interface TypeScriptsState {\n typeHookExpr?: { create?: string; update?: string };\n typeValidateExpr?: string;\n}\n\n/** Type-level hook/validate scripts changed. */\nexport interface TypeScriptsModifiedChange extends DiffChangeBase {\n kind: \"type_scripts_modified\";\n before: TypeScriptsState;\n after: TypeScriptsState;\n}\n\n/**\n * Single change in migration diff, discriminated by `kind` so that\n * `before`/`after` are typed per change kind.\n */\nexport type DiffChange =\n | TypeAddedChange\n | TypeRemovedChange\n | TypeModifiedChange\n | TypeSettingsModifiedChange\n | FieldAddedChange\n | FieldRemovedChange\n | FieldModifiedChange\n | FieldTypeModifiedChange\n | IndexAddedChange\n | IndexRemovedChange\n | IndexModifiedChange\n | FileAddedChange\n | FileRemovedChange\n | FileModifiedChange\n | RelationshipAddedChange\n | RelationshipRemovedChange\n | RelationshipModifiedChange\n | PermissionModifiedChange\n | TypeScriptsModifiedChange;\n\n/**\n * Field-level diff change (added / removed / modified).\n */\nexport type FieldDiffChange =\n | FieldAddedChange\n | FieldRemovedChange\n | FieldModifiedChange\n | FieldTypeModifiedChange;\n\n/**\n * Index-level diff change (added / removed / modified).\n */\nexport type IndexDiffChange = IndexAddedChange | IndexRemovedChange | IndexModifiedChange;\n\n/**\n * Migration diff - changes between two schema versions\n * Stored as XXXX/diff.json (e.g., 0001/diff.json)\n */\nexport interface MigrationDiff {\n /** Format version for future compatibility */\n version: number;\n namespace: string;\n createdAt: string;\n description?: string;\n changes: DiffChange[];\n /** Whether there are breaking changes (data loss or constraint violations possible) */\n hasBreakingChanges: boolean;\n /** List of breaking changes */\n breakingChanges: BreakingChangeInfo[];\n /** Whether there are non-breaking changes that may cause data loss (e.g. field/type removal) */\n hasWarnings: boolean;\n /** List of non-breaking warnings */\n warnings: WarningChangeInfo[];\n /** Whether a migration script is required to handle data migration */\n requiresMigrationScript: boolean;\n /** Explicit acknowledgment that this migration needs no script despite breaking changes or data-loss warnings */\n scriptSkipped?: ScriptSkippedInfo;\n}\n\n/**\n * Acknowledgment that a migration requiring or recommending a script intentionally has none.\n * Recorded by `tailordb migration script <n> --no-script --reason \"...\"`.\n */\nexport interface ScriptSkippedInfo {\n reason: string;\n acknowledgedAt: string;\n}\n\n/**\n * Breaking change information in migration diff\n */\nexport interface BreakingChangeInfo {\n typeName: string;\n fieldName?: string;\n reason: string;\n /** If true, this change is not supported and migration generation will fail */\n unsupported?: boolean;\n /** If true, show 3-step migration instructions for this unsupported change */\n showThreeStepHint?: boolean;\n}\n\n/**\n * Warning change information in migration diff.\n *\n * Warnings are non-breaking changes that may still cause data loss\n * (e.g. removing a field or type). Unlike breaking changes, a migration\n * script is not required, but writing one is recommended if you need to\n * preserve or transform data before the change applies.\n */\nexport interface WarningChangeInfo {\n typeName: string;\n fieldName?: string;\n reason: string;\n}\n\n/**\n * Check if a migration diff has any changes\n * @param {MigrationDiff} diff - Migration diff to check\n * @returns {boolean} True if diff has changes\n */\nexport function hasChanges(diff: MigrationDiff): boolean {\n return diff.changes.length > 0;\n}\n\n/**\n * Format a migration diff for display\n * @param {MigrationDiff} diff - Migration diff to format\n * @returns {string} Formatted diff string\n */\nexport function formatMigrationDiff(diff: MigrationDiff): string {\n if (diff.changes.length === 0) {\n return \"No schema differences detected.\";\n }\n\n const lines: string[] = [];\n\n // Group changes by type name\n const changesByType = new Map<string, DiffChange[]>();\n for (const change of diff.changes) {\n const existing = changesByType.get(change.typeName) ?? [];\n existing.push(change);\n changesByType.set(change.typeName, existing);\n }\n\n for (const [typeName, changes] of changesByType) {\n lines.push(`${diff.namespace}.${typeName}:`);\n\n for (const change of changes) {\n lines.push(formatDiffChange(change));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a single diff change for display\n * @param {DiffChange} change - Diff change to format\n * @returns {string} Formatted change string\n */\nfunction formatDiffChange(change: DiffChange): string {\n switch (change.kind) {\n case \"type_added\":\n return ` + [Type] ${change.typeName} (new type)`;\n case \"type_removed\":\n return ` - [Type] ${change.typeName} (removed)`;\n case \"type_modified\":\n return ` ~ [Type] ${change.typeName}: ${change.reason}`;\n case \"type_settings_modified\":\n return ` ~ [Type Settings] ${change.typeName}: ${change.reason ?? \"settings changed\"}`;\n case \"field_added\": {\n const typeStr = formatFieldType(change.after);\n return ` + ${change.fieldName}: ${typeStr}`;\n }\n case \"field_removed\":\n return ` - ${change.fieldName}: ${change.before.type}`;\n case \"field_modified\":\n case \"field_type_modified\":\n return ` ~ ${change.fieldName}: ${formatFieldModification(change.before, change.after)}`;\n case \"index_added\":\n return ` + [Index] ${change.indexName}`;\n case \"index_removed\":\n return ` - [Index] ${change.indexName}`;\n case \"index_modified\":\n return ` ~ [Index] ${change.indexName}: ${change.reason ?? \"modified\"}`;\n case \"file_added\":\n return ` + [File] ${change.fieldName}`;\n case \"file_removed\":\n return ` - [File] ${change.fieldName}`;\n case \"file_modified\":\n return ` ~ [File] ${change.fieldName}: ${change.reason ?? \"modified\"}`;\n case \"relationship_added\":\n return ` + [Relationship${change.relationshipType ? ` (${change.relationshipType})` : \"\"}] ${change.relationshipName}`;\n case \"relationship_removed\":\n return ` - [Relationship${change.relationshipType ? ` (${change.relationshipType})` : \"\"}] ${change.relationshipName}`;\n case \"relationship_modified\":\n return ` ~ [Relationship${change.relationshipType ? ` (${change.relationshipType})` : \"\"}] ${change.relationshipName}: ${change.reason ?? \"modified\"}`;\n case \"permission_modified\":\n return ` ~ [Permission] ${change.reason ?? \"modified\"}`;\n case \"type_scripts_modified\":\n return ` ~ [Type Scripts] ${change.typeName}: ${change.reason ?? \"type-level hooks/validate changed\"}`;\n default: {\n // Runtime fallback: diff.json is parsed without validation, so\n // hand-edited or future-version files may carry unknown kinds.\n const unknown = change as { typeName: string; fieldName?: string };\n return ` ? ${unknown.typeName}.${unknown.fieldName ?? \"\"}`;\n }\n }\n}\n\n/**\n * Format field type with attributes\n * @param {SnapshotFieldConfig} field - Field configuration\n * @returns {string} Formatted field type string\n */\nfunction formatFieldType(field: SnapshotFieldConfig): string {\n let type = field.type;\n if (field.array) type += \"[]\";\n if (field.required) type += \" (required)\";\n else type += \" (optional)\";\n return type;\n}\n\n/**\n * Format field modification details\n * @param {SnapshotFieldConfig} before - Before field configuration\n * @param {SnapshotFieldConfig} after - After field configuration\n * @returns {string} Formatted modification details\n */\nfunction formatFieldModification(before: SnapshotFieldConfig, after: SnapshotFieldConfig): string {\n const changes: string[] = [];\n\n if (before.type !== after.type) {\n changes.push(`type: ${before.type} → ${after.type}`);\n }\n if (before.required !== after.required) {\n changes.push(`required: ${before.required} → ${after.required}`);\n }\n if (Boolean(before.array) !== Boolean(after.array)) {\n changes.push(`array: ${before.array ?? false} → ${after.array ?? false}`);\n }\n if (Boolean(before.index) !== Boolean(after.index)) {\n changes.push(`index: ${before.index ?? false} → ${after.index ?? false}`);\n }\n if (Boolean(before.unique) !== Boolean(after.unique)) {\n changes.push(`unique: ${before.unique ?? false} → ${after.unique ?? false}`);\n }\n if (Boolean(before.vector) !== Boolean(after.vector)) {\n changes.push(`vector: ${before.vector ?? false} → ${after.vector ?? false}`);\n }\n\n const beforeAllowed = before.allowedValues ?? [];\n const afterAllowed = after.allowedValues ?? [];\n const afterSet = new Set(afterAllowed.map((v) => v.value));\n const hasAllowedValuesChange =\n beforeAllowed.length !== afterAllowed.length ||\n beforeAllowed.some((v) => !afterSet.has(v.value));\n if (hasAllowedValuesChange) {\n const beforeValues = beforeAllowed.map((v) => v.value).join(\", \");\n const afterValues = afterAllowed.map((v) => v.value).join(\", \");\n changes.push(`allowedValues: [${beforeValues}] → [${afterValues}]`);\n }\n\n const beforeHooks = before.hooks;\n const afterHooks = after.hooks;\n if (\n (beforeHooks?.create?.expr ?? \"\") !== (afterHooks?.create?.expr ?? \"\") ||\n (beforeHooks?.update?.expr ?? \"\") !== (afterHooks?.update?.expr ?? \"\")\n ) {\n changes.push(\"hooks modified\");\n }\n\n const beforeValidate = before.validate ?? [];\n const afterValidate = after.validate ?? [];\n if (beforeValidate.length !== afterValidate.length) {\n changes.push(`validations: ${beforeValidate.length} → ${afterValidate.length}`);\n }\n\n if (Boolean(before.serial) !== Boolean(after.serial)) {\n changes.push(\n `serial: ${before.serial ? \"enabled\" : \"disabled\"} → ${after.serial ? \"enabled\" : \"disabled\"}`,\n );\n }\n\n return changes.join(\", \");\n}\n\n/**\n * Format breaking changes for display\n * @param {BreakingChangeInfo[]} breakingChanges - Breaking changes to format\n * @returns {string} Formatted breaking changes string\n */\nexport function formatBreakingChanges(breakingChanges: BreakingChangeInfo[]): string {\n if (breakingChanges.length === 0) {\n return \"\";\n }\n\n const lines: string[] = [\"Breaking changes detected:\", \"\"];\n\n for (const bc of breakingChanges) {\n const location = bc.fieldName ? `${bc.typeName}.${bc.fieldName}` : bc.typeName;\n lines.push(` - ${location}: ${bc.reason}`);\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format warning changes for display\n * @param {WarningChangeInfo[]} warnings - Warning changes to format\n * @returns {string} Formatted warning changes string\n */\nexport function formatWarnings(warnings: WarningChangeInfo[]): string {\n if (warnings.length === 0) {\n return \"\";\n }\n\n const lines: string[] = [\"Warning: data loss possible:\", \"\"];\n\n for (const w of warnings) {\n const location = w.fieldName ? `${w.typeName}.${w.fieldName}` : w.typeName;\n lines.push(` - ${location}: ${w.reason}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nconst DIFF_CHANGE_LABELS: Record<DiffChangeKind, string> = {\n type_added: \"type(s) added\",\n type_removed: \"type(s) removed\",\n type_modified: \"type(s) modified\",\n type_settings_modified: \"type setting(s) modified\",\n field_added: \"field(s) added\",\n field_removed: \"field(s) removed\",\n field_modified: \"field(s) modified\",\n field_type_modified: \"field type(s) modified\",\n index_added: \"index(es) added\",\n index_removed: \"index(es) removed\",\n index_modified: \"index(es) modified\",\n file_added: \"file field(s) added\",\n file_removed: \"file field(s) removed\",\n file_modified: \"file field(s) modified\",\n relationship_added: \"relationship(s) added\",\n relationship_removed: \"relationship(s) removed\",\n relationship_modified: \"relationship(s) modified\",\n permission_modified: \"permission(s) modified\",\n type_scripts_modified: \"type script(s) modified\",\n};\n\n/**\n * Format a summary of the migration diff\n * @param {MigrationDiff} diff - Migration diff to summarize\n * @returns {string} Formatted summary string\n */\nexport function formatDiffSummary(diff: MigrationDiff): string {\n const stats: Partial<Record<DiffChangeKind, number>> = {};\n for (const change of diff.changes) {\n stats[change.kind] = (stats[change.kind] ?? 0) + 1;\n }\n\n const parts = Object.keys(stats).map(\n (kind) => `${stats[kind as DiffChangeKind]} ${DIFF_CHANGE_LABELS[kind as DiffChangeKind]}`,\n );\n\n return parts.length > 0 ? parts.join(\", \") : \"No changes\";\n}\n","import type { SnapshotFieldConfig } from \"./snapshot-types\";\n\n/**\n * Scalar type changes whose complete source domain is accepted by the target\n * representation without relying on per-row index recreation.\n *\n * Keep this list deliberately narrow. Pair-specific platform experiments can\n * extend it once both indexed and unindexed read paths have been verified.\n */\nconst IN_PLACE_TYPE_CHANGES = new Set([\n \"decimal:string\",\n \"enum:string\",\n \"integer:float\",\n \"uuid:string\",\n]);\n\n/**\n * Determine whether a field type change can use a single phased migration.\n * @param before - Previous field configuration\n * @param after - Target field configuration\n * @returns Whether the migration can normalize data before applying the type\n */\nexport function supportsInPlaceFieldTypeChange(\n before: SnapshotFieldConfig,\n after: SnapshotFieldConfig,\n): boolean {\n if (before.type === after.type) return false;\n if (before.array || after.array) return false;\n if (before.type === \"nested\" || after.type === \"nested\") return false;\n if (before.serial || after.serial) return false;\n if (before.vector || after.vector) return false;\n if (before.foreignKey || after.foreignKey) return false;\n\n return IN_PLACE_TYPE_CHANGES.has(`${before.type}:${after.type}`);\n}\n","/**\n * Types for TailorDB migration execution\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { formatMigrationNumber } from \"./migration-number\";\nimport type { MigrationDiff } from \"./diff-calculator\";\n\n// ============================================================================\n// Label Constants\n// ============================================================================\n\n/**\n * Maximum length for Kubernetes label values\n * Labels must match pattern: ^[a-z][a-z0-9_-]{0,62}\n */\nexport const MAX_LABEL_LENGTH = 63;\n\n/**\n * Prefix added to migration numbers in labels (required because migration names start with numbers)\n */\nconst MIGRATION_LABEL_PREFIX = \"m\";\n\n/**\n * Label key for storing migration state in TailorDB Service metadata\n */\nexport const MIGRATION_LABEL_KEY = \"sdk-migration\";\n\n/** Label key identifying which migration history ID is deployed. */\nexport const MIGRATION_HISTORY_LABEL_KEY = \"sdk-migration-history\";\n\n/** Valid migration history ID syntax for metadata label values. */\nexport const MIGRATION_HISTORY_ID_PATTERN = /^[a-z][a-z0-9_-]{0,62}$/;\n\n// ============================================================================\n// Error Constants\n// ============================================================================\n\n/**\n * Error patterns that indicate schema corruption\n */\nexport const SCHEMA_ERROR_PATTERNS = [\n \"failed to fetch schema\",\n \"sqlaccess error\",\n \"schema not found\",\n \"invalid schema\",\n] as const;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Pending migration to be executed\n */\nexport interface PendingMigration {\n /** Migration number */\n number: number;\n /** Path to migration script file (may not exist on disk) */\n scriptPath: string;\n /** Whether a migration script file exists on disk for this migration */\n hasScript: boolean;\n /** Path to diff file */\n diffPath: string;\n /** Namespace this migration belongs to */\n namespace: string;\n /** Migrations directory path */\n migrationsDir: string;\n /** Migration diff content */\n diff: MigrationDiff;\n}\n\n// ============================================================================\n// Label Helper Functions\n// ============================================================================\n\n/**\n * Sanitize migration number for use as label value\n * Label pattern: ^[a-z][a-z0-9_-]{0,62}\n * - Must start with lowercase letter (add prefix since migration numbers start with digits)\n * - Max 63 characters\n * @param {number} migrationNumber - Migration number to sanitize\n * @returns {string} Sanitized label value\n */\nexport function sanitizeMigrationLabel(migrationNumber: number): string {\n const sanitized = MIGRATION_LABEL_PREFIX + formatMigrationNumber(migrationNumber);\n return sanitized.slice(0, MAX_LABEL_LENGTH);\n}\n\n/**\n * Parse migration number from label value\n * @param {string} label - Label value (e.g., \"m0001\")\n * @returns {number | null} Parsed number or null if invalid\n */\nexport function parseMigrationLabelNumber(label: string): number | null {\n if (!label.startsWith(MIGRATION_LABEL_PREFIX)) return null;\n const numStr = label.slice(MIGRATION_LABEL_PREFIX.length);\n // Strict digits-only match: a malformed label (e.g. \"m0001-extra\") must\n // read as unset, not as migration 1. Same for numbers outside the\n // 0000-9999 directory range the migrations system supports.\n if (!/^\\d+$/.test(numStr)) return null;\n const num = parseInt(numStr, 10);\n return num > 9999 ? null : num;\n}\n\n/**\n * Parse and validate a migration history ID stored in metadata.\n * @param label - Metadata label value\n * @returns Valid history ID, or null for malformed input\n */\nexport function parseMigrationHistoryId(label: string): string | null {\n return MIGRATION_HISTORY_ID_PATTERN.test(label) ? label : null;\n}\n\n/**\n * Create a migration history ID that is valid as a metadata label value.\n * @returns New migration history ID\n */\nexport function createMigrationHistoryId(): string {\n return `h${randomUUID().replaceAll(\"-\", \"\")}`;\n}\n\n// ============================================================================\n// Error Helper Functions\n// ============================================================================\n\n/**\n * Check if an error message indicates schema corruption\n * @param {string} errorMessage - Error message to check\n * @returns {boolean} True if error indicates schema corruption\n */\nexport function isSchemaError(errorMessage: string): boolean {\n const lowerMessage = errorMessage.toLowerCase();\n return SCHEMA_ERROR_PATTERNS.some((pattern) => lowerMessage.includes(pattern));\n}\n\n/**\n * Handle optional-to-required field change error with helpful message\n * @param {unknown} error - Error to handle\n * @param {string[]} messages - Additional messages to display\n */\nexport function handleOptionalToRequiredError(error: unknown, messages: string[]): never {\n if (\n error instanceof ConnectError &&\n error.code === Code.FailedPrecondition &&\n error.message.includes(\"cannot be updated from non-required to required when records exist\")\n ) {\n logger.error(\n \"Schema change failed: Cannot change field from optional to required when records exist.\",\n );\n logger.newline();\n for (const message of messages) {\n logger.info(message);\n }\n }\n throw error;\n}\n\n// ============================================================================\n// Remote Schema Verification Types\n// ============================================================================\n\n/**\n * Type of schema drift detected between remote and local snapshot\n */\nexport type SchemaDriftKind =\n | \"type_missing_remote\"\n | \"type_missing_local\"\n | \"type_settings_mismatch\"\n | \"field_missing_remote\"\n | \"field_missing_local\"\n | \"field_mismatch\"\n | \"index_missing_remote\"\n | \"index_missing_local\"\n | \"index_mismatch\"\n | \"file_missing_remote\"\n | \"file_missing_local\"\n | \"file_mismatch\"\n | \"relationship_missing_remote\"\n | \"relationship_missing_local\"\n | \"relationship_mismatch\"\n | \"permission_mismatch\"\n | \"script_mismatch\";\n\n/**\n * Single schema drift item\n */\nexport interface SchemaDrift {\n typeName: string;\n kind: SchemaDriftKind;\n fieldName?: string;\n indexName?: string;\n fileName?: string;\n relationshipName?: string;\n relationshipType?: \"forward\" | \"backward\";\n details: string;\n}\n\n/**\n * Reason why remote schema verification was skipped for a namespace\n */\nexport type RemoteSchemaVerificationSkipReason =\n | \"not_deployed\"\n | \"no_migration_label\"\n | \"no_snapshot\";\n\nexport interface MigrationCheckpointRepair {\n namespace: string;\n from: number;\n to: 0;\n fromHistoryId: string | null;\n toHistoryId: string;\n}\n\n/**\n * Result of remote schema verification for a single namespace\n */\nexport interface RemoteSchemaVerificationResult {\n namespace: string;\n remoteMigrationNumber: number;\n drifts: SchemaDrift[];\n hasDrift: boolean;\n /** Set when the remote migration checkpoint does not exist in the local migration history */\n checkpointMissingLocal?: boolean;\n /** Safe checkpoint reset offered after the remote schema matched the local baseline */\n checkpointRepair?: Omit<MigrationCheckpointRepair, \"namespace\">;\n /** Set when verification could not run (no remote migration label, or no snapshot at the remote migration number) */\n skipped?: RemoteSchemaVerificationSkipReason;\n}\n","/**\n * Zod schemas for TailorDB migration snapshot and diff files.\n *\n * Each schema mirrors the corresponding hand-written interface from\n * snapshot-types.ts / diff-calculator.ts. Schemas are cast to\n * `z.ZodType<T>` to keep them aligned with the interfaces at compile time.\n *\n * All object schemas use `z.looseObject` so that unknown keys written\n * by newer CLI versions survive a load → save round-trip.\n */\n\nimport { z } from \"zod\";\nimport { MIGRATION_HISTORY_ID_PATTERN } from \"./types\";\nimport type {\n TypeSettingsPatch,\n SnapshotPermissionState,\n TypeAddedChange,\n TypeRemovedChange,\n TypeModifiedChange,\n TypeSettingsModifiedChange,\n SnapshotTypeSettingsState,\n FieldAddedChange,\n FieldRemovedChange,\n FieldModifiedChange,\n FieldTypeModifiedChange,\n IndexAddedChange,\n IndexRemovedChange,\n IndexModifiedChange,\n FileAddedChange,\n FileRemovedChange,\n FileModifiedChange,\n RelationshipAddedChange,\n RelationshipRemovedChange,\n RelationshipModifiedChange,\n PermissionModifiedChange,\n TypeScriptsModifiedChange,\n TypeScriptsState,\n DiffChange,\n BreakingChangeInfo,\n WarningChangeInfo,\n MigrationDiff,\n ScriptSkippedInfo,\n} from \"./diff-calculator\";\nimport type {\n SnapshotHook,\n SnapshotValidation,\n SnapshotSerial,\n SnapshotEnumValue,\n SnapshotFieldConfig,\n SnapshotIndexConfig,\n SnapshotRelationship,\n SnapshotActionPermission,\n SnapshotRecordPermission,\n SnapshotGqlPermissionPolicy,\n SnapshotGqlPermission,\n TailorDBSnapshotType,\n SchemaSnapshot,\n RebaselineMarker,\n SnapshotPermissionOperand,\n SnapshotPermissionCondition,\n} from \"./snapshot-types\";\n\nfunction snapshotRecordSchema<T>(valueSchema: z.ZodType<T>): z.ZodType<Record<string, T>> {\n return z\n .custom<Record<string, unknown>>(\n (value) => typeof value === \"object\" && value !== null && !Array.isArray(value),\n { message: \"Expected record\" },\n )\n .transform((value, ctx) => {\n const record = Object.create(null) as Record<string, T>;\n for (const key of Object.keys(value)) {\n const result = valueSchema.safeParse(value[key]);\n if (!result.success) {\n for (const issue of result.error.issues) {\n ctx.addIssue({ ...issue, path: [key, ...issue.path] });\n }\n continue;\n }\n record[key] = result.data;\n }\n return record;\n }) as z.ZodType<Record<string, T>>;\n}\n\n// ============================================================================\n// Snapshot Leaf Types\n// ============================================================================\n\nexport const snapshotHookSchema: z.ZodType<SnapshotHook> = z.looseObject({\n expr: z.string(),\n});\n\nexport const snapshotValidationSchema: z.ZodType<SnapshotValidation> = z.looseObject({\n script: z.looseObject({ expr: z.string() }).optional() as z.ZodType<{ expr: string }>,\n errorMessage: z.string(),\n});\n\nexport const snapshotSerialSchema: z.ZodType<SnapshotSerial> = z.looseObject({\n start: z.number(),\n maxValue: z.number().optional(),\n format: z.string().optional(),\n});\n\nexport const snapshotEnumValueSchema: z.ZodType<SnapshotEnumValue> = z.looseObject({\n value: z.string(),\n description: z.string().optional(),\n});\n\n// SnapshotFieldConfig is self-referential (fields?: Record<string, SnapshotFieldConfig>)\n// z.lazy handles the recursion; the outer cast closes the type cycle.\nexport const snapshotFieldConfigSchema: z.ZodType<SnapshotFieldConfig> = z.looseObject({\n type: z.string(),\n // `required` defaults to true to match the pre-validation `?? true` behaviour.\n required: z.boolean().default(true),\n array: z.boolean().optional(),\n index: z.boolean().optional(),\n unique: z.boolean().optional(),\n allowedValues: z.array(snapshotEnumValueSchema).optional(),\n foreignKey: z.boolean().optional(),\n foreignKeyType: z.string().optional(),\n foreignKeyField: z.string().optional(),\n description: z.string().optional(),\n vector: z.boolean().optional(),\n hooks: z\n .looseObject({\n create: snapshotHookSchema.optional(),\n update: snapshotHookSchema.optional(),\n })\n .optional(),\n validate: z.array(snapshotValidationSchema).optional(),\n serial: snapshotSerialSchema.optional(),\n scale: z.number().optional(),\n default: z.unknown().optional(),\n fields: z.lazy(() => snapshotRecordSchema(snapshotFieldConfigSchema)).optional(),\n}) as z.ZodType<SnapshotFieldConfig>;\n\nexport const snapshotIndexConfigSchema: z.ZodType<SnapshotIndexConfig> = z.looseObject({\n fields: z.array(z.string()),\n unique: z.boolean().optional(),\n});\n\nexport const snapshotRelationshipSchema: z.ZodType<SnapshotRelationship> = z.looseObject({\n targetType: z.string(),\n targetField: z.string(),\n sourceField: z.string(),\n isArray: z.boolean(),\n description: z.string(),\n});\n\n// ============================================================================\n// Permission Types\n// ============================================================================\n\n// Structure validated; vocabulary kept open for platform evolution\nconst FIELD_REF_KEYS = [\"user\", \"record\", \"newRecord\", \"oldRecord\"] as const;\n\n// Record-level operand: reject a plain object that contains two or more known\n// ref keys — such an object is ambiguous and signals a malformed condition.\nconst snapshotPermissionOperandSchema = z.unknown().refine((v) => {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return true;\n const keys = Object.keys(v as Record<string, unknown>);\n const refKeyCount = FIELD_REF_KEYS.filter((k) => keys.includes(k)).length;\n return refKeyCount < 2;\n}, \"Ambiguous field-ref operand: contains more than one of user/record/newRecord/oldRecord\") as unknown as z.ZodType<SnapshotPermissionOperand>;\n\n// GQL operand: same ambiguity check, plus reject record/newRecord/oldRecord refs.\nconst snapshotGqlPermissionOperandSchema = z\n .unknown()\n .refine((v) => {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return true;\n const keys = Object.keys(v as Record<string, unknown>);\n const refKeyCount = FIELD_REF_KEYS.filter((k) => keys.includes(k)).length;\n return refKeyCount < 2;\n }, \"Ambiguous field-ref operand: contains more than one of user/record/newRecord/oldRecord\")\n .refine((v) => {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return true;\n const keys = Object.keys(v as Record<string, unknown>);\n return ![\"record\", \"newRecord\", \"oldRecord\"].some((k) => keys.includes(k));\n }, \"GQL permissions only support { user } field references\") as unknown as z.ZodType<SnapshotPermissionOperand>;\n\n// Structure validated; vocabulary kept open for platform evolution\nconst snapshotPermissionOperatorSchema = z.string();\n\n// SnapshotPermissionCondition is a readonly 3-tuple; extra trailing elements tolerated.\nconst snapshotPermissionConditionSchema = z\n .tuple([\n snapshotPermissionOperandSchema,\n snapshotPermissionOperatorSchema,\n snapshotPermissionOperandSchema,\n ])\n .rest(z.unknown()) as unknown as z.ZodType<SnapshotPermissionCondition>;\n\nconst snapshotGqlPermissionConditionSchema = z\n .tuple([\n snapshotGqlPermissionOperandSchema,\n snapshotPermissionOperatorSchema,\n snapshotGqlPermissionOperandSchema,\n ])\n .rest(z.unknown()) as unknown as z.ZodType<SnapshotPermissionCondition>;\n\nexport const snapshotActionPermissionSchema: z.ZodType<SnapshotActionPermission> = z.looseObject({\n conditions: z.array(snapshotPermissionConditionSchema),\n description: z.string().optional(),\n permit: z.enum([\"allow\", \"deny\"]),\n});\n\nexport const snapshotRecordPermissionSchema: z.ZodType<SnapshotRecordPermission> = z.looseObject({\n create: z.array(snapshotActionPermissionSchema).default([]),\n read: z.array(snapshotActionPermissionSchema).default([]),\n update: z.array(snapshotActionPermissionSchema).default([]),\n delete: z.array(snapshotActionPermissionSchema).default([]),\n});\n\n// Structure validated; vocabulary kept open for platform evolution\nconst snapshotGqlActionSchema = z.string();\n\nexport const snapshotGqlPermissionPolicySchema: z.ZodType<SnapshotGqlPermissionPolicy> =\n z.looseObject({\n conditions: z.array(snapshotGqlPermissionConditionSchema),\n actions: z.array(snapshotGqlActionSchema),\n permit: z.enum([\"allow\", \"deny\"]),\n description: z.string().optional(),\n }) as unknown as z.ZodType<SnapshotGqlPermissionPolicy>;\n\n// SnapshotGqlPermission = readonly SnapshotGqlPermissionPolicy[]\nconst snapshotGqlPermissionSchema: z.ZodType<SnapshotGqlPermission> = z.array(\n snapshotGqlPermissionPolicySchema,\n);\n\n// ============================================================================\n// TailorDBSnapshotType\n// ============================================================================\n\nexport const tailorDBSnapshotTypeSchema: z.ZodType<TailorDBSnapshotType> = z.looseObject({\n name: z.string(),\n // `pluralForm` is typed as required but legacy snapshots may omit it;\n // loadSnapshot backfills it via inflection so we accept undefined here.\n pluralForm: z.string().optional() as z.ZodType<string>,\n description: z.string().optional(),\n fields: snapshotRecordSchema(snapshotFieldConfigSchema),\n settings: z\n .looseObject({\n aggregation: z.boolean().optional(),\n bulkUpsert: z.boolean().optional(),\n gqlOperations: z\n .looseObject({\n create: z.boolean().optional(),\n update: z.boolean().optional(),\n delete: z.boolean().optional(),\n read: z.boolean().optional(),\n })\n .optional(),\n publishEvents: z.boolean().optional(),\n })\n .optional(),\n indexes: snapshotRecordSchema(snapshotIndexConfigSchema).optional(),\n files: snapshotRecordSchema(z.string()).optional(),\n forwardRelationships: snapshotRecordSchema(snapshotRelationshipSchema).optional(),\n backwardRelationships: snapshotRecordSchema(snapshotRelationshipSchema).optional(),\n permissions: z\n .looseObject({\n record: snapshotRecordPermissionSchema.optional(),\n gql: snapshotGqlPermissionSchema.optional(),\n })\n .optional(),\n});\n\n// ============================================================================\n// SchemaSnapshot\n// ============================================================================\n\nconst rebaselineMarkerSchema: z.ZodType<RebaselineMarker> = z.looseObject({\n historyId: z.string().regex(MIGRATION_HISTORY_ID_PATTERN),\n replacedHistoryId: z.string().regex(MIGRATION_HISTORY_ID_PATTERN).nullable(),\n replacedLatestMigration: z.number().int().min(0).max(9999),\n});\n\nexport const schemaSnapshotSchema: z.ZodType<SchemaSnapshot> = z.looseObject({\n version: z.number(),\n namespace: z.string(),\n createdAt: z.string(),\n types: snapshotRecordSchema(tailorDBSnapshotTypeSchema),\n rebaseline: rebaselineMarkerSchema.optional(),\n});\n\n// ============================================================================\n// Diff Types\n// ============================================================================\n\nconst typeSettingsPatchSchema: z.ZodType<TypeSettingsPatch> = z.looseObject({\n indexes: snapshotRecordSchema(snapshotIndexConfigSchema).optional(),\n files: snapshotRecordSchema(z.string()).optional(),\n});\n\nconst snapshotTypeSettingsStateSchema: z.ZodType<SnapshotTypeSettingsState> = z.looseObject({\n description: z.string().optional(),\n pluralForm: z.string(),\n settings: z\n .looseObject({\n aggregation: z.boolean().optional(),\n bulkUpsert: z.boolean().optional(),\n gqlOperations: z\n .looseObject({\n create: z.boolean().optional(),\n update: z.boolean().optional(),\n delete: z.boolean().optional(),\n read: z.boolean().optional(),\n })\n .optional(),\n publishEvents: z.boolean().optional(),\n })\n .optional(),\n});\n\nconst snapshotPermissionStateSchema: z.ZodType<SnapshotPermissionState> = z.looseObject({\n recordPermission: snapshotRecordPermissionSchema.optional(),\n gqlPermission: snapshotGqlPermissionSchema.optional(),\n});\n\n// Individual change schemas are typed as z.ZodType<T> after the looseObject\n// cast so that z.discriminatedUnion can accept them.\nconst typeAddedChangeSchema = z.looseObject({\n kind: z.literal(\"type_added\"),\n typeName: z.string(),\n reason: z.string().optional(),\n after: tailorDBSnapshotTypeSchema,\n}) as unknown as z.ZodType<TypeAddedChange>;\n\nconst typeRemovedChangeSchema = z.looseObject({\n kind: z.literal(\"type_removed\"),\n typeName: z.string(),\n reason: z.string().optional(),\n before: tailorDBSnapshotTypeSchema,\n}) as unknown as z.ZodType<TypeRemovedChange>;\n\nconst typeModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"type_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n before: typeSettingsPatchSchema.optional(),\n after: typeSettingsPatchSchema.optional(),\n}) as unknown as z.ZodType<TypeModifiedChange>;\n\nconst typeSettingsModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"type_settings_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n before: snapshotTypeSettingsStateSchema,\n after: snapshotTypeSettingsStateSchema,\n}) as unknown as z.ZodType<TypeSettingsModifiedChange>;\n\nconst fieldAddedChangeSchema = z.looseObject({\n kind: z.literal(\"field_added\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n after: snapshotFieldConfigSchema,\n}) as unknown as z.ZodType<FieldAddedChange>;\n\nconst fieldRemovedChangeSchema = z.looseObject({\n kind: z.literal(\"field_removed\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n before: snapshotFieldConfigSchema,\n}) as unknown as z.ZodType<FieldRemovedChange>;\n\nconst fieldModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"field_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n before: snapshotFieldConfigSchema,\n after: snapshotFieldConfigSchema,\n}) as unknown as z.ZodType<FieldModifiedChange>;\n\nconst fieldTypeModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"field_type_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n before: snapshotFieldConfigSchema,\n after: snapshotFieldConfigSchema,\n}) as unknown as z.ZodType<FieldTypeModifiedChange>;\n\nconst indexAddedChangeSchema = z.looseObject({\n kind: z.literal(\"index_added\"),\n typeName: z.string(),\n reason: z.string().optional(),\n indexName: z.string(),\n after: snapshotIndexConfigSchema,\n}) as unknown as z.ZodType<IndexAddedChange>;\n\nconst indexRemovedChangeSchema = z.looseObject({\n kind: z.literal(\"index_removed\"),\n typeName: z.string(),\n reason: z.string().optional(),\n indexName: z.string(),\n before: snapshotIndexConfigSchema,\n}) as unknown as z.ZodType<IndexRemovedChange>;\n\nconst indexModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"index_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n indexName: z.string(),\n before: snapshotIndexConfigSchema,\n after: snapshotIndexConfigSchema,\n}) as unknown as z.ZodType<IndexModifiedChange>;\n\nconst fileAddedChangeSchema = z.looseObject({\n kind: z.literal(\"file_added\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n after: z.string(),\n}) as unknown as z.ZodType<FileAddedChange>;\n\nconst fileRemovedChangeSchema = z.looseObject({\n kind: z.literal(\"file_removed\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n before: z.string(),\n}) as unknown as z.ZodType<FileRemovedChange>;\n\nconst fileModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"file_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n fieldName: z.string(),\n before: z.string(),\n after: z.string(),\n}) as unknown as z.ZodType<FileModifiedChange>;\n\nconst relationshipAddedChangeSchema = z.looseObject({\n kind: z.literal(\"relationship_added\"),\n typeName: z.string(),\n reason: z.string().optional(),\n relationshipName: z.string(),\n relationshipType: z.enum([\"forward\", \"backward\"]).optional(),\n after: snapshotRelationshipSchema,\n}) as unknown as z.ZodType<RelationshipAddedChange>;\n\nconst relationshipRemovedChangeSchema = z.looseObject({\n kind: z.literal(\"relationship_removed\"),\n typeName: z.string(),\n reason: z.string().optional(),\n relationshipName: z.string(),\n relationshipType: z.enum([\"forward\", \"backward\"]).optional(),\n before: snapshotRelationshipSchema,\n}) as unknown as z.ZodType<RelationshipRemovedChange>;\n\nconst relationshipModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"relationship_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n relationshipName: z.string(),\n relationshipType: z.enum([\"forward\", \"backward\"]).optional(),\n before: snapshotRelationshipSchema,\n after: snapshotRelationshipSchema,\n}) as unknown as z.ZodType<RelationshipModifiedChange>;\n\nconst permissionModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"permission_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n before: snapshotPermissionStateSchema.optional(),\n after: snapshotPermissionStateSchema.optional(),\n}) as unknown as z.ZodType<PermissionModifiedChange>;\n\nconst typeScriptsStateSchema: z.ZodType<TypeScriptsState> = z.looseObject({\n typeHookExpr: z\n .looseObject({\n create: z.string().optional(),\n update: z.string().optional(),\n })\n .optional(),\n typeValidateExpr: z.string().optional(),\n});\n\nconst typeScriptsModifiedChangeSchema = z.looseObject({\n kind: z.literal(\"type_scripts_modified\"),\n typeName: z.string(),\n reason: z.string().optional(),\n before: typeScriptsStateSchema,\n after: typeScriptsStateSchema,\n}) as unknown as z.ZodType<TypeScriptsModifiedChange>;\n\ntype DiscriminableSchema = Parameters<typeof z.discriminatedUnion>[1][number];\n\nexport const diffChangeSchema: z.ZodType<DiffChange> = z.discriminatedUnion(\"kind\", [\n typeAddedChangeSchema as unknown as DiscriminableSchema,\n typeRemovedChangeSchema as unknown as DiscriminableSchema,\n typeModifiedChangeSchema as unknown as DiscriminableSchema,\n typeSettingsModifiedChangeSchema as unknown as DiscriminableSchema,\n fieldAddedChangeSchema as unknown as DiscriminableSchema,\n fieldRemovedChangeSchema as unknown as DiscriminableSchema,\n fieldModifiedChangeSchema as unknown as DiscriminableSchema,\n fieldTypeModifiedChangeSchema as unknown as DiscriminableSchema,\n indexAddedChangeSchema as unknown as DiscriminableSchema,\n indexRemovedChangeSchema as unknown as DiscriminableSchema,\n indexModifiedChangeSchema as unknown as DiscriminableSchema,\n fileAddedChangeSchema as unknown as DiscriminableSchema,\n fileRemovedChangeSchema as unknown as DiscriminableSchema,\n fileModifiedChangeSchema as unknown as DiscriminableSchema,\n relationshipAddedChangeSchema as unknown as DiscriminableSchema,\n relationshipRemovedChangeSchema as unknown as DiscriminableSchema,\n relationshipModifiedChangeSchema as unknown as DiscriminableSchema,\n permissionModifiedChangeSchema as unknown as DiscriminableSchema,\n typeScriptsModifiedChangeSchema as unknown as DiscriminableSchema,\n]) as z.ZodType<DiffChange>;\n\nexport const breakingChangeInfoSchema: z.ZodType<BreakingChangeInfo> = z.looseObject({\n typeName: z.string(),\n fieldName: z.string().optional(),\n reason: z.string(),\n unsupported: z.boolean().optional(),\n showThreeStepHint: z.boolean().optional(),\n});\n\nexport const warningChangeInfoSchema: z.ZodType<WarningChangeInfo> = z.looseObject({\n typeName: z.string(),\n fieldName: z.string().optional(),\n reason: z.string(),\n});\n\nexport const scriptSkippedInfoSchema: z.ZodType<ScriptSkippedInfo> = z.looseObject({\n reason: z.string().trim().min(1),\n acknowledgedAt: z.string(),\n});\n\n// MigrationDiff: `warnings` and `hasWarnings` are optional here so that\n// older diff.json files that predate these fields still validate cleanly.\n// loadDiff backfills both from the warnings array after validation.\nexport const migrationDiffSchema: z.ZodType<MigrationDiff> = z.looseObject({\n version: z.number(),\n namespace: z.string(),\n createdAt: z.string(),\n description: z.string().optional(),\n changes: z.array(diffChangeSchema),\n hasBreakingChanges: z.boolean(),\n breakingChanges: z.array(breakingChangeInfoSchema),\n // Optional for backward compat: loadDiff backfills these after validation.\n hasWarnings: z.boolean().optional() as z.ZodType<boolean>,\n warnings: z.array(warningChangeInfoSchema).optional() as z.ZodType<WarningChangeInfo[]>,\n requiresMigrationScript: z.boolean(),\n scriptSkipped: scriptSkippedInfoSchema.optional(),\n});\n","/**\n * Schema snapshot data model for TailorDB migrations.\n *\n * Leaf module: these types describe the persisted snapshot format\n * (XXXX/schema.json) and are shared by snapshot.ts (snapshot management)\n * and diff-calculator.ts (diff types and formatting) without creating\n * import cycles between them.\n */\n\n// ============================================================================\n// Snapshot Types\n// ============================================================================\n\n/**\n * Hook configuration in schema snapshot\n */\nexport interface SnapshotHook {\n expr: string;\n}\n\n/**\n * Validation configuration in schema snapshot\n */\nexport interface SnapshotValidation {\n script?: { expr: string };\n errorMessage: string;\n}\n\n/**\n * Serial configuration in schema snapshot\n */\nexport interface SnapshotSerial {\n start: number;\n maxValue?: number;\n format?: string;\n}\n\n/**\n * Enum value with optional description in schema snapshot\n */\nexport interface SnapshotEnumValue {\n value: string;\n description?: string;\n}\n\n/**\n * Field configuration in schema snapshot\n */\nexport interface SnapshotFieldConfig {\n type: string;\n required: boolean;\n array?: boolean;\n index?: boolean;\n unique?: boolean;\n allowedValues?: SnapshotEnumValue[];\n foreignKey?: boolean;\n foreignKeyType?: string;\n foreignKeyField?: string;\n description?: string;\n vector?: boolean;\n hooks?: {\n create?: SnapshotHook;\n update?: SnapshotHook;\n };\n validate?: SnapshotValidation[];\n serial?: SnapshotSerial;\n scale?: number;\n default?: unknown;\n /** Nested fields (recursive) */\n fields?: Record<string, SnapshotFieldConfig>;\n}\n\n/**\n * Index configuration in schema snapshot\n */\nexport interface SnapshotIndexConfig {\n fields: string[];\n unique?: boolean;\n}\n\n/**\n * Relationship configuration in schema snapshot\n */\nexport interface SnapshotRelationship {\n targetType: string;\n targetField: string;\n sourceField: string;\n isArray: boolean;\n description: string;\n}\n\n// ============================================================================\n// Permission Types\n// ============================================================================\n\n/**\n * Field-reference operand in a permission condition. Always an object with\n * exactly one of `user` / `record` / `newRecord` / `oldRecord` keys.\n */\nexport type SnapshotFieldRefOperand =\n | { user: string }\n | { record: string }\n | { newRecord: string }\n | { oldRecord: string };\n\n/**\n * Literal value operand (right-hand side of a permission condition). Matches\n * the SDK-level value operand surface — primitives and their arrays — as\n * defined in the Zod parser schema (RecordPermissionOperandSchema /\n * GqlPermissionOperandSchema in parser/service/tailordb/schema.ts).\n */\nexport type SnapshotValueOperand = string | boolean | string[] | boolean[];\n\n/**\n * Permission operand union. Either a field-ref object or a literal value.\n */\nexport type SnapshotPermissionOperand = SnapshotFieldRefOperand | SnapshotValueOperand;\n\n/**\n * Permission operators\n */\nexport type SnapshotPermissionOperator = \"eq\" | \"ne\" | \"in\" | \"nin\" | \"hasAny\" | \"nhasAny\";\n\n/**\n * Permission condition tuple\n */\nexport type SnapshotPermissionCondition = readonly [\n SnapshotPermissionOperand,\n SnapshotPermissionOperator,\n SnapshotPermissionOperand,\n];\n\n/**\n * Type guard: is the operand a field-reference (object) operand?\n * @param {SnapshotPermissionOperand} operand - Operand to test\n * @returns {boolean} True if operand is a field-ref (not a value operand)\n */\nexport function isSnapshotFieldRefOperand(\n operand: SnapshotPermissionOperand,\n): operand is SnapshotFieldRefOperand {\n // snapshot JSON may contain null; z.unknown() does not reject it\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n return typeof operand === \"object\" && operand !== null && !Array.isArray(operand);\n}\n\n/**\n * Action permission policy\n */\nexport interface SnapshotActionPermission {\n conditions: readonly SnapshotPermissionCondition[];\n description?: string;\n permit: \"allow\" | \"deny\";\n}\n\n/**\n * Record-level permission configuration\n */\nexport interface SnapshotRecordPermission {\n create: readonly SnapshotActionPermission[];\n read: readonly SnapshotActionPermission[];\n update: readonly SnapshotActionPermission[];\n delete: readonly SnapshotActionPermission[];\n}\n\n/**\n * GQL permission actions\n */\nexport type SnapshotGqlAction =\n | \"read\"\n | \"create\"\n | \"update\"\n | \"delete\"\n | \"aggregate\"\n | \"bulkUpsert\"\n | \"all\";\n\n/**\n * GQL permission policy\n */\nexport interface SnapshotGqlPermissionPolicy {\n conditions: readonly SnapshotPermissionCondition[];\n actions: readonly SnapshotGqlAction[];\n permit: \"allow\" | \"deny\";\n description?: string;\n}\n\n/**\n * GQL permission configuration\n */\nexport type SnapshotGqlPermission = readonly SnapshotGqlPermissionPolicy[];\n\n/**\n * Type definition in schema snapshot.\n * `pluralForm` is always materialized — either set by the SDK user, derived\n * via inflection at snapshot construction, or backfilled when loading legacy\n * snapshots in `loadSnapshot`.\n */\nexport interface TailorDBSnapshotType {\n name: string;\n pluralForm: string;\n description?: string;\n fields: Record<string, SnapshotFieldConfig>;\n settings?: {\n aggregation?: boolean;\n bulkUpsert?: boolean;\n gqlOperations?: {\n create?: boolean;\n update?: boolean;\n delete?: boolean;\n read?: boolean;\n };\n publishEvents?: boolean;\n };\n indexes?: Record<string, SnapshotIndexConfig>;\n files?: Record<string, string>;\n forwardRelationships?: Record<string, SnapshotRelationship>;\n backwardRelationships?: Record<string, SnapshotRelationship>;\n permissions?: {\n record?: SnapshotRecordPermission;\n gql?: SnapshotGqlPermission;\n };\n typeHookExpr?: { create?: string; update?: string };\n typeValidateExpr?: string;\n}\n\nexport type SnapshotSettings = NonNullable<TailorDBSnapshotType[\"settings\"]>;\nexport type SnapshotGqlOperations = NonNullable<SnapshotSettings[\"gqlOperations\"]>;\n\n/** Identifies the history transition created by a full rebaseline. */\nexport interface RebaselineMarker {\n historyId: string;\n replacedHistoryId: string | null;\n replacedLatestMigration: number;\n}\n\n/**\n * Schema snapshot - full schema state at a point in time.\n * Stored as XXXX/schema.json. Defined here (leaf module) so that\n * snapshot-schema.ts can reference it without importing snapshot.ts.\n */\nexport interface SchemaSnapshot {\n /** Format version for future compatibility */\n version: number;\n namespace: string;\n createdAt: string;\n types: Record<string, TailorDBSnapshotType>;\n rebaseline?: RebaselineMarker;\n}\n\ndeclare const normalizedSchemaSnapshotBrand: unique symbol;\n\n/**\n * Schema snapshot normalized to a canonical form for consistent comparison.\n *\n * Returned by snapshot creation and loading functions so drift detection stays\n * stable when local definitions omit defaults that the platform materializes.\n */\nexport type NormalizedSchemaSnapshot = SchemaSnapshot & {\n readonly [normalizedSchemaSnapshotBrand]: true;\n};\n","/**\n * Schema snapshot management for TailorDB migrations\n */\n\nimport * as fs from \"node:fs\";\nimport { toJson } from \"@bufbuild/protobuf\";\nimport { ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport {\n TailorDBGQLPermission_Action,\n TailorDBType_PermitAction,\n TailorDBType_Permission_Operator,\n TailorDBType_Permission_Permit,\n type TailorDBGQLPermission,\n type TailorDBGQLPermission_Condition,\n type TailorDBGQLPermission_Operand,\n type TailorDBGQLPermission_Operator,\n type TailorDBGQLPermission_Permit,\n type TailorDBType as ProtoTailorDBType,\n type TailorDBType_Permission,\n type TailorDBType_Permission_Condition,\n type TailorDBType_Permission_Operand,\n} from \"@tailor-platform/tailor-proto/tailordb_resource_pb\";\nimport * as inflection from \"inflection\";\nimport * as path from \"pathe\";\nimport { z } from \"zod\";\nimport {\n computeSourceScriptHash,\n extractSourceScriptHash,\n} from \"#/parser/service/tailordb/type-script\";\nimport { assertDefined } from \"#/utils/assert\";\nimport {\n type MigrationDiff,\n type DiffChange,\n type FieldDiffChange,\n type BreakingChangeInfo,\n type SnapshotTypeSettingsState,\n type TypeScriptsState,\n type WarningChangeInfo,\n MIN_SUPPORTED_MIGRATION_FILE_VERSION,\n SCHEMA_SNAPSHOT_VERSION,\n} from \"./diff-calculator\";\nimport { supportsInPlaceFieldTypeChange } from \"./field-type-change\";\nimport { formatMigrationNumber } from \"./migration-number\";\nimport { schemaSnapshotSchema, migrationDiffSchema } from \"./snapshot-schema\";\nimport type {\n TailorDBType,\n OperatorFieldConfig,\n StandardActionPermission,\n} from \"#/parser/service/tailordb/types\";\nimport type {\n NormalizedSchemaSnapshot,\n SchemaSnapshot,\n SnapshotActionPermission,\n SnapshotFieldConfig,\n SnapshotGqlAction,\n SnapshotGqlPermission,\n SnapshotGqlOperations,\n SnapshotPermissionOperand,\n SnapshotPermissionOperator,\n SnapshotIndexConfig,\n SnapshotPermissionCondition,\n SnapshotRecordPermission,\n SnapshotRelationship,\n SnapshotSettings,\n TailorDBSnapshotType,\n} from \"./snapshot-types\";\nimport type { SchemaDrift } from \"./types\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Initial schema migration number (0000)\n */\nexport const INITIAL_SCHEMA_NUMBER = 0;\n\n/**\n * Migration file names (used within migration directories)\n */\nexport const SCHEMA_FILE_NAME = \"schema.json\";\n/** File name for migration diff metadata. */\nexport const DIFF_FILE_NAME = \"diff.json\";\n/** File name for migration script. */\nexport const MIGRATE_FILE_NAME = \"migrate.ts\";\n/** File name for migration script unit test. */\nexport const MIGRATE_TEST_FILE_NAME = \"migrate.test.ts\";\n/** File name for generated DB type definitions. */\nexport const DB_TYPES_FILE_NAME = \"db.ts\";\n\n/**\n * Pattern for validating migration number format (4-digit sequential number)\n * Examples: 0001, 0002, 0003, ...\n */\nexport const MIGRATION_NUMBER_PATTERN = /^\\d{4}$/;\n\n/**\n * Platform default scale for decimal fields when scale is not explicitly specified.\n * Must stay in sync with the platform's default decimal scale.\n */\nexport const DEFAULT_DECIMAL_SCALE = 6;\n\nexport class UnsupportedMigrationFileVersionError extends Error {}\n\nfunction assertSupportedMigrationFileVersion(filePath: string, raw: unknown): void {\n if (typeof raw !== \"object\" || raw === null || !(\"version\" in raw)) return;\n const version = raw.version;\n if (typeof version !== \"number\") return;\n if (\n Number.isInteger(version) &&\n version >= MIN_SUPPORTED_MIGRATION_FILE_VERSION &&\n version <= SCHEMA_SNAPSHOT_VERSION\n ) {\n return;\n }\n\n const supportedRange = `${MIN_SUPPORTED_MIGRATION_FILE_VERSION}-${SCHEMA_SNAPSHOT_VERSION}`;\n let guidance: string;\n if (version > SCHEMA_SNAPSHOT_VERSION) {\n guidance = `Upgrade to an SDK that supports migration file format version ${version}.`;\n } else if (version < MIN_SUPPORTED_MIGRATION_FILE_VERSION) {\n guidance =\n \"Re-baseline with an SDK that still supports this migration history, then upgrade the SDK.\";\n } else {\n guidance = \"Restore the migration file from version control or regenerate it.\";\n }\n throw new UnsupportedMigrationFileVersionError(\n `Unsupported migration file format version ${version} at ${filePath}. ` +\n `This SDK supports migration file format versions ${supportedRange}. ${guidance}`,\n );\n}\n\nfunction createSnapshotRecord<T>(): Record<string, T> {\n return Object.create(null) as Record<string, T>;\n}\n\nfunction copySnapshotRecord<T>(record: Record<string, T> | undefined): Record<string, T> {\n const copy = createSnapshotRecord<T>();\n for (const [key, value] of Object.entries(record ?? {})) {\n copy[key] = value;\n }\n return copy;\n}\n\n/**\n * Normalize a snapshot field into the canonical form for comparison, returning\n * a new object rather than mutating the input. Currently fills in the platform\n * default decimal scale when omitted, which avoids false drift between local\n * schemas (where scale may be omitted) and the platform (which always\n * materializes a scale).\n * @param {SnapshotFieldConfig} field - Field configuration to normalize\n * @returns {SnapshotFieldConfig} A new, normalized field object\n */\nfunction normalizeSnapshotField(field: SnapshotFieldConfig): SnapshotFieldConfig {\n const fields = field.fields\n ? Object.fromEntries(\n Object.entries(field.fields).map(([name, nested]) => [\n name,\n normalizeSnapshotField(nested),\n ]),\n )\n : undefined;\n\n return {\n ...field,\n ...(field.type === \"decimal\" && field.scale === undefined && { scale: DEFAULT_DECIMAL_SCALE }),\n ...(fields && { fields }),\n };\n}\n\n/**\n * Normalize a snapshot type into the canonical comparison shape, returning a\n * new object rather than mutating the input. Currently fills:\n * - `pluralForm` via inflection when missing (legacy snapshots written\n * before `pluralForm` became required may omit it)\n * - per-field `scale` defaults via {@link normalizeSnapshotField}\n *\n * Idempotent — safe to call multiple times on the same input.\n * @param {TailorDBSnapshotType} type - Snapshot type to normalize\n * @returns {TailorDBSnapshotType} A new, normalized snapshot type object\n */\nfunction normalizeSnapshotType(type: TailorDBSnapshotType): TailorDBSnapshotType {\n // `pluralForm` is typed as required by TailorDBSnapshotType, but JSON.parse'd legacy\n // snapshots may have it undefined at runtime — backfill from inflection.\n const pluralForm =\n (type as { pluralForm?: string }).pluralForm || inflection.pluralize(type.name);\n const fields = createSnapshotRecord<SnapshotFieldConfig>();\n for (const [fieldName, field] of Object.entries(type.fields)) {\n fields[fieldName] = normalizeSnapshotField(field);\n }\n return { ...type, pluralForm, fields };\n}\n\n/**\n * Normalize a schema snapshot into the canonical comparison shape, returning a\n * new object rather than mutating the input.\n * @param {SchemaSnapshot} snapshot - Schema snapshot to normalize\n * @returns {NormalizedSchemaSnapshot} A new schema snapshot object branded as normalized\n */\nexport function normalizeSchemaSnapshot(snapshot: SchemaSnapshot): NormalizedSchemaSnapshot {\n const types = createSnapshotRecord<TailorDBSnapshotType>();\n for (const [typeName, type] of Object.entries(snapshot.types)) {\n types[typeName] = normalizeSnapshotType(type);\n }\n return { ...snapshot, types } as NormalizedSchemaSnapshot;\n}\n\n// Re-export SCHEMA_SNAPSHOT_VERSION for convenience\nexport { SCHEMA_SNAPSHOT_VERSION };\nexport { formatMigrationNumber };\n\n// ============================================================================\n// Snapshot Types\n// ============================================================================\n\n// Snapshot data-model types live in snapshot-types.ts (leaf module shared\n// with diff-calculator.ts). Re-exported here for backward compatibility.\nexport { isSnapshotFieldRefOperand } from \"./snapshot-types\";\nexport type {\n SnapshotEnumValue,\n SnapshotFieldConfig,\n SnapshotIndexConfig,\n SnapshotRelationship,\n SnapshotPermissionOperand,\n SnapshotPermissionCondition,\n SnapshotActionPermission,\n SnapshotRecordPermission,\n SnapshotGqlPermissionPolicy,\n SnapshotGqlPermission,\n SnapshotGqlOperations,\n SnapshotSettings,\n TailorDBSnapshotType,\n SchemaSnapshot,\n NormalizedSchemaSnapshot,\n RebaselineMarker,\n} from \"./snapshot-types\";\n\n/**\n * Migration file type\n */\nexport type MigrationFileType = \"schema\" | \"diff\" | \"migrate\" | \"test\" | \"db\";\n\n// ============================================================================\n// Migration Number Helpers\n// ============================================================================\n\n/**\n * Validate that a migration number follows the expected format (4-digit number)\n * @param {string} numberStr - Migration number string to validate\n * @returns {boolean} True if number matches expected format\n */\nexport function isValidMigrationNumber(numberStr: string): boolean {\n return MIGRATION_NUMBER_PATTERN.test(numberStr);\n}\n\n// ============================================================================\n// Path Helpers\n// ============================================================================\n\n/**\n * Map of migration file types to their file names\n */\nconst MIGRATION_FILE_NAMES: Record<MigrationFileType, string> = {\n schema: SCHEMA_FILE_NAME,\n diff: DIFF_FILE_NAME,\n migrate: MIGRATE_FILE_NAME,\n test: MIGRATE_TEST_FILE_NAME,\n db: DB_TYPES_FILE_NAME,\n};\n\n/**\n * Get migration directory path for a given number\n * @param {string} migrationsDir - Base migrations directory path\n * @param {number} num - Migration number\n * @returns {string} Full directory path for the migration\n */\nexport function getMigrationDirPath(migrationsDir: string, num: number): string {\n const numStr = formatMigrationNumber(num);\n return path.join(migrationsDir, numStr);\n}\n\n/**\n * Get migration file path for a given number and type\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} num - Migration number\n * @param {MigrationFileType} type - File type\n * @returns {string} Full file path\n */\nexport function getMigrationFilePath(\n migrationsDir: string,\n num: number,\n type: MigrationFileType,\n): string {\n const migrationDir = getMigrationDirPath(migrationsDir, num);\n return path.join(migrationDir, MIGRATION_FILE_NAMES[type]);\n}\n\n// ============================================================================\n// Snapshot Creation\n// ============================================================================\n\n/**\n * Create a snapshot field config from an OperatorFieldConfig.\n * @param {import(\"#/parser/service/tailordb/types\").OperatorFieldConfig} fieldConfig - Field configuration\n * @returns {SnapshotFieldConfig} Snapshot field configuration\n */\nfunction createSnapshotFieldConfigFromOperatorConfig(\n fieldConfig: OperatorFieldConfig,\n): SnapshotFieldConfig {\n const config: SnapshotFieldConfig = {\n type: fieldConfig.type,\n required: fieldConfig.required !== false,\n };\n\n if (fieldConfig.array) config.array = true;\n if (fieldConfig.index) config.index = true;\n if (fieldConfig.unique) config.unique = true;\n\n if (fieldConfig.allowedValues && fieldConfig.allowedValues.length > 0) {\n config.allowedValues = fieldConfig.allowedValues.map((v) => ({\n value: v.value,\n ...(v.description && { description: v.description }),\n }));\n }\n\n if (fieldConfig.foreignKey) {\n config.foreignKey = true;\n if (fieldConfig.foreignKeyType) config.foreignKeyType = fieldConfig.foreignKeyType;\n if (fieldConfig.foreignKeyField) config.foreignKeyField = fieldConfig.foreignKeyField;\n }\n\n if (fieldConfig.description) config.description = fieldConfig.description;\n if (fieldConfig.vector) config.vector = true;\n\n if (fieldConfig.hooks) {\n config.hooks = {};\n if (fieldConfig.hooks.create) {\n config.hooks.create = { expr: fieldConfig.hooks.create.expr };\n }\n if (fieldConfig.hooks.update) {\n config.hooks.update = { expr: fieldConfig.hooks.update.expr };\n }\n }\n\n if (fieldConfig.validate && fieldConfig.validate.length > 0) {\n config.validate = fieldConfig.validate.map((v) => ({\n script: { expr: v.script.expr },\n errorMessage: v.errorMessage,\n }));\n }\n\n if (fieldConfig.serial) {\n config.serial = {\n start: fieldConfig.serial.start,\n ...(fieldConfig.serial.maxValue !== undefined && { maxValue: fieldConfig.serial.maxValue }),\n ...(fieldConfig.serial.format && { format: fieldConfig.serial.format }),\n };\n }\n\n if (fieldConfig.scale !== undefined) config.scale = fieldConfig.scale;\n if (fieldConfig.default !== undefined) config.default = fieldConfig.default;\n\n // Recursive for nested fields\n if (fieldConfig.fields && Object.keys(fieldConfig.fields).length > 0) {\n config.fields = {};\n for (const [nestedName, nestedConfig] of Object.entries(fieldConfig.fields)) {\n config.fields[nestedName] = createSnapshotFieldConfigFromOperatorConfig(nestedConfig);\n }\n }\n\n return normalizeSnapshotField(config);\n}\n\n/**\n * Create a snapshot type from a parsed type\n * @param {TailorDBType} type - Parsed TailorDB type definition\n * @returns {TailorDBSnapshotType} Snapshot type configuration\n */\nexport function createSnapshotType(type: TailorDBType): TailorDBSnapshotType {\n const fields = createSnapshotRecord<SnapshotFieldConfig>();\n\n for (const [fieldName, field] of Object.entries(type.fields)) {\n fields[fieldName] = createSnapshotFieldConfigFromOperatorConfig(field.config);\n }\n\n const snapshotType: TailorDBSnapshotType = {\n name: type.name,\n pluralForm: type.pluralForm || inflection.pluralize(type.name),\n fields,\n };\n\n if (type.description) snapshotType.description = type.description;\n snapshotType.settings = {};\n if (type.settings.aggregation !== undefined) {\n snapshotType.settings.aggregation = type.settings.aggregation;\n }\n if (type.settings.bulkUpsert !== undefined) {\n snapshotType.settings.bulkUpsert = type.settings.bulkUpsert;\n }\n if (type.settings.gqlOperations) {\n // gqlOperations is already normalized by schema transform\n const ops = type.settings.gqlOperations;\n snapshotType.settings.gqlOperations = {\n ...(ops.create !== undefined && {\n create: ops.create,\n }),\n ...(ops.update !== undefined && {\n update: ops.update,\n }),\n ...(ops.delete !== undefined && {\n delete: ops.delete,\n }),\n ...(ops.read !== undefined && {\n read: ops.read,\n }),\n };\n }\n if (type.settings.publishEvents !== undefined) {\n snapshotType.settings.publishEvents = type.settings.publishEvents;\n }\n\n if (type.indexes && Object.keys(type.indexes).length > 0) {\n snapshotType.indexes = {};\n for (const [indexName, indexConfig] of Object.entries(type.indexes)) {\n snapshotType.indexes[indexName] = {\n fields: indexConfig.fields,\n unique: indexConfig.unique,\n };\n }\n }\n\n if (type.files && Object.keys(type.files).length > 0) {\n snapshotType.files = { ...type.files };\n }\n\n if (type.typeHookExpr) {\n snapshotType.typeHookExpr = type.typeHookExpr;\n }\n\n if (type.typeValidateExpr) {\n snapshotType.typeValidateExpr = type.typeValidateExpr;\n }\n\n if (Object.keys(type.forwardRelationships).length > 0) {\n snapshotType.forwardRelationships = {};\n for (const [relName, rel] of Object.entries(type.forwardRelationships)) {\n snapshotType.forwardRelationships[relName] = {\n targetType: rel.targetType,\n targetField: rel.targetField,\n sourceField: rel.sourceField,\n isArray: rel.isArray,\n description: rel.description,\n };\n }\n }\n\n if (Object.keys(type.backwardRelationships).length > 0) {\n snapshotType.backwardRelationships = {};\n for (const [relName, rel] of Object.entries(type.backwardRelationships)) {\n snapshotType.backwardRelationships[relName] = {\n targetType: rel.targetType,\n targetField: rel.targetField,\n sourceField: rel.sourceField,\n isArray: rel.isArray,\n description: rel.description,\n };\n }\n }\n\n if (type.permissions.record || type.permissions.gql) {\n snapshotType.permissions = {};\n\n if (type.permissions.record) {\n snapshotType.permissions.record = {\n create: type.permissions.record.create.map(convertActionPermission),\n read: type.permissions.record.read.map(convertActionPermission),\n update: type.permissions.record.update.map(convertActionPermission),\n delete: type.permissions.record.delete.map(convertActionPermission),\n };\n }\n\n if (type.permissions.gql) {\n snapshotType.permissions.gql = type.permissions.gql.map((policy) => ({\n conditions: policy.conditions as SnapshotPermissionCondition[],\n actions: policy.actions as SnapshotGqlAction[],\n permit: policy.permit,\n ...(policy.description && { description: policy.description }),\n }));\n }\n }\n\n return normalizeSnapshotType(snapshotType);\n}\n\n/**\n * Convert an action permission to snapshot format\n * @param {StandardActionPermission<\"record\">} permission - Action permission\n * @returns {SnapshotActionPermission} Snapshot action permission\n */\nfunction convertActionPermission(\n permission: StandardActionPermission<\"record\">,\n): SnapshotActionPermission {\n return {\n conditions: permission.conditions as SnapshotPermissionCondition[],\n permit: permission.permit,\n ...(permission.description && { description: permission.description }),\n };\n}\n\n/**\n * Create a schema snapshot from local type definitions\n * @param {Record<string, TailorDBType>} types - Local type definitions\n * @param {string} namespace - Namespace for the snapshot\n * @returns {NormalizedSchemaSnapshot} Normalized schema snapshot\n */\nexport function createSnapshotFromLocalTypes(\n types: Record<string, TailorDBType>,\n namespace: string,\n): NormalizedSchemaSnapshot {\n const snapshotTypes = createSnapshotRecord<TailorDBSnapshotType>();\n\n for (const [typeName, type] of Object.entries(types)) {\n snapshotTypes[typeName] = createSnapshotType(type);\n }\n\n return normalizeSchemaSnapshot({\n version: SCHEMA_SNAPSHOT_VERSION,\n namespace,\n createdAt: new Date().toISOString(),\n types: snapshotTypes,\n });\n}\n\n// ============================================================================\n// Snapshot Loading\n// ============================================================================\n\n/**\n * Load a schema snapshot from a file\n * @param {string} filePath - Path to the snapshot file\n * @returns {NormalizedSchemaSnapshot} Loaded normalized schema snapshot\n */\nexport function loadSnapshot(filePath: string): NormalizedSchemaSnapshot {\n const content = fs.readFileSync(filePath, \"utf-8\");\n let raw: unknown;\n try {\n raw = JSON.parse(content);\n } catch (error) {\n throw new Error(`Invalid schema snapshot at ${filePath}: ${String(error)}`, { cause: error });\n }\n assertSupportedMigrationFileVersion(filePath, raw);\n const result = schemaSnapshotSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid schema snapshot at ${filePath}: ${z.prettifyError(result.error)}`, {\n cause: result.error,\n });\n }\n const snapshot = result.data;\n return normalizeSchemaSnapshot(snapshot);\n}\n\n/**\n * Load a migration diff from a file\n * @param {string} filePath - Path to the diff file\n * @returns {MigrationDiff} Loaded migration diff\n */\nexport function loadDiff(filePath: string): MigrationDiff {\n const content = fs.readFileSync(filePath, \"utf-8\");\n let raw: unknown;\n try {\n raw = JSON.parse(content);\n } catch (error) {\n throw new Error(`Invalid migration diff at ${filePath}: ${String(error)}`, { cause: error });\n }\n assertSupportedMigrationFileVersion(filePath, raw);\n const result = migrationDiffSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid migration diff at ${filePath}: ${z.prettifyError(result.error)}`, {\n cause: result.error,\n });\n }\n const parsed = result.data;\n // Backfill fields introduced after the initial diff.json schema so that older\n // migrations on disk remain readable without manual edits. A missing warnings\n // field (pre-warning-tier diff.json) is reconstructed from the recorded\n // removal changes so those migrations keep their data-loss classification.\n // hasWarnings is derived from the warnings array to stay consistent even if\n // a hand-edited diff.json sets one side without the other.\n // `warnings` is optional in the schema (backcompat) but cast to required; guard for safety\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n const warnings = parsed.warnings ?? deriveWarningsFromChanges(parsed);\n return {\n ...parsed,\n warnings,\n hasWarnings: warnings.length > 0,\n };\n}\n\nconst FIELD_REMOVED_WARNING_REASON =\n \"Field removed (existing data will no longer be accessible through the schema)\";\nconst TYPE_REMOVED_WARNING_REASON =\n \"Type removed (all records of this type will be deleted during post-migration cleanup)\";\n\n/**\n * Reconstruct data-loss warnings from removal changes for diff.json files\n * written before the warning tier existed\n * @param {MigrationDiff} diff - Parsed legacy migration diff\n * @returns {WarningChangeInfo[]} Warnings equivalent to what diff generation would have recorded\n */\nfunction deriveWarningsFromChanges(diff: MigrationDiff): WarningChangeInfo[] {\n const warnings: WarningChangeInfo[] = [];\n for (const change of diff.changes) {\n if (change.kind === \"field_removed\") {\n warnings.push({\n typeName: change.typeName,\n fieldName: change.fieldName,\n reason: FIELD_REMOVED_WARNING_REASON,\n });\n } else if (change.kind === \"type_removed\") {\n warnings.push({ typeName: change.typeName, reason: TYPE_REMOVED_WARNING_REASON });\n }\n }\n return warnings;\n}\n\n/**\n * Get all migration directories and their files, sorted by number\n * @param {string} migrationsDir - Migrations directory path\n * @returns {Array<{number: number, type: \"schema\" | \"diff\", path: string}>} Migration files sorted by number\n */\nexport function getMigrationFiles(\n migrationsDir: string,\n): { number: number; type: \"schema\" | \"diff\"; path: string }[] {\n if (!fs.existsSync(migrationsDir)) {\n return [];\n }\n\n const entries = fs.readdirSync(migrationsDir, { withFileTypes: true });\n const migrations: {\n number: number;\n type: \"schema\" | \"diff\";\n path: string;\n }[] = [];\n\n for (const entry of entries) {\n // Only process directories with valid migration numbers (e.g., \"0000\", \"0001\")\n if (!entry.isDirectory()) continue;\n if (!isValidMigrationNumber(entry.name)) continue;\n\n const num = parseInt(entry.name, 10);\n const migrationDir = path.join(migrationsDir, entry.name);\n\n // Check for schema.json\n const schemaPath = path.join(migrationDir, SCHEMA_FILE_NAME);\n if (fs.existsSync(schemaPath)) {\n migrations.push({\n number: num,\n type: \"schema\",\n path: schemaPath,\n });\n }\n\n // Check for diff.json\n const diffPath = path.join(migrationDir, DIFF_FILE_NAME);\n if (fs.existsSync(diffPath)) {\n migrations.push({\n number: num,\n type: \"diff\",\n path: diffPath,\n });\n }\n }\n\n // Sort by number\n return migrations.toSorted((a, b) => a.number - b.number);\n}\n\n/**\n * Get the next migration number for a directory\n * Returns INITIAL_SCHEMA_NUMBER (0) if no migrations exist\n * @param {string} migrationsDir - Migrations directory path\n * @returns {number} Next migration number\n */\nexport function getNextMigrationNumber(migrationsDir: string): number {\n const files = getMigrationFiles(migrationsDir);\n if (files.length === 0) return INITIAL_SCHEMA_NUMBER;\n return Math.max(...files.map((f) => f.number)) + 1;\n}\n\n/**\n * Apply a diff to a snapshot to get the resulting snapshot\n * @param {SchemaSnapshot} snapshot - Base snapshot to apply diff to\n * @param {MigrationDiff} diff - Diff to apply\n * @returns {NormalizedSchemaSnapshot} Normalized snapshot after applying diff\n */\nfunction applyDiffToSnapshot(\n snapshot: SchemaSnapshot,\n diff: MigrationDiff,\n): NormalizedSchemaSnapshot {\n const types = copySnapshotRecord(snapshot.types);\n\n for (const change of diff.changes) {\n switch (change.kind) {\n case \"type_added\":\n types[change.typeName] = change.after;\n break;\n case \"type_removed\":\n delete types[change.typeName];\n break;\n case \"type_modified\": {\n const existing = types[change.typeName];\n if (existing && change.after) {\n const after = change.after;\n types[change.typeName] = {\n ...existing,\n ...(after.indexes !== undefined && { indexes: after.indexes }),\n ...(after.files !== undefined && { files: after.files }),\n };\n }\n break;\n }\n case \"type_settings_modified\": {\n const existing = types[change.typeName];\n if (existing) {\n types[change.typeName] = {\n ...existing,\n description: change.after.description,\n pluralForm: change.after.pluralForm,\n settings: change.after.settings ?? {},\n };\n }\n break;\n }\n case \"type_scripts_modified\": {\n const existing = types[change.typeName];\n if (existing) {\n const { typeHookExpr: _, typeValidateExpr: __, ...rest } = existing;\n types[change.typeName] = {\n ...rest,\n ...(change.after.typeHookExpr && { typeHookExpr: change.after.typeHookExpr }),\n ...(change.after.typeValidateExpr !== undefined && {\n typeValidateExpr: change.after.typeValidateExpr,\n }),\n };\n }\n break;\n }\n case \"field_added\":\n case \"field_modified\":\n case \"field_type_modified\": {\n const existing = types[change.typeName];\n if (existing) {\n const fields = copySnapshotRecord(existing.fields);\n fields[change.fieldName] = change.after;\n types[change.typeName] = {\n ...existing,\n fields,\n };\n }\n break;\n }\n case \"field_removed\": {\n const existing = types[change.typeName];\n if (existing) {\n const remainingFields = copySnapshotRecord(existing.fields);\n delete remainingFields[change.fieldName];\n types[change.typeName] = {\n ...existing,\n fields: remainingFields,\n };\n }\n break;\n }\n case \"index_added\":\n case \"index_modified\": {\n const existing = types[change.typeName];\n if (existing) {\n const indexes = copySnapshotRecord(existing.indexes);\n indexes[change.indexName] = change.after;\n types[change.typeName] = {\n ...existing,\n indexes,\n };\n }\n break;\n }\n case \"index_removed\": {\n const existing = types[change.typeName];\n if (existing && existing.indexes) {\n const remainingIndexes = copySnapshotRecord(existing.indexes);\n delete remainingIndexes[change.indexName];\n types[change.typeName] = {\n ...existing,\n indexes: Object.keys(remainingIndexes).length > 0 ? remainingIndexes : undefined,\n };\n }\n break;\n }\n case \"file_added\":\n case \"file_modified\": {\n const existing = types[change.typeName];\n if (existing) {\n const files = copySnapshotRecord(existing.files);\n files[change.fieldName] = change.after;\n types[change.typeName] = {\n ...existing,\n files,\n };\n }\n break;\n }\n case \"file_removed\": {\n const existing = types[change.typeName];\n if (existing && existing.files) {\n const remainingFiles = copySnapshotRecord(existing.files);\n delete remainingFiles[change.fieldName];\n types[change.typeName] = {\n ...existing,\n files: Object.keys(remainingFiles).length > 0 ? remainingFiles : undefined,\n };\n }\n break;\n }\n case \"relationship_added\":\n case \"relationship_modified\": {\n const existing = types[change.typeName];\n if (existing) {\n const rel = change.after;\n // Use relationshipType if specified, fallback to existing logic for backwards compatibility\n const targetType =\n change.relationshipType ??\n (existing.forwardRelationships?.[change.relationshipName]\n ? \"forward\"\n : existing.backwardRelationships?.[change.relationshipName]\n ? \"backward\"\n : \"forward\");\n\n if (targetType === \"forward\") {\n const forwardRelationships = copySnapshotRecord(existing.forwardRelationships);\n forwardRelationships[change.relationshipName] = rel;\n types[change.typeName] = {\n ...existing,\n forwardRelationships,\n };\n } else {\n const backwardRelationships = copySnapshotRecord(existing.backwardRelationships);\n backwardRelationships[change.relationshipName] = rel;\n types[change.typeName] = {\n ...existing,\n backwardRelationships,\n };\n }\n }\n break;\n }\n case \"relationship_removed\": {\n const type = types[change.typeName];\n if (type) {\n // Use relationshipType if specified\n const targetType =\n change.relationshipType ??\n (type.forwardRelationships?.[change.relationshipName]\n ? \"forward\"\n : type.backwardRelationships?.[change.relationshipName]\n ? \"backward\"\n : null);\n\n if (targetType === \"forward\" && type.forwardRelationships?.[change.relationshipName]) {\n const remaining = copySnapshotRecord(type.forwardRelationships);\n delete remaining[change.relationshipName];\n types[change.typeName] = {\n ...type,\n forwardRelationships: Object.keys(remaining).length > 0 ? remaining : undefined,\n };\n } else if (\n targetType === \"backward\" &&\n type.backwardRelationships?.[change.relationshipName]\n ) {\n const remaining = copySnapshotRecord(type.backwardRelationships);\n delete remaining[change.relationshipName];\n types[change.typeName] = {\n ...type,\n backwardRelationships: Object.keys(remaining).length > 0 ? remaining : undefined,\n };\n }\n }\n break;\n }\n case \"permission_modified\": {\n const existing = types[change.typeName];\n if (existing && change.after) {\n const after = change.after;\n types[change.typeName] = {\n ...existing,\n permissions: {\n record: after.recordPermission,\n gql: after.gqlPermission,\n },\n };\n }\n break;\n }\n }\n }\n\n return normalizeSchemaSnapshot({\n ...snapshot,\n types,\n createdAt: diff.createdAt,\n });\n}\n\n/**\n * Reconstruct the latest schema snapshot from all migration files\n * Returns null if no migrations exist\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} [maxVersion] - Optional maximum migration version to apply\n * @returns {NormalizedSchemaSnapshot | null} Reconstructed normalized snapshot or null if no migrations exist\n */\nexport function reconstructSnapshotFromMigrations(\n migrationsDir: string,\n maxVersion?: number,\n): NormalizedSchemaSnapshot | null {\n const files = getMigrationFiles(migrationsDir);\n if (files.length === 0) return null;\n\n // Find the initial schema file (should be 0000/schema.json)\n const schemaFile = files.find((f) => f.type === \"schema\" && f.number === INITIAL_SCHEMA_NUMBER);\n if (!schemaFile) {\n throw new Error(\n `No initial schema file found in ${migrationsDir}. Expected ${formatMigrationNumber(\n INITIAL_SCHEMA_NUMBER,\n )}/schema.json`,\n );\n }\n\n let snapshot = loadSnapshot(schemaFile.path);\n\n // Apply subsequent diffs in order (up to maxVersion if specified)\n for (const file of files) {\n if (file.type === \"diff\" && file.number > schemaFile.number) {\n // Skip diffs beyond maxVersion if specified\n if (maxVersion !== undefined && file.number > maxVersion) {\n continue;\n }\n const diff = loadDiff(file.path);\n snapshot = applyDiffToSnapshot(snapshot, diff);\n }\n }\n\n return snapshot;\n}\n\n/**\n * Get the latest migration number from a directory\n * Returns 0 if no migrations exist\n * @param {string} migrationsDir - Migrations directory path\n * @returns {number} Latest migration number or 0 if no migrations exist\n */\nexport function getLatestMigrationNumber(migrationsDir: string): number {\n return latestMigrationNumber(getMigrationFiles(migrationsDir));\n}\n\nfunction latestMigrationNumber(files: { number: number }[]): number {\n if (files.length === 0) return 0;\n return Math.max(...files.map((f) => f.number));\n}\n\n/**\n * Assert that a migration number exists in the local migration history.\n * 0 is always accepted as the baseline snapshot.\n *\n * Returns the latest migration number so callers that need it (e.g. sync's\n * post-sync hint) can reuse this function's directory scan instead of\n * scanning the migrations directory a second time.\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} migrationNumber - Migration number to check\n * @returns {number} The latest migration number in the history\n */\nexport function assertMigrationNumberExists(\n migrationsDir: string,\n migrationNumber: number,\n): number {\n const files = getMigrationFiles(migrationsDir);\n if (migrationNumber !== 0 && !files.some((f) => f.number === migrationNumber)) {\n throw new Error(\n `Migration ${formatMigrationNumber(migrationNumber)} does not exist in working tree (latest is ${formatMigrationNumber(latestMigrationNumber(files))}).`,\n );\n }\n return latestMigrationNumber(files);\n}\n\n// ============================================================================\n// Snapshot Comparison\n// ============================================================================\n\n/**\n * Compare two field configs and determine if they are different\n * @param {SnapshotFieldConfig} oldField - Old field configuration\n * @param {SnapshotFieldConfig} newField - New field configuration\n * @returns {boolean} True if fields are different\n */\nfunction areFieldsDifferent(oldField: SnapshotFieldConfig, newField: SnapshotFieldConfig): boolean {\n // Compare required properties\n if (oldField.type !== newField.type) return true;\n if (oldField.required !== newField.required) return true;\n\n // Compare optional boolean properties (default to false)\n const booleanProps = [\"array\", \"index\", \"unique\", \"foreignKey\", \"vector\"] as const;\n for (const prop of booleanProps) {\n if ((oldField[prop] ?? false) !== (newField[prop] ?? false)) return true;\n }\n\n // Compare foreign key properties\n if (oldField.foreignKeyType !== newField.foreignKeyType) return true;\n if (oldField.foreignKeyField !== newField.foreignKeyField) return true;\n\n if ((oldField.description ?? \"\") !== (newField.description ?? \"\")) return true;\n\n const oldAllowed = oldField.allowedValues ?? [];\n const newAllowed = newField.allowedValues ?? [];\n if (oldAllowed.length !== newAllowed.length) return true;\n const newAllowedMap = new Map(newAllowed.map((v) => [v.value, v.description]));\n for (const v of oldAllowed) {\n if (!newAllowedMap.has(v.value)) return true;\n if ((v.description ?? \"\") !== (newAllowedMap.get(v.value) ?? \"\")) return true;\n }\n\n const oldHooks = oldField.hooks;\n const newHooks = newField.hooks;\n if (Boolean(oldHooks) !== Boolean(newHooks)) return true;\n if (oldHooks && newHooks) {\n if ((oldHooks.create?.expr ?? \"\") !== (newHooks.create?.expr ?? \"\")) return true;\n if ((oldHooks.update?.expr ?? \"\") !== (newHooks.update?.expr ?? \"\")) return true;\n }\n\n const oldValidate = oldField.validate ?? [];\n const newValidate = newField.validate ?? [];\n if (oldValidate.length !== newValidate.length) return true;\n for (let i = 0; i < oldValidate.length; i++) {\n const oldV = assertDefined(oldValidate[i], `oldValidate missing index ${i}`);\n const newV = assertDefined(newValidate[i], `newValidate missing index ${i}`);\n if ((oldV.script?.expr ?? \"\") !== (newV.script?.expr ?? \"\")) return true;\n if (oldV.errorMessage !== newV.errorMessage) return true;\n }\n\n const oldSerial = oldField.serial;\n const newSerial = newField.serial;\n if (Boolean(oldSerial) !== Boolean(newSerial)) return true;\n if (oldSerial && newSerial) {\n if (oldSerial.start !== newSerial.start) return true;\n if (oldSerial.maxValue !== newSerial.maxValue) return true;\n if ((oldSerial.format ?? \"\") !== (newSerial.format ?? \"\")) return true;\n }\n\n if (oldField.scale !== newField.scale) return true;\n\n if (oldField.default !== newField.default) {\n if (typeof oldField.default !== typeof newField.default) return true;\n if (JSON.stringify(oldField.default) !== JSON.stringify(newField.default)) return true;\n }\n\n const oldFields = oldField.fields ?? {};\n const newFields = newField.fields ?? {};\n const oldFieldNames = Object.keys(oldFields);\n const newFieldNames = Object.keys(newFields);\n if (oldFieldNames.length !== newFieldNames.length) return true;\n for (const fieldName of oldFieldNames) {\n const oldF = oldFields[fieldName];\n const newF = newFields[fieldName];\n if (!newF) return true;\n if (\n areFieldsDifferent(assertDefined(oldF, `field \"${fieldName}\" missing from oldFields`), newF)\n )\n return true;\n }\n\n return false;\n}\n\n/**\n * Collect breaking changes for a field change\n * @param {string} typeName - Name of the type containing the field\n * @param {string} fieldName - Name of the field being changed\n * @param {SnapshotFieldConfig | undefined} oldField - Old field configuration\n * @param {SnapshotFieldConfig | undefined} newField - New field configuration\n * @returns {BreakingChangeInfo[]} Breaking change information\n */\nfunction getBreakingFieldChanges(\n typeName: string,\n fieldName: string,\n oldField: SnapshotFieldConfig | undefined,\n newField: SnapshotFieldConfig | undefined,\n): BreakingChangeInfo[] {\n const breakingChanges: BreakingChangeInfo[] = [];\n\n // Field added as required - breaking (existing records don't have this value)\n if (!oldField && newField && newField.required) {\n breakingChanges.push({\n typeName,\n fieldName,\n reason: \"Required field added\",\n });\n }\n\n // Compatible scalar type changes use a phased in-place migration. Other\n // pairs still require expand-contract migration support.\n if (oldField && newField && oldField.type !== newField.type) {\n const supported = supportsInPlaceFieldTypeChange(oldField, newField);\n breakingChanges.push({\n typeName,\n fieldName,\n reason: `Field type changed from ${oldField.type} to ${newField.type}`,\n ...(!supported && { unsupported: true, showThreeStepHint: true }),\n });\n }\n\n // Optional to required - breaking\n if (oldField && newField && !oldField.required && newField.required) {\n breakingChanges.push({\n typeName,\n fieldName,\n reason: \"Field changed from optional to required\",\n });\n }\n\n // Array property changed - unsupported (requires 3-step migration)\n if (oldField && newField && (oldField.array ?? false) !== (newField.array ?? false)) {\n const [fromType, toType] = oldField.array\n ? [\"array\", \"single value\"]\n : [\"single value\", \"array\"];\n breakingChanges.push({\n typeName,\n fieldName,\n reason: `Field changed from ${fromType} to ${toType}`,\n unsupported: true,\n showThreeStepHint: true,\n });\n }\n\n // Foreign key relationship changed - breaking (existing references may become invalid)\n if (oldField && newField) {\n const oldForeignKeyType = oldField.foreignKeyType;\n const newForeignKeyType = newField.foreignKeyType;\n if (oldForeignKeyType && newForeignKeyType && oldForeignKeyType !== newForeignKeyType) {\n breakingChanges.push({\n typeName,\n fieldName,\n reason: `Foreign key target type changed from ${oldForeignKeyType} to ${newForeignKeyType}`,\n });\n }\n }\n\n // Unique constraint added - breaking (existing duplicate values would violate constraint)\n if (oldField && newField && !(oldField.unique ?? false) && (newField.unique ?? false)) {\n breakingChanges.push({\n typeName,\n fieldName,\n reason: \"Unique constraint added to field\",\n });\n }\n\n // Decimal scale changed - breaking (rows stored under the old scale must be\n // re-saved so their stored precision matches the new schema)\n if (\n oldField?.type === \"decimal\" &&\n newField?.type === \"decimal\" &&\n oldField.scale !== newField.scale\n ) {\n breakingChanges.push({\n typeName,\n fieldName,\n reason: `Decimal scale changed from ${oldField.scale} to ${newField.scale}`,\n });\n }\n\n // Enum values removed - breaking (existing records may have removed values)\n if (oldField && newField && oldField.type === \"enum\" && newField.type === \"enum\") {\n const oldAllowed = oldField.allowedValues ?? [];\n const newAllowed = newField.allowedValues ?? [];\n const oldValues = oldAllowed.map((v) => v.value);\n const newValuesSet = new Set(newAllowed.map((v) => v.value));\n const removedValues = oldValues.filter((v) => !newValuesSet.has(v));\n if (removedValues.length > 0) {\n breakingChanges.push({\n typeName,\n fieldName,\n reason: `Enum values removed: ${removedValues.join(\", \")}`,\n });\n }\n }\n\n return breakingChanges;\n}\n\n/**\n * Context for collecting diff changes, breaking changes, and warnings\n */\ninterface DiffContext {\n changes: DiffChange[];\n breakingChanges: BreakingChangeInfo[];\n warnings: WarningChangeInfo[];\n}\n\nfunction addChange(\n ctx: DiffContext,\n change: FieldDiffChange,\n oldField: SnapshotFieldConfig | undefined,\n newField: SnapshotFieldConfig | undefined,\n): void {\n ctx.changes.push(change);\n\n if (!change.fieldName) return;\n\n const breakingChanges = getBreakingFieldChanges(\n change.typeName,\n change.fieldName,\n oldField,\n newField,\n );\n if (breakingChanges.length > 0) {\n ctx.breakingChanges.push(...breakingChanges);\n return;\n }\n\n // Non-breaking removal still risks losing schema access: surface a warning so users\n // can decide whether to add a migration script (e.g. JOIN through a\n // soon-to-be-dropped foreign key before it disappears).\n if (change.kind === \"field_removed\") {\n ctx.warnings.push({\n typeName: change.typeName,\n fieldName: change.fieldName,\n reason: FIELD_REMOVED_WARNING_REASON,\n });\n }\n}\n\nfunction compareTypeFields(\n ctx: DiffContext,\n typeName: string,\n prevType: TailorDBSnapshotType,\n currType: TailorDBSnapshotType,\n): void {\n const prevFieldNames = new Set(Object.keys(prevType.fields));\n const currFieldNames = new Set(Object.keys(currType.fields));\n\n // Check for added fields\n for (const fieldName of currFieldNames) {\n if (!prevFieldNames.has(fieldName)) {\n const currField = assertDefined(\n currType.fields[fieldName],\n `field \"${fieldName}\" missing from currType`,\n );\n addChange(\n ctx,\n {\n kind: \"field_added\",\n typeName,\n fieldName,\n after: currField,\n },\n undefined,\n currField,\n );\n }\n }\n\n // Check for removed fields\n for (const fieldName of prevFieldNames) {\n if (!currFieldNames.has(fieldName)) {\n const prevField = assertDefined(\n prevType.fields[fieldName],\n `field \"${fieldName}\" missing from prevType`,\n );\n addChange(\n ctx,\n {\n kind: \"field_removed\",\n typeName,\n fieldName,\n before: prevField,\n },\n prevField,\n undefined,\n );\n }\n }\n\n // Check for modified fields\n for (const fieldName of currFieldNames) {\n if (!prevFieldNames.has(fieldName)) continue;\n\n const prevField = assertDefined(\n prevType.fields[fieldName],\n `field \"${fieldName}\" missing from prevType`,\n );\n const currField = assertDefined(\n currType.fields[fieldName],\n `field \"${fieldName}\" missing from currType`,\n );\n\n if (areFieldsDifferent(prevField, currField)) {\n addChange(\n ctx,\n {\n kind: prevField.type === currField.type ? \"field_modified\" : \"field_type_modified\",\n typeName,\n fieldName,\n before: prevField,\n after: currField,\n },\n prevField,\n currField,\n );\n }\n }\n}\n\n/**\n * Determine if a type-level index change is breaking. Mirrors the field-level\n * unique reasoning: enforcing a unique constraint over existing rows can fail\n * on duplicates, so both adding a unique index and re-pointing an existing\n * unique index at a different field set require a data migration.\n * @param {string} typeName - Name of the type containing the index\n * @param {string} indexName - Name of the index being changed\n * @param {SnapshotIndexConfig | undefined} oldIndex - Old index configuration\n * @param {SnapshotIndexConfig | undefined} newIndex - New index configuration\n * @returns {BreakingChangeInfo | null} Breaking change info or null if not breaking\n */\nexport function isBreakingIndexChange(\n typeName: string,\n indexName: string,\n oldIndex: SnapshotIndexConfig | undefined,\n newIndex: SnapshotIndexConfig | undefined,\n): BreakingChangeInfo | null {\n if (!newIndex || !(newIndex.unique ?? false)) return null;\n\n // Unique index added, or unique constraint added to an existing index\n if (!oldIndex || !(oldIndex.unique ?? false)) {\n return {\n typeName,\n reason: `Unique constraint added to index \"${indexName}\"`,\n };\n }\n\n // Unique index re-pointed at a different field set: the old constraint is\n // dropped and a new one enforced, so duplicates are just as possible.\n if (JSON.stringify(oldIndex.fields.toSorted()) !== JSON.stringify(newIndex.fields.toSorted())) {\n return {\n typeName,\n reason: `Unique index fields changed on index \"${indexName}\"`,\n };\n }\n\n return null;\n}\n\n/**\n * Compare type-level indexes\n * @param {DiffContext} ctx - Diff context\n * @param {string} typeName - Type name\n * @param {Record<string, SnapshotIndexConfig> | undefined} oldIndexes - Previous indexes\n * @param {Record<string, SnapshotIndexConfig> | undefined} newIndexes - Current indexes\n * @returns {void}\n */\nfunction compareIndexes(\n ctx: DiffContext,\n typeName: string,\n oldIndexes: Record<string, SnapshotIndexConfig> | undefined,\n newIndexes: Record<string, SnapshotIndexConfig> | undefined,\n): void {\n const oldKeys = new Set(Object.keys(oldIndexes || {}));\n const newKeys = new Set(Object.keys(newIndexes || {}));\n\n // Index added\n for (const [indexName, indexConfig] of Object.entries(newIndexes ?? {})) {\n if (!oldKeys.has(indexName)) {\n ctx.changes.push({\n kind: \"index_added\",\n typeName,\n indexName,\n after: indexConfig,\n });\n const breaking = isBreakingIndexChange(typeName, indexName, undefined, indexConfig);\n if (breaking) {\n ctx.breakingChanges.push(breaking);\n }\n }\n }\n\n // Index removed\n for (const [indexName, indexConfig] of Object.entries(oldIndexes ?? {})) {\n if (!newKeys.has(indexName)) {\n ctx.changes.push({\n kind: \"index_removed\",\n typeName,\n indexName,\n before: indexConfig,\n });\n }\n }\n\n // Index modified\n for (const [indexName, newIndex] of Object.entries(newIndexes ?? {})) {\n if (oldKeys.has(indexName)) {\n const oldIndex = assertDefined(\n assertDefined(oldIndexes, \"oldIndexes is undefined when oldKeys has entry\")[indexName],\n `index \"${indexName}\" missing from oldIndexes`,\n );\n\n const oldFieldsStr = JSON.stringify(oldIndex.fields.toSorted());\n const newFieldsStr = JSON.stringify(newIndex.fields.toSorted());\n\n if (\n oldFieldsStr !== newFieldsStr ||\n (oldIndex.unique ?? false) !== (newIndex.unique ?? false)\n ) {\n const reasons: string[] = [];\n if (oldFieldsStr !== newFieldsStr) reasons.push(\"fields changed\");\n if ((oldIndex.unique ?? false) !== (newIndex.unique ?? false))\n reasons.push(\"unique constraint changed\");\n ctx.changes.push({\n kind: \"index_modified\",\n typeName,\n indexName,\n reason: reasons.join(\", \"),\n before: oldIndex,\n after: newIndex,\n });\n const breaking = isBreakingIndexChange(typeName, indexName, oldIndex, newIndex);\n if (breaking) {\n ctx.breakingChanges.push(breaking);\n }\n }\n }\n }\n}\n\n/**\n * Compare type-level file fields\n * @param {DiffContext} ctx - Diff context\n * @param {string} typeName - Type name\n * @param {Record<string, string> | undefined} oldFiles - Previous file fields\n * @param {Record<string, string> | undefined} newFiles - Current file fields\n * @returns {void}\n */\nfunction compareFiles(\n ctx: DiffContext,\n typeName: string,\n oldFiles: Record<string, string> | undefined,\n newFiles: Record<string, string> | undefined,\n): void {\n const oldKeys = new Set(Object.keys(oldFiles || {}));\n const newKeys = new Set(Object.keys(newFiles || {}));\n\n // File field added\n for (const [fileName, fileDesc] of Object.entries(newFiles ?? {})) {\n if (!oldKeys.has(fileName)) {\n ctx.changes.push({\n kind: \"file_added\",\n typeName,\n fieldName: fileName,\n after: fileDesc,\n });\n }\n }\n\n // File field removed\n for (const [fileName, fileDesc] of Object.entries(oldFiles ?? {})) {\n if (!newKeys.has(fileName)) {\n ctx.changes.push({\n kind: \"file_removed\",\n typeName,\n fieldName: fileName,\n before: fileDesc,\n });\n }\n }\n\n // File field modified (description changed)\n for (const [fileName, newDesc] of Object.entries(newFiles ?? {})) {\n if (oldKeys.has(fileName)) {\n const oldDesc = assertDefined(\n assertDefined(oldFiles, \"oldFiles is undefined when oldKeys has entry\")[fileName],\n `file \"${fileName}\" missing from oldFiles`,\n );\n if (oldDesc !== newDesc) {\n ctx.changes.push({\n kind: \"file_modified\",\n typeName,\n fieldName: fileName,\n reason: \"description changed\",\n before: oldDesc,\n after: newDesc,\n });\n }\n }\n }\n}\n\n/**\n * Compare type-level relationships\n * @param {DiffContext} ctx - Diff context\n * @param {string} typeName - Type name\n * @param {\"forward\" | \"backward\"} relationshipType - Relationship direction to compare\n * @param {Record<string, SnapshotRelationship> | undefined} oldRelationships - Previous relationships\n * @param {Record<string, SnapshotRelationship> | undefined} newRelationships - Current relationships\n * @returns {void}\n */\nfunction compareRelationships(\n ctx: DiffContext,\n typeName: string,\n relationshipType: \"forward\" | \"backward\",\n oldRelationships: Record<string, SnapshotRelationship> | undefined,\n newRelationships: Record<string, SnapshotRelationship> | undefined,\n): void {\n const oldKeys = new Set(Object.keys(oldRelationships || {}));\n const newKeys = new Set(Object.keys(newRelationships || {}));\n\n // Relationship added\n for (const [relName, rel] of Object.entries(newRelationships ?? {})) {\n if (!oldKeys.has(relName)) {\n ctx.changes.push({\n kind: \"relationship_added\",\n typeName,\n relationshipName: relName,\n relationshipType,\n after: rel,\n });\n }\n }\n\n // Relationship removed\n for (const [relName, rel] of Object.entries(oldRelationships ?? {})) {\n if (!newKeys.has(relName)) {\n ctx.changes.push({\n kind: \"relationship_removed\",\n typeName,\n relationshipName: relName,\n relationshipType,\n before: rel,\n });\n }\n }\n\n // Relationship modified\n for (const [relName, newRel] of Object.entries(newRelationships ?? {})) {\n if (oldKeys.has(relName)) {\n const oldRel = assertDefined(\n assertDefined(oldRelationships, \"oldRelationships is undefined when oldKeys has entry\")[\n relName\n ],\n `relationship \"${relName}\" missing from oldRelationships`,\n );\n\n const reasons: string[] = [];\n if (oldRel.targetType !== newRel.targetType) reasons.push(\"targetType changed\");\n if (oldRel.targetField !== newRel.targetField) reasons.push(\"targetField changed\");\n if (oldRel.sourceField !== newRel.sourceField) reasons.push(\"sourceField changed\");\n if (oldRel.isArray !== newRel.isArray) reasons.push(\"isArray changed\");\n if (oldRel.description !== newRel.description) {\n reasons.push(\"description changed\");\n }\n\n if (reasons.length > 0) {\n ctx.changes.push({\n kind: \"relationship_modified\",\n typeName,\n relationshipName: relName,\n relationshipType,\n reason: reasons.join(\", \"),\n before: oldRel,\n after: newRel,\n });\n }\n }\n }\n}\n\n/**\n * Compare type-level permissions\n * @param {DiffContext} ctx - Diff context\n * @param {string} typeName - Type name\n * @param {SnapshotRecordPermission | undefined} oldRecordPerm - Previous record permission\n * @param {SnapshotRecordPermission | undefined} newRecordPerm - Current record permission\n * @param {SnapshotGqlPermission | undefined} oldGqlPerm - Previous GQL permission\n * @param {SnapshotGqlPermission | undefined} newGqlPerm - Current GQL permission\n * @returns {void}\n */\nfunction comparePermissions(\n ctx: DiffContext,\n typeName: string,\n oldRecordPerm: SnapshotRecordPermission | undefined,\n newRecordPerm: SnapshotRecordPermission | undefined,\n oldGqlPerm: SnapshotGqlPermission | undefined,\n newGqlPerm: SnapshotGqlPermission | undefined,\n): void {\n // Compare record permissions\n const oldComparableRecordPerm = comparableRecordPermission(oldRecordPerm);\n const newComparableRecordPerm = comparableRecordPermission(newRecordPerm);\n const oldRecordStr = JSON.stringify(oldComparableRecordPerm ?? null);\n const newRecordStr = JSON.stringify(newComparableRecordPerm ?? null);\n const recordPermChanged = oldRecordStr !== newRecordStr;\n\n // Compare GQL permissions\n const oldComparableGqlPerm = comparableGqlPermission(oldGqlPerm);\n const newComparableGqlPerm = comparableGqlPermission(newGqlPerm);\n const oldGqlStr = JSON.stringify(oldComparableGqlPerm ?? null);\n const newGqlStr = JSON.stringify(newComparableGqlPerm ?? null);\n const gqlPermChanged = oldGqlStr !== newGqlStr;\n\n if (recordPermChanged || gqlPermChanged) {\n const reasons: string[] = [];\n if (recordPermChanged) reasons.push(\"record permission\");\n if (gqlPermChanged) reasons.push(\"GQL permission\");\n\n ctx.changes.push({\n kind: \"permission_modified\",\n typeName,\n reason: `${reasons.join(\" and \")} changed`,\n before: { recordPermission: oldComparableRecordPerm, gqlPermission: oldComparableGqlPerm },\n after: { recordPermission: newComparableRecordPerm, gqlPermission: newComparableGqlPerm },\n });\n }\n}\n\nconst GQL_ACTION_ORDER: Record<SnapshotGqlAction, number> = {\n all: 0,\n create: 1,\n read: 2,\n update: 3,\n delete: 4,\n aggregate: 5,\n bulkUpsert: 6,\n};\n\n// Policies and conditions combine as an order-independent set on the platform,\n// so canonicalize their order before comparison to avoid false drift when the\n// remote returns them in a different order than the local snapshot declares.\nfunction sortByJson<T>(items: readonly T[]): T[] {\n return items\n .map((item) => [JSON.stringify(item), item] as const)\n .toSorted(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([, item]) => item);\n}\n\nfunction comparableGqlPermission(\n permission: SnapshotGqlPermission | undefined,\n): SnapshotGqlPermission | undefined {\n const policies = permission?.map((policy) => ({\n ...policy,\n conditions: sortByJson(policy.conditions),\n actions: policy.actions.toSorted(\n (left, right) => GQL_ACTION_ORDER[left] - GQL_ACTION_ORDER[right],\n ),\n }));\n return policies && policies.length > 0 ? sortByJson(policies) : undefined;\n}\n\nfunction comparableRecordPermission(\n permission: SnapshotRecordPermission | undefined,\n): SnapshotRecordPermission | undefined {\n if (!permission) return undefined;\n if (!Object.values(permission).some((policies) => policies.length > 0)) return undefined;\n\n const canonical: SnapshotRecordPermission = {\n create: sortByJson(permission.create.map(canonicalActionPermission)),\n read: sortByJson(permission.read.map(canonicalActionPermission)),\n update: sortByJson(permission.update.map(canonicalActionPermission)),\n delete: sortByJson(permission.delete.map(canonicalActionPermission)),\n };\n return canonical;\n}\n\nfunction canonicalActionPermission(policy: SnapshotActionPermission): SnapshotActionPermission {\n return { ...policy, conditions: sortByJson(policy.conditions) };\n}\n\nfunction normalizeComparableGqlOperations(\n operations: SnapshotGqlOperations | undefined,\n): SnapshotGqlOperations | undefined {\n if (!operations) return undefined;\n\n return {\n create: operations.create ?? true,\n update: operations.update ?? true,\n delete: operations.delete ?? true,\n read: operations.read ?? true,\n };\n}\n\nfunction normalizeComparableSettings(\n settings: TailorDBSnapshotType[\"settings\"],\n): TailorDBSnapshotType[\"settings\"] | undefined {\n const normalized: SnapshotSettings = {};\n\n if (settings?.aggregation === true) normalized.aggregation = true;\n if (settings?.bulkUpsert === true) normalized.bulkUpsert = true;\n if (settings?.publishEvents === true) normalized.publishEvents = true;\n\n const gqlOperations = normalizeComparableGqlOperations(settings?.gqlOperations);\n if (gqlOperations) normalized.gqlOperations = gqlOperations;\n\n return Object.keys(normalized).length > 0 ? normalized : undefined;\n}\n\nfunction typeSettingsState(\n description: string | undefined,\n pluralForm: string,\n settings: TailorDBSnapshotType[\"settings\"],\n): SnapshotTypeSettingsState {\n return {\n ...(description ? { description } : {}),\n pluralForm,\n ...(settings && { settings }),\n };\n}\n\nfunction comparableTypeSettings(type: TailorDBSnapshotType): SnapshotTypeSettingsState {\n return typeSettingsState(\n type.description,\n inflection.camelize(type.pluralForm, true),\n normalizeComparableSettings(type.settings),\n );\n}\n\nfunction snapshotTypeSettingsState(type: TailorDBSnapshotType): SnapshotTypeSettingsState {\n return typeSettingsState(type.description, type.pluralForm, type.settings ?? {});\n}\n\nfunction compareTypeSettings(\n ctx: DiffContext,\n typeName: string,\n previous: TailorDBSnapshotType,\n current: TailorDBSnapshotType,\n): void {\n const previousComparable = comparableTypeSettings(previous);\n const currentComparable = comparableTypeSettings(current);\n\n if (JSON.stringify(previousComparable) === JSON.stringify(currentComparable)) return;\n\n ctx.changes.push({\n kind: \"type_settings_modified\",\n typeName,\n reason: \"settings changed\",\n before: snapshotTypeSettingsState(previous),\n after: snapshotTypeSettingsState(current),\n });\n}\n\nfunction typeScriptsState(type: TailorDBSnapshotType): TypeScriptsState {\n return {\n ...(type.typeHookExpr && { typeHookExpr: type.typeHookExpr }),\n ...(type.typeValidateExpr !== undefined && { typeValidateExpr: type.typeValidateExpr }),\n };\n}\n\nfunction compareTypeScripts(\n ctx: DiffContext,\n typeName: string,\n previous: TailorDBSnapshotType,\n current: TailorDBSnapshotType,\n): void {\n const prevState = typeScriptsState(previous);\n const currState = typeScriptsState(current);\n\n if (JSON.stringify(prevState) === JSON.stringify(currState)) return;\n\n ctx.changes.push({\n kind: \"type_scripts_modified\",\n typeName,\n reason: \"type-level scripts changed\",\n before: prevState,\n after: currState,\n });\n}\n\n/**\n * Compare two snapshots and generate a diff\n * @param {SchemaSnapshot} previous - Previous schema snapshot\n * @param {SchemaSnapshot} current - Current schema snapshot\n * @returns {MigrationDiff} Migration diff between snapshots\n */\nexport function compareSnapshots(previous: SchemaSnapshot, current: SchemaSnapshot): MigrationDiff {\n return compareNormalizedSnapshots(\n normalizeSchemaSnapshot(previous),\n normalizeSchemaSnapshot(current),\n );\n}\n\nfunction compareNormalizedSnapshots(\n previous: NormalizedSchemaSnapshot,\n current: NormalizedSchemaSnapshot,\n): MigrationDiff {\n const ctx: DiffContext = { changes: [], breakingChanges: [], warnings: [] };\n\n const previousTypeNames = new Set(Object.keys(previous.types));\n const currentTypeNames = new Set(Object.keys(current.types));\n\n // Check for added types\n for (const [typeName, type] of Object.entries(current.types)) {\n if (!previousTypeNames.has(typeName)) {\n ctx.changes.push({\n kind: \"type_added\",\n typeName,\n after: type,\n });\n }\n }\n\n // Check for removed types\n for (const [typeName, type] of Object.entries(previous.types)) {\n if (!currentTypeNames.has(typeName)) {\n ctx.changes.push({\n kind: \"type_removed\",\n typeName,\n before: type,\n });\n ctx.warnings.push({\n typeName,\n reason: TYPE_REMOVED_WARNING_REASON,\n });\n }\n }\n\n // Check for modified types\n for (const typeName of currentTypeNames) {\n if (!previousTypeNames.has(typeName)) continue;\n\n const prevType = assertDefined(\n previous.types[typeName],\n `type \"${typeName}\" missing from previous snapshot`,\n );\n const currType = assertDefined(\n current.types[typeName],\n `type \"${typeName}\" missing from current snapshot`,\n );\n\n // Compare type-level settings and metadata\n compareTypeSettings(ctx, typeName, prevType, currType);\n\n // Compare type-level hook/validate scripts\n compareTypeScripts(ctx, typeName, prevType, currType);\n\n // Compare fields\n compareTypeFields(ctx, typeName, prevType, currType);\n\n // Compare indexes\n compareIndexes(ctx, typeName, prevType.indexes, currType.indexes);\n\n // Compare file fields\n compareFiles(ctx, typeName, prevType.files, currType.files);\n\n // Compare relationships\n compareRelationships(\n ctx,\n typeName,\n \"forward\",\n prevType.forwardRelationships,\n currType.forwardRelationships,\n );\n compareRelationships(\n ctx,\n typeName,\n \"backward\",\n prevType.backwardRelationships,\n currType.backwardRelationships,\n );\n\n // Compare permissions\n comparePermissions(\n ctx,\n typeName,\n prevType.permissions?.record,\n currType.permissions?.record,\n prevType.permissions?.gql,\n currType.permissions?.gql,\n );\n }\n\n return {\n version: SCHEMA_SNAPSHOT_VERSION,\n namespace: current.namespace,\n createdAt: new Date().toISOString(),\n changes: ctx.changes,\n hasBreakingChanges: ctx.breakingChanges.length > 0,\n breakingChanges: ctx.breakingChanges,\n hasWarnings: ctx.warnings.length > 0,\n warnings: ctx.warnings,\n requiresMigrationScript: ctx.breakingChanges.length > 0,\n };\n}\n\n/**\n * Compare a snapshot against canonical TailorDBSnapshotType-shaped local types.\n * Callers are expected to pre-convert TailorDBService.types to TailorDBSnapshotType via\n * `createSnapshotType`. As a safety net, `compareSnapshots` re-runs idempotent\n * normalization on both sides, so a caller that forgets will still get correct\n * comparisons (no silent false drift).\n * @param {SchemaSnapshot} snapshot - Schema snapshot to compare against\n * @param {Record<string, TailorDBSnapshotType>} localTypes - Local snapshot-shaped types\n * @param {string} namespace - Namespace for comparison\n * @returns {MigrationDiff} Migration diff\n */\nexport function compareLocalTypesWithSnapshot(\n snapshot: SchemaSnapshot,\n localTypes: Record<string, TailorDBSnapshotType>,\n namespace: string,\n): MigrationDiff {\n const currentSnapshot: SchemaSnapshot = {\n version: SCHEMA_SNAPSHOT_VERSION,\n namespace,\n createdAt: new Date().toISOString(),\n types: localTypes,\n };\n return compareSnapshots(snapshot, currentSnapshot);\n}\n\n// ============================================================================\n// Snapshot Writing\n// ============================================================================\n\n/**\n * Write a schema snapshot to a file (creates directory structure)\n * @param {SchemaSnapshot} snapshot - Snapshot to write\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} num - Migration number\n * @returns {string} Path to the written file\n */\nexport function writeSnapshot(\n snapshot: SchemaSnapshot,\n migrationsDir: string,\n num: number,\n): string {\n const migrationDir = getMigrationDirPath(migrationsDir, num);\n fs.mkdirSync(migrationDir, { recursive: true });\n const filePath = getMigrationFilePath(migrationsDir, num, \"schema\");\n fs.writeFileSync(filePath, JSON.stringify(snapshot, null, 2));\n return filePath;\n}\n\n/**\n * Write a migration diff to a file (creates directory structure)\n * @param {MigrationDiff} diff - Diff to write\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} num - Migration number\n * @returns {string} Path to the written file\n */\nexport function writeDiff(diff: MigrationDiff, migrationsDir: string, num: number): string {\n const migrationDir = getMigrationDirPath(migrationsDir, num);\n fs.mkdirSync(migrationDir, { recursive: true });\n const filePath = getMigrationFilePath(migrationsDir, num, \"diff\");\n fs.writeFileSync(filePath, JSON.stringify(diff, null, 2));\n return filePath;\n}\n\n// ============================================================================\n// Migration Validation\n// ============================================================================\n\n/**\n * Validation error for migration files\n */\nexport interface MigrationValidationError {\n type: \"missing_schema\" | \"missing_diff\" | \"duplicate\" | \"gap\" | \"invalid_schema_number\";\n message: string;\n migrationNumber?: number;\n}\n\n/**\n * Validate migration files in a directory\n *\n * Checks:\n * - Schema file exists at 0000 (initial schema)\n * - No gaps in migration numbers\n * - No duplicate migration numbers (schema at 0000, diffs at 1+)\n * - Diff files exist for migrations 1+\n * @param {string} migrationsDir - Migrations directory path\n * @returns {MigrationValidationError[]} Array of validation errors (empty if valid)\n */\nexport function validateMigrationFiles(migrationsDir: string): MigrationValidationError[] {\n const errors: MigrationValidationError[] = [];\n\n if (!fs.existsSync(migrationsDir)) {\n // No migrations directory - this is valid (no migrations yet)\n return errors;\n }\n\n // Use getMigrationFiles to get directory-based migration files\n const migrationFiles = getMigrationFiles(migrationsDir);\n if (migrationFiles.length === 0) {\n // No migration files at all - valid\n return errors;\n }\n\n // Categorize files by type\n const schemaFiles: number[] = [];\n const diffFiles: number[] = [];\n\n for (const file of migrationFiles) {\n if (file.type === \"schema\") {\n schemaFiles.push(file.number);\n } else {\n diffFiles.push(file.number);\n }\n }\n\n // Check for schema file at INITIAL_SCHEMA_NUMBER (0000)\n if (!schemaFiles.includes(INITIAL_SCHEMA_NUMBER)) {\n errors.push({\n type: \"missing_schema\",\n message: `Initial schema snapshot (${formatMigrationNumber(\n INITIAL_SCHEMA_NUMBER,\n )}/schema.json) is missing`,\n migrationNumber: INITIAL_SCHEMA_NUMBER,\n });\n }\n\n // Check for schema files at wrong positions (only 0000 should have schema)\n for (const num of schemaFiles) {\n if (num !== INITIAL_SCHEMA_NUMBER) {\n errors.push({\n type: \"invalid_schema_number\",\n message: `Schema file found at migration ${formatMigrationNumber(\n num,\n )}, but schema should only exist at ${formatMigrationNumber(INITIAL_SCHEMA_NUMBER)}`,\n migrationNumber: num,\n });\n }\n }\n\n // Get all migration numbers\n const allNumbers = [...new Set([...schemaFiles, ...diffFiles])].toSorted((a, b) => a - b);\n\n if (allNumbers.length === 0) {\n return errors;\n }\n\n // Check for duplicate files (same number with both schema and diff, except for INITIAL_SCHEMA_NUMBER)\n for (const num of schemaFiles) {\n if (num !== INITIAL_SCHEMA_NUMBER && diffFiles.includes(num)) {\n errors.push({\n type: \"duplicate\",\n message: `Migration ${formatMigrationNumber(num)} has both schema and diff files`,\n migrationNumber: num,\n });\n }\n }\n\n // Check for gaps in sequence (from INITIAL_SCHEMA_NUMBER to max)\n const maxNum = Math.max(...allNumbers);\n for (let i = INITIAL_SCHEMA_NUMBER; i <= maxNum; i++) {\n if (!allNumbers.includes(i)) {\n errors.push({\n type: \"gap\",\n message: `Migration ${formatMigrationNumber(i)} is missing (gap in sequence)`,\n migrationNumber: i,\n });\n }\n }\n\n // Check that migrations > INITIAL_SCHEMA_NUMBER have diff files\n for (const num of allNumbers) {\n if (num > INITIAL_SCHEMA_NUMBER && !diffFiles.includes(num)) {\n errors.push({\n type: \"missing_diff\",\n message: `Migration ${formatMigrationNumber(num)} is missing diff file`,\n migrationNumber: num,\n });\n }\n }\n\n return errors;\n}\n\n/**\n * Validate migration files and throw if invalid\n * @param {string} migrationsDir - Migrations directory path\n * @param {string} namespace - Namespace for error messages\n * @throws {Error} If validation fails\n */\nexport function assertValidMigrationFiles(migrationsDir: string, namespace: string): void {\n const errors = validateMigrationFiles(migrationsDir);\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => ` - ${e.message}`).join(\"\\n\");\n throw new Error(\n `Migration file validation failed for namespace \"${namespace}\":\\n${errorMessages}`,\n );\n }\n}\n\n// ============================================================================\n// Remote Schema Verification\n// ============================================================================\n\nexport interface RemoteGqlPermission {\n typeName: string;\n permission?: TailorDBGQLPermission;\n}\n\ntype RemoteFieldConfig = NonNullable<ProtoTailorDBType[\"schema\"]>[\"fields\"][string];\ntype RemoteRelationshipConfig = NonNullable<ProtoTailorDBType[\"schema\"]>[\"relationships\"][string];\n\nfunction convertRemoteFieldToSnapshot(remoteField: RemoteFieldConfig): SnapshotFieldConfig {\n const config: SnapshotFieldConfig = {\n type: remoteField.type,\n required: remoteField.required,\n };\n\n if (remoteField.array) config.array = true;\n if (remoteField.index) config.index = true;\n if (remoteField.unique) config.unique = true;\n if (remoteField.foreignKey) {\n config.foreignKey = true;\n if (remoteField.foreignKeyType) config.foreignKeyType = remoteField.foreignKeyType;\n if (remoteField.foreignKeyField) config.foreignKeyField = remoteField.foreignKeyField;\n }\n const allowedValues = remoteField.allowedValues;\n if (allowedValues.length > 0) {\n config.allowedValues = allowedValues.map((v) => ({\n value: v.value,\n ...(v.description && { description: v.description }),\n }));\n }\n\n if (remoteField.description) config.description = remoteField.description;\n if (remoteField.vector) config.vector = true;\n\n if (remoteField.hooks) {\n config.hooks = {};\n if (remoteField.hooks.create?.expr) {\n config.hooks.create = { expr: remoteField.hooks.create.expr };\n }\n if (remoteField.hooks.update?.expr) {\n config.hooks.update = { expr: remoteField.hooks.update.expr };\n }\n }\n\n const validate = remoteField.validate;\n if (validate.length > 0) {\n config.validate = validate.map((v) => ({\n script: { expr: convertRemoteValidateExpression(v.script?.expr ?? \"\", v.action) },\n errorMessage: v.errorMessage ?? \"\",\n }));\n }\n\n if (remoteField.serial) {\n config.serial = {\n start: Number(remoteField.serial.start),\n ...(remoteField.serial.maxValue && { maxValue: Number(remoteField.serial.maxValue) }),\n ...(remoteField.serial.format && { format: remoteField.serial.format }),\n };\n }\n\n if (remoteField.scale !== undefined) config.scale = remoteField.scale;\n\n const nestedFields = remoteField.fields;\n if (Object.keys(nestedFields).length > 0) {\n config.fields = createSnapshotRecord<SnapshotFieldConfig>();\n for (const [fieldName, nestedField] of Object.entries(nestedFields)) {\n config.fields[fieldName] = convertRemoteFieldToSnapshot(nestedField);\n }\n }\n\n return config;\n}\n\n/**\n * Convert remote ParsedTailorDBType to SnapshotFieldConfig for comparison\n * @param {ProtoTailorDBType} remoteType - Remote TailorDB type from API\n * @returns {Record<string, SnapshotFieldConfig>} Converted field configs\n */\nfunction convertRemoteFieldsToSnapshot(\n remoteType: ProtoTailorDBType,\n): Record<string, SnapshotFieldConfig> {\n const fields = createSnapshotRecord<SnapshotFieldConfig>();\n const remoteFields = remoteType.schema?.fields ?? {};\n\n for (const [fieldName, remoteField] of Object.entries(remoteFields)) {\n fields[fieldName] = convertRemoteFieldToSnapshot(remoteField);\n }\n\n return fields;\n}\n\nfunction convertRemoteValidateExpression(expr: string, action: TailorDBType_PermitAction): string {\n return action === TailorDBType_PermitAction.DENY && expr.startsWith(\"!\") ? expr.slice(1) : expr;\n}\n\nfunction convertRemoteSettingsToSnapshot(\n remoteSettings: NonNullable<ProtoTailorDBType[\"schema\"]>[\"settings\"] | undefined,\n expectedSettings?: TailorDBSnapshotType[\"settings\"],\n): TailorDBSnapshotType[\"settings\"] | undefined {\n const settings: SnapshotSettings = {};\n\n if (remoteSettings?.aggregation) settings.aggregation = true;\n if (remoteSettings?.bulkUpsert) settings.bulkUpsert = true;\n if (remoteSettings?.publishRecordEvents) settings.publishEvents = true;\n\n const disabled = remoteSettings?.disableGqlOperations;\n if (disabled) {\n const hasDisabledOperation =\n disabled.create || disabled.update || disabled.delete || disabled.read;\n if (expectedSettings?.gqlOperations !== undefined || hasDisabledOperation) {\n settings.gqlOperations = {\n create: !disabled.create,\n update: !disabled.update,\n delete: !disabled.delete,\n read: !disabled.read,\n };\n }\n }\n\n return Object.keys(settings).length > 0 ? settings : undefined;\n}\n\nfunction convertRemoteIndexesToSnapshot(\n remoteIndexes: NonNullable<ProtoTailorDBType[\"schema\"]>[\"indexes\"] | undefined,\n): Record<string, SnapshotIndexConfig> | undefined {\n const indexes = createSnapshotRecord<SnapshotIndexConfig>();\n for (const [indexName, indexConfig] of Object.entries(remoteIndexes ?? {})) {\n indexes[indexName] = {\n fields: indexConfig.fieldNames,\n ...(indexConfig.unique && { unique: true }),\n };\n }\n return Object.keys(indexes).length > 0 ? indexes : undefined;\n}\n\nfunction convertRemoteFilesToSnapshot(\n remoteFiles: NonNullable<ProtoTailorDBType[\"schema\"]>[\"files\"] | undefined,\n): Record<string, string> | undefined {\n const files = createSnapshotRecord<string>();\n for (const [fileName, fileConfig] of Object.entries(remoteFiles ?? {})) {\n files[fileName] = fileConfig.description || \"\";\n }\n return Object.keys(files).length > 0 ? files : undefined;\n}\n\nfunction convertRemoteRelationshipToSnapshot(\n relationship: RemoteRelationshipConfig,\n direction: \"forward\" | \"backward\",\n): SnapshotRelationship {\n return direction === \"forward\"\n ? {\n targetType: relationship.refType,\n targetField: relationship.srcField,\n sourceField: relationship.refField,\n isArray: relationship.array,\n description: relationship.description || \"\",\n }\n : {\n targetType: relationship.refType,\n targetField: relationship.refField,\n sourceField: relationship.srcField,\n isArray: relationship.array,\n description: relationship.description || \"\",\n };\n}\n\nfunction remoteRelationshipMatchesExpectedDirection(\n relationship: RemoteRelationshipConfig,\n expected: SnapshotRelationship,\n direction: \"forward\" | \"backward\",\n): boolean {\n const converted = convertRemoteRelationshipToSnapshot(relationship, direction);\n return (\n converted.targetType === expected.targetType &&\n converted.targetField === expected.targetField &&\n converted.sourceField === expected.sourceField &&\n converted.isArray === expected.isArray\n );\n}\n\nfunction inferRemoteRelationshipDirection(\n relationshipName: string,\n relationship: RemoteRelationshipConfig,\n expectedType: TailorDBSnapshotType | undefined,\n): \"forward\" | \"backward\" {\n const expectedForward = expectedType?.forwardRelationships?.[relationshipName];\n const expectedBackward = expectedType?.backwardRelationships?.[relationshipName];\n\n if (expectedForward && !expectedBackward) return \"forward\";\n if (expectedBackward && !expectedForward) return \"backward\";\n if (\n expectedForward &&\n remoteRelationshipMatchesExpectedDirection(relationship, expectedForward, \"forward\")\n ) {\n return \"forward\";\n }\n if (\n expectedBackward &&\n remoteRelationshipMatchesExpectedDirection(relationship, expectedBackward, \"backward\")\n ) {\n return \"backward\";\n }\n\n return relationship.array ? \"backward\" : \"forward\";\n}\n\nfunction convertRemoteRelationshipsToSnapshot(\n remoteRelationships: NonNullable<ProtoTailorDBType[\"schema\"]>[\"relationships\"] | undefined,\n expectedType?: TailorDBSnapshotType,\n): Pick<TailorDBSnapshotType, \"forwardRelationships\" | \"backwardRelationships\"> {\n const forwardRelationships = createSnapshotRecord<SnapshotRelationship>();\n const backwardRelationships = createSnapshotRecord<SnapshotRelationship>();\n\n for (const [relationshipName, relationship] of Object.entries(remoteRelationships ?? {})) {\n const direction = inferRemoteRelationshipDirection(\n relationshipName,\n relationship,\n expectedType,\n );\n if (direction === \"forward\") {\n forwardRelationships[relationshipName] = convertRemoteRelationshipToSnapshot(\n relationship,\n direction,\n );\n } else {\n backwardRelationships[relationshipName] = convertRemoteRelationshipToSnapshot(\n relationship,\n direction,\n );\n }\n }\n\n return {\n ...(Object.keys(forwardRelationships).length > 0 && { forwardRelationships }),\n ...(Object.keys(backwardRelationships).length > 0 && { backwardRelationships }),\n };\n}\n\ntype RemoteRecordPolicy = NonNullable<TailorDBType_Permission>[\"create\"][number];\n\ntype RemotePermissionPermit = TailorDBType_Permission_Permit | TailorDBGQLPermission_Permit;\ntype RemotePermissionOperator = TailorDBType_Permission_Operator | TailorDBGQLPermission_Operator;\ntype PermissionSource = \"record\" | \"GQL\";\n\n// TailorDBType_Permission_Permit and TailorDBGQLPermission_Permit share identical numeric values.\nconst REMOTE_PERMISSION_PERMITS = new Map<number, \"allow\" | \"deny\">([\n [TailorDBType_Permission_Permit.ALLOW, \"allow\"],\n [TailorDBType_Permission_Permit.DENY, \"deny\"],\n]);\n\n// TailorDBType_Permission_Operator and TailorDBGQLPermission_Operator share identical numeric values.\nconst REMOTE_PERMISSION_OPERATORS = new Map<number, SnapshotPermissionOperator>([\n [TailorDBType_Permission_Operator.EQ, \"eq\"],\n [TailorDBType_Permission_Operator.NE, \"ne\"],\n [TailorDBType_Permission_Operator.IN, \"in\"],\n [TailorDBType_Permission_Operator.NIN, \"nin\"],\n [TailorDBType_Permission_Operator.HAS_ANY, \"hasAny\"],\n [TailorDBType_Permission_Operator.NHAS_ANY, \"nhasAny\"],\n]);\n\nfunction convertRemotePermit(\n permit: RemotePermissionPermit,\n source: PermissionSource,\n): \"allow\" | \"deny\" {\n const converted = REMOTE_PERMISSION_PERMITS.get(permit);\n if (converted) return converted;\n throw new Error(`Unsupported ${source} permission permit: ${permit}`);\n}\n\nfunction convertRemoteOperator(\n operator: RemotePermissionOperator,\n source: PermissionSource,\n): SnapshotPermissionOperator {\n const converted = REMOTE_PERMISSION_OPERATORS.get(operator);\n if (converted) return converted;\n throw new Error(`Unsupported ${source} permission operator: ${operator}`);\n}\n\nfunction convertRemoteValueOperand(\n operand: TailorDBType_Permission_Operand | TailorDBGQLPermission_Operand | undefined,\n): SnapshotPermissionOperand {\n switch (operand?.kind.case) {\n case \"userField\":\n return { user: operand.kind.value };\n case \"recordField\":\n return { record: operand.kind.value };\n case \"oldRecordField\":\n return { oldRecord: operand.kind.value };\n case \"newRecordField\":\n return { newRecord: operand.kind.value };\n case \"value\":\n return toJson(ValueSchema, operand.kind.value) as SnapshotPermissionOperand;\n default:\n throw new Error(\"Unsupported permission operand\");\n }\n}\n\nfunction convertRemoteRecordCondition(\n condition: TailorDBType_Permission_Condition,\n): SnapshotPermissionCondition {\n return [\n convertRemoteValueOperand(condition.left),\n convertRemoteOperator(condition.operator, \"record\"),\n convertRemoteValueOperand(condition.right),\n ];\n}\n\nfunction convertRemoteGqlCondition(\n condition: TailorDBGQLPermission_Condition,\n): SnapshotPermissionCondition {\n return [\n convertRemoteValueOperand(condition.left),\n convertRemoteOperator(condition.operator, \"GQL\"),\n convertRemoteValueOperand(condition.right),\n ];\n}\n\nfunction convertRemoteRecordPolicy(policy: RemoteRecordPolicy): SnapshotActionPermission {\n return {\n conditions: policy.conditions.map(convertRemoteRecordCondition),\n permit: convertRemotePermit(policy.permit, \"record\"),\n ...(policy.description && { description: policy.description }),\n };\n}\n\nfunction convertRemoteRecordPermissionToSnapshot(\n permission: TailorDBType_Permission | undefined,\n): SnapshotRecordPermission | undefined {\n const recordPermission: SnapshotRecordPermission = {\n create: permission?.create.map(convertRemoteRecordPolicy) ?? [],\n read: permission?.read.map(convertRemoteRecordPolicy) ?? [],\n update: permission?.update.map(convertRemoteRecordPolicy) ?? [],\n delete: permission?.delete.map(convertRemoteRecordPolicy) ?? [],\n };\n\n return Object.values(recordPermission).some((policies) => policies.length > 0)\n ? recordPermission\n : undefined;\n}\n\nfunction convertRemoteGqlAction(action: TailorDBGQLPermission_Action): SnapshotGqlAction {\n switch (action) {\n case TailorDBGQLPermission_Action.ALL:\n return \"all\";\n case TailorDBGQLPermission_Action.CREATE:\n return \"create\";\n case TailorDBGQLPermission_Action.READ:\n return \"read\";\n case TailorDBGQLPermission_Action.UPDATE:\n return \"update\";\n case TailorDBGQLPermission_Action.DELETE:\n return \"delete\";\n case TailorDBGQLPermission_Action.AGGREGATE:\n return \"aggregate\";\n case TailorDBGQLPermission_Action.BULK_UPSERT:\n return \"bulkUpsert\";\n default:\n throw new Error(`Unsupported GQL permission action: ${action}`);\n }\n}\n\nfunction convertRemoteGqlPermissionToSnapshot(\n permission: TailorDBGQLPermission | undefined,\n): SnapshotGqlPermission | undefined {\n const policies =\n permission?.policies.map((policy) => ({\n conditions: policy.conditions.map(convertRemoteGqlCondition),\n actions: policy.actions.map(convertRemoteGqlAction),\n permit: convertRemotePermit(policy.permit, \"GQL\"),\n ...(policy.description && { description: policy.description }),\n })) ?? [];\n\n return policies.length > 0 ? policies : undefined;\n}\n\nfunction convertRemoteTypeToSnapshot(\n remoteType: ProtoTailorDBType,\n expectedType?: TailorDBSnapshotType,\n): TailorDBSnapshotType {\n const settings = convertRemoteSettingsToSnapshot(\n remoteType.schema?.settings,\n expectedType?.settings,\n );\n const relationships = convertRemoteRelationshipsToSnapshot(\n remoteType.schema?.relationships,\n expectedType,\n );\n const recordPermission = convertRemoteRecordPermissionToSnapshot(remoteType.schema?.permission);\n const snapshotType: TailorDBSnapshotType = {\n name: remoteType.name,\n pluralForm: remoteType.schema?.settings?.pluralForm || inflection.pluralize(remoteType.name),\n fields: convertRemoteFieldsToSnapshot(remoteType),\n ...(settings && { settings }),\n ...relationships,\n };\n\n if (remoteType.schema?.description) {\n snapshotType.description = remoteType.schema.description;\n }\n const indexes = convertRemoteIndexesToSnapshot(remoteType.schema?.indexes);\n if (indexes) snapshotType.indexes = indexes;\n\n const files = convertRemoteFilesToSnapshot(remoteType.schema?.files);\n if (files) snapshotType.files = files;\n\n if (recordPermission) {\n snapshotType.permissions = { record: recordPermission };\n }\n\n return snapshotType;\n}\n\n/**\n * Convert remote TailorDB types into the normalized snapshot shape used by drift checks.\n * @param {ProtoTailorDBType[]} remoteTypes - Remote TailorDB types from the API\n * @param {string} namespace - Namespace for the reconstructed snapshot\n * @param {readonly RemoteGqlPermission[]} remoteGqlPermissions - Remote GQL permissions for the namespace\n * @param {SchemaSnapshot} expectedSnapshot - Optional snapshot used to disambiguate remote relationship direction\n * @returns {NormalizedSchemaSnapshot} Normalized snapshot-shaped remote state\n */\nexport function createSnapshotFromRemoteTypes(\n remoteTypes: ProtoTailorDBType[],\n namespace: string,\n remoteGqlPermissions: readonly RemoteGqlPermission[] = [],\n expectedSnapshot?: SchemaSnapshot,\n): NormalizedSchemaSnapshot {\n const types = createSnapshotRecord<TailorDBSnapshotType>();\n for (const remoteType of remoteTypes) {\n types[remoteType.name] = convertRemoteTypeToSnapshot(\n remoteType,\n expectedSnapshot?.types[remoteType.name],\n );\n }\n\n for (const permission of remoteGqlPermissions) {\n const { typeName } = permission;\n const snapshotType = types[typeName];\n if (!snapshotType) continue;\n\n const gqlPermission = convertRemoteGqlPermissionToSnapshot(permission.permission);\n if (!gqlPermission) continue;\n\n snapshotType.permissions = {\n ...snapshotType.permissions,\n gql: gqlPermission,\n };\n }\n\n return normalizeSchemaSnapshot({\n version: SCHEMA_SNAPSHOT_VERSION,\n namespace,\n createdAt: new Date().toISOString(),\n types,\n });\n}\n\nfunction fieldDifferenceValue(value: unknown): string {\n if (value === undefined || value === \"\") return \"none\";\n return String(value);\n}\n\nfunction fieldDifferenceKey(prefix: string, key: string): string {\n return prefix ? `${prefix}.${key}` : key;\n}\n\nfunction addFieldDifference(\n differences: string[],\n prefix: string,\n key: string,\n remoteValue: unknown,\n snapshotValue: unknown,\n): void {\n if (remoteValue === snapshotValue) return;\n differences.push(\n `${fieldDifferenceKey(prefix, key)}: remote=${fieldDifferenceValue(\n remoteValue,\n )}, expected=${fieldDifferenceValue(snapshotValue)}`,\n );\n}\n\nfunction addBooleanFieldDifference(\n differences: string[],\n prefix: string,\n key: keyof SnapshotFieldConfig,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n addFieldDifference(\n differences,\n prefix,\n key,\n remoteField[key] ?? false,\n snapshotField[key] ?? false,\n );\n}\n\nfunction addAllowedValuesDifferences(\n differences: string[],\n prefix: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n const remoteAllowed = remoteField.allowedValues ?? [];\n const snapshotAllowed = snapshotField.allowedValues ?? [];\n if (remoteAllowed.length !== snapshotAllowed.length) {\n differences.push(\n `${fieldDifferenceKey(prefix, \"allowedValues\")} count: remote=${remoteAllowed.length}, expected=${snapshotAllowed.length}`,\n );\n return;\n }\n\n const snapshotAllowedValues = new Map(snapshotAllowed.map((v) => [v.value, v.description]));\n for (const value of remoteAllowed) {\n if (!snapshotAllowedValues.has(value.value)) {\n differences.push(\n `${fieldDifferenceKey(prefix, \"allowedValues\")}: remote has '${value.value}' not in snapshot`,\n );\n return;\n }\n const snapshotDescription = snapshotAllowedValues.get(value.value);\n if ((value.description ?? \"\") !== (snapshotDescription ?? \"\")) {\n addFieldDifference(\n differences,\n prefix,\n `allowedValues.${value.value}.description`,\n value.description ?? \"\",\n snapshotDescription ?? \"\",\n );\n return;\n }\n }\n\n const remoteAllowedValues = new Set(remoteAllowed.map((v) => v.value));\n for (const value of snapshotAllowed) {\n if (!remoteAllowedValues.has(value.value)) {\n differences.push(\n `${fieldDifferenceKey(prefix, \"allowedValues\")}: snapshot has '${value.value}' not in remote`,\n );\n return;\n }\n }\n}\n\nfunction addHooksDifferences(\n differences: string[],\n prefix: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n addFieldDifference(\n differences,\n prefix,\n \"hooks.create\",\n remoteField.hooks?.create?.expr ?? \"\",\n snapshotField.hooks?.create?.expr ?? \"\",\n );\n addFieldDifference(\n differences,\n prefix,\n \"hooks.update\",\n remoteField.hooks?.update?.expr ?? \"\",\n snapshotField.hooks?.update?.expr ?? \"\",\n );\n}\n\nfunction addValidationDifferences(\n differences: string[],\n prefix: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n const remoteValidate = remoteField.validate ?? [];\n const snapshotValidate = snapshotField.validate ?? [];\n if (remoteValidate.length !== snapshotValidate.length) {\n differences.push(\n `${fieldDifferenceKey(prefix, \"validate\")} count: remote=${remoteValidate.length}, expected=${snapshotValidate.length}`,\n );\n }\n\n const commonLength = Math.min(remoteValidate.length, snapshotValidate.length);\n for (let index = 0; index < commonLength; index++) {\n const remoteValidation = assertDefined(\n remoteValidate[index],\n `remoteValidate missing index ${index}`,\n );\n const snapshotValidation = assertDefined(\n snapshotValidate[index],\n `snapshotValidate missing index ${index}`,\n );\n addFieldDifference(\n differences,\n prefix,\n `validate[${index}].script`,\n remoteValidation.script?.expr ?? \"\",\n snapshotValidation.script?.expr ?? \"\",\n );\n addFieldDifference(\n differences,\n prefix,\n `validate[${index}].errorMessage`,\n remoteValidation.errorMessage,\n snapshotValidation.errorMessage,\n );\n }\n}\n\nfunction addSerialDifferences(\n differences: string[],\n prefix: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n addFieldDifference(\n differences,\n prefix,\n \"serial.start\",\n remoteField.serial?.start,\n snapshotField.serial?.start,\n );\n addFieldDifference(\n differences,\n prefix,\n \"serial.maxValue\",\n remoteField.serial?.maxValue,\n snapshotField.serial?.maxValue,\n );\n addFieldDifference(\n differences,\n prefix,\n \"serial.format\",\n remoteField.serial?.format ?? \"\",\n snapshotField.serial?.format ?? \"\",\n );\n}\n\nfunction addNestedFieldDifferences(\n differences: string[],\n prefix: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n const remoteFields = remoteField.fields ?? {};\n const snapshotFields = snapshotField.fields ?? {};\n const remoteFieldNames = Object.keys(remoteFields);\n const snapshotFieldNames = Object.keys(snapshotFields);\n\n if (remoteFieldNames.length !== snapshotFieldNames.length) {\n differences.push(\n `${fieldDifferenceKey(prefix, \"fields\")} count: remote=${remoteFieldNames.length}, expected=${snapshotFieldNames.length}`,\n );\n }\n\n for (const fieldName of remoteFieldNames) {\n const remoteNestedField = remoteFields[fieldName];\n const snapshotNestedField = snapshotFields[fieldName];\n const nestedPrefix = fieldDifferenceKey(prefix, `fields.${fieldName}`);\n if (!snapshotNestedField) {\n differences.push(`${nestedPrefix}: exists in remote but not snapshot`);\n continue;\n }\n addFieldDifferences(\n differences,\n nestedPrefix,\n assertDefined(remoteNestedField, `remote field \"${fieldName}\" missing`),\n snapshotNestedField,\n );\n }\n\n for (const fieldName of snapshotFieldNames) {\n if (remoteFields[fieldName]) continue;\n differences.push(\n `${fieldDifferenceKey(prefix, `fields.${fieldName}`)}: exists in snapshot but not remote`,\n );\n }\n}\n\nfunction addFieldDifferences(\n differences: string[],\n prefix: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): void {\n addFieldDifference(differences, prefix, \"type\", remoteField.type, snapshotField.type);\n addFieldDifference(differences, prefix, \"required\", remoteField.required, snapshotField.required);\n\n for (const key of [\"array\", \"index\", \"unique\", \"foreignKey\", \"vector\"] as const) {\n addBooleanFieldDifference(differences, prefix, key, remoteField, snapshotField);\n }\n\n addFieldDifference(\n differences,\n prefix,\n \"foreignKeyType\",\n remoteField.foreignKeyType,\n snapshotField.foreignKeyType,\n );\n addFieldDifference(\n differences,\n prefix,\n \"foreignKeyField\",\n remoteField.foreignKeyField,\n snapshotField.foreignKeyField,\n );\n addFieldDifference(\n differences,\n prefix,\n \"description\",\n remoteField.description ?? \"\",\n snapshotField.description ?? \"\",\n );\n addAllowedValuesDifferences(differences, prefix, remoteField, snapshotField);\n addHooksDifferences(differences, prefix, remoteField, snapshotField);\n addValidationDifferences(differences, prefix, remoteField, snapshotField);\n addSerialDifferences(differences, prefix, remoteField, snapshotField);\n addFieldDifference(differences, prefix, \"scale\", remoteField.scale, snapshotField.scale);\n addNestedFieldDifferences(differences, prefix, remoteField, snapshotField);\n}\n\n/**\n * Compare a single field between remote and snapshot\n * @param {string} typeName - Name of the type\n * @param {string} fieldName - Name of the field\n * @param {SnapshotFieldConfig} remoteField - Remote field config\n * @param {SnapshotFieldConfig} snapshotField - Snapshot field config\n * @returns {SchemaDrift | null} Drift info or null if fields match\n */\nfunction compareFields(\n typeName: string,\n fieldName: string,\n remoteField: SnapshotFieldConfig,\n snapshotField: SnapshotFieldConfig,\n): SchemaDrift | null {\n const differences: string[] = [];\n addFieldDifferences(differences, \"\", remoteField, snapshotField);\n\n if (differences.length > 0) {\n return {\n typeName,\n kind: \"field_mismatch\",\n fieldName,\n details: differences.join(\"; \"),\n };\n }\n\n return null;\n}\n\n/**\n * System fields that are auto-generated and should be excluded from comparison\n */\nconst SYSTEM_FIELDS = new Set([\"id\"]);\n\n/**\n * Compare remote TailorDB types with a local snapshot\n * @param {ProtoTailorDBType[]} remoteTypes - Remote types from listParsedTailorDBTypes API\n * @param {SchemaSnapshot} snapshot - Local schema snapshot\n * @param {readonly RemoteGqlPermission[]} remoteGqlPermissions - Remote GQL permissions for the namespace\n * @returns {SchemaDrift[]} List of drifts detected\n */\nexport function compareRemoteWithSnapshot(\n remoteTypes: ProtoTailorDBType[],\n snapshot: SchemaSnapshot,\n remoteGqlPermissions: readonly RemoteGqlPermission[] = [],\n): SchemaDrift[] {\n const structuralDrifts = compareNormalizedRemoteWithSnapshot(\n createRemoteComparableSnapshot(\n createSnapshotFromRemoteTypes(\n remoteTypes,\n snapshot.namespace,\n remoteGqlPermissions,\n snapshot,\n ),\n ),\n createRemoteComparableSnapshot(snapshot),\n );\n\n const scriptDrifts = compareScriptHashes(remoteTypes, snapshot);\n\n return [...structuralDrifts, ...scriptDrifts];\n}\n\nfunction extractRemoteScriptHash(remoteType: ProtoTailorDBType): string | undefined {\n const exprs = [\n remoteType.schema?.typeHook?.create?.expr,\n remoteType.schema?.typeHook?.update?.expr,\n remoteType.schema?.typeValidate?.create?.expr,\n remoteType.schema?.typeValidate?.update?.expr,\n ];\n let found: string | undefined;\n for (const expr of exprs) {\n if (expr) {\n const hash = extractSourceScriptHash(expr);\n if (hash) {\n if (found && found !== hash) return undefined;\n found = hash;\n }\n }\n }\n return found;\n}\n\nfunction remoteHasScripts(remoteType: ProtoTailorDBType): boolean {\n return !!(\n remoteType.schema?.typeHook?.create?.expr ||\n remoteType.schema?.typeHook?.update?.expr ||\n remoteType.schema?.typeValidate?.create?.expr ||\n remoteType.schema?.typeValidate?.update?.expr\n );\n}\n\nfunction compareScriptHashes(\n remoteTypes: ProtoTailorDBType[],\n snapshot: SchemaSnapshot,\n): SchemaDrift[] {\n const drifts: SchemaDrift[] = [];\n const remoteByName = new Map(remoteTypes.map((t) => [t.name, t]));\n\n for (const [typeName, snapshotType] of Object.entries(snapshot.types)) {\n const localHash = computeSourceScriptHash(snapshotType.fields, {\n typeHookExpr: snapshotType.typeHookExpr,\n typeValidateExpr: snapshotType.typeValidateExpr,\n });\n\n const remoteType = remoteByName.get(typeName);\n if (!remoteType) continue;\n\n if (localHash) {\n const remoteHash = extractRemoteScriptHash(remoteType);\n if (localHash !== remoteHash) {\n drifts.push({\n typeName,\n kind: \"script_mismatch\",\n details: remoteHash\n ? `Type '${typeName}' scripts differ between remote and snapshot`\n : `Type '${typeName}' has no script hash on remote`,\n });\n }\n } else if (remoteHasScripts(remoteType)) {\n drifts.push({\n typeName,\n kind: \"script_mismatch\",\n details: `Type '${typeName}' has scripts on remote but not in snapshot`,\n });\n }\n }\n\n return drifts;\n}\n\nfunction stripFieldScriptProps(field: SnapshotFieldConfig): SnapshotFieldConfig {\n const { hooks: _hooks, validate: _validate, default: _default, ...rest } = field;\n if (rest.fields) {\n const nested = createSnapshotRecord<SnapshotFieldConfig>();\n for (const [name, f] of Object.entries(rest.fields)) {\n nested[name] = stripFieldScriptProps(f);\n }\n return { ...rest, fields: nested };\n }\n return rest;\n}\n\nfunction createRemoteComparableSnapshot(snapshot: SchemaSnapshot): NormalizedSchemaSnapshot {\n const types = createSnapshotRecord<TailorDBSnapshotType>();\n\n for (const [typeName, type] of Object.entries(snapshot.types)) {\n const fields = createSnapshotRecord<SnapshotFieldConfig>();\n for (const [fieldName, field] of Object.entries(type.fields)) {\n if (SYSTEM_FIELDS.has(fieldName)) continue;\n fields[fieldName] = stripFieldScriptProps(field);\n }\n const { typeHookExpr: _, typeValidateExpr: __, ...typeRest } = type;\n types[typeName] = { ...typeRest, fields };\n }\n\n return normalizeSchemaSnapshot({\n ...snapshot,\n types,\n });\n}\n\nfunction fieldDriftFromChange(\n change: Extract<DiffChange, { kind: \"field_modified\" | \"field_type_modified\" }>,\n): SchemaDrift {\n return (\n compareFields(change.typeName, change.fieldName, change.before, change.after) ?? {\n typeName: change.typeName,\n kind: \"field_mismatch\",\n fieldName: change.fieldName,\n details: `Field '${change.fieldName}' differs between remote and snapshot`,\n }\n );\n}\n\nfunction schemaDriftFromDiffChange(change: DiffChange): SchemaDrift {\n switch (change.kind) {\n case \"type_added\":\n return {\n typeName: change.typeName,\n kind: \"type_missing_remote\",\n details: `Type '${change.typeName}' exists in snapshot but not in remote`,\n };\n case \"type_removed\":\n return {\n typeName: change.typeName,\n kind: \"type_missing_local\",\n details: `Type '${change.typeName}' exists in remote but not in snapshot`,\n };\n case \"type_settings_modified\":\n case \"type_modified\":\n return {\n typeName: change.typeName,\n kind: \"type_settings_mismatch\",\n details: change.reason ?? \"Type settings differ between remote and snapshot\",\n };\n case \"field_added\":\n return {\n typeName: change.typeName,\n kind: \"field_missing_remote\",\n fieldName: change.fieldName,\n details: `Field '${change.fieldName}' exists in snapshot but not in remote`,\n };\n case \"field_removed\":\n return {\n typeName: change.typeName,\n kind: \"field_missing_local\",\n fieldName: change.fieldName,\n details: `Field '${change.fieldName}' exists in remote but not in snapshot`,\n };\n case \"field_modified\":\n case \"field_type_modified\":\n return fieldDriftFromChange(change);\n case \"index_added\":\n return {\n typeName: change.typeName,\n kind: \"index_missing_remote\",\n indexName: change.indexName,\n details: `Index '${change.indexName}' exists in snapshot but not in remote`,\n };\n case \"index_removed\":\n return {\n typeName: change.typeName,\n kind: \"index_missing_local\",\n indexName: change.indexName,\n details: `Index '${change.indexName}' exists in remote but not in snapshot`,\n };\n case \"index_modified\":\n return {\n typeName: change.typeName,\n kind: \"index_mismatch\",\n indexName: change.indexName,\n details: change.reason ?? `Index '${change.indexName}' differs between remote and snapshot`,\n };\n case \"file_added\":\n return {\n typeName: change.typeName,\n kind: \"file_missing_remote\",\n fileName: change.fieldName,\n details: `File '${change.fieldName}' exists in snapshot but not in remote`,\n };\n case \"file_removed\":\n return {\n typeName: change.typeName,\n kind: \"file_missing_local\",\n fileName: change.fieldName,\n details: `File '${change.fieldName}' exists in remote but not in snapshot`,\n };\n case \"file_modified\":\n return {\n typeName: change.typeName,\n kind: \"file_mismatch\",\n fileName: change.fieldName,\n details: change.reason ?? `File '${change.fieldName}' differs between remote and snapshot`,\n };\n case \"relationship_added\":\n return {\n typeName: change.typeName,\n kind: \"relationship_missing_remote\",\n relationshipName: change.relationshipName,\n relationshipType: change.relationshipType,\n details: `Relationship '${change.relationshipName}' exists in snapshot but not in remote`,\n };\n case \"relationship_removed\":\n return {\n typeName: change.typeName,\n kind: \"relationship_missing_local\",\n relationshipName: change.relationshipName,\n relationshipType: change.relationshipType,\n details: `Relationship '${change.relationshipName}' exists in remote but not in snapshot`,\n };\n case \"relationship_modified\":\n return {\n typeName: change.typeName,\n kind: \"relationship_mismatch\",\n relationshipName: change.relationshipName,\n relationshipType: change.relationshipType,\n details:\n change.reason ??\n `Relationship '${change.relationshipName}' differs between remote and snapshot`,\n };\n case \"permission_modified\":\n return {\n typeName: change.typeName,\n kind: \"permission_mismatch\",\n details: change.reason ?? \"Permissions differ between remote and snapshot\",\n };\n case \"type_scripts_modified\":\n return {\n typeName: change.typeName,\n kind: \"script_mismatch\",\n details: change.reason ?? \"Type-level scripts differ between remote and snapshot\",\n };\n default: {\n change satisfies never;\n throw new Error(\"Unsupported diff change\");\n }\n }\n}\n\nfunction compareNormalizedRemoteWithSnapshot(\n remoteSnapshot: NormalizedSchemaSnapshot,\n snapshot: NormalizedSchemaSnapshot,\n): SchemaDrift[] {\n return compareNormalizedSnapshots(remoteSnapshot, snapshot).changes.map(\n schemaDriftFromDiffChange,\n );\n}\n\n/**\n * Format schema drifts for display\n * @param {SchemaDrift[]} drifts - List of drifts to format\n * @returns {string} Formatted drift report\n */\nexport function formatSchemaDrifts(drifts: SchemaDrift[]): string {\n if (drifts.length === 0) {\n return \"No schema drifts detected.\";\n }\n\n const lines: string[] = [];\n\n // Group drifts by type\n const driftsByType = new Map<string, SchemaDrift[]>();\n for (const drift of drifts) {\n const existing = driftsByType.get(drift.typeName) ?? [];\n existing.push(drift);\n driftsByType.set(drift.typeName, existing);\n }\n\n for (const [typeName, typeDrifts] of driftsByType) {\n lines.push(` Type '${typeName}':`);\n for (const drift of typeDrifts) {\n if (drift.fieldName) {\n lines.push(` - Field '${drift.fieldName}': ${drift.details}`);\n } else if (drift.indexName) {\n lines.push(` - Index '${drift.indexName}': ${drift.details}`);\n } else if (drift.fileName) {\n lines.push(` - File '${drift.fileName}': ${drift.details}`);\n } else if (drift.relationshipName) {\n const relationshipType = drift.relationshipType ? ` (${drift.relationshipType})` : \"\";\n lines.push(\n ` - Relationship${relationshipType} '${drift.relationshipName}': ${drift.details}`,\n );\n } else {\n lines.push(` - ${drift.details}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n","import { createHash, type Hash } from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { formatMigrationNumber, getMigrationFilePath, MIGRATION_NUMBER_PATTERN } from \"./snapshot\";\nimport type { NamespaceWithMigrations } from \"./config\";\n\nconst MIGRATION_FILE_KINDS = [\"schema\", \"diff\", \"migrate\", \"db\"] as const;\n\nfunction getMigrationArtifactNumbers(migrationsDir: string): number[] {\n if (!fs.existsSync(migrationsDir)) return [];\n\n return fs\n .readdirSync(migrationsDir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && MIGRATION_NUMBER_PATTERN.test(entry.name))\n .map((entry) => Number.parseInt(entry.name, 10))\n .filter((migrationNumber) =>\n MIGRATION_FILE_KINDS.some((kind) =>\n fs.existsSync(getMigrationFilePath(migrationsDir, migrationNumber, kind)),\n ),\n )\n .toSorted((a, b) => a - b);\n}\n\nfunction updateHashWithDirectory(\n hash: Hash,\n directoryPath: string,\n prefix = \"\",\n activeDirectories = new Set<string>(),\n): void {\n const realDirectoryPath = fs.realpathSync(directoryPath);\n if (activeDirectories.has(realDirectoryPath)) {\n hash.update(`directory-cycle\\0${prefix}\\0${realDirectoryPath}\\0`);\n return;\n }\n activeDirectories.add(realDirectoryPath);\n const entries = fs\n .readdirSync(directoryPath, { withFileTypes: true })\n .toSorted((a, b) => a.name.localeCompare(b.name));\n\n try {\n for (const entry of entries) {\n const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;\n const entryPath = path.join(directoryPath, entry.name);\n if (entry.isDirectory()) {\n hash.update(`directory\\0${relativePath}\\0`);\n updateHashWithDirectory(hash, entryPath, relativePath, activeDirectories);\n } else if (entry.isFile()) {\n hash.update(`file\\0${relativePath}\\0`);\n hash.update(fs.readFileSync(entryPath));\n hash.update(\"\\0\");\n } else if (entry.isSymbolicLink()) {\n hash.update(`symlink\\0${relativePath}\\0${fs.readlinkSync(entryPath)}\\0`);\n try {\n const target = fs.statSync(entryPath);\n if (target.isDirectory()) {\n hash.update(\"target-directory\\0\");\n updateHashWithDirectory(hash, entryPath, `${relativePath}@target`, activeDirectories);\n } else if (target.isFile()) {\n hash.update(\"target-file\\0\");\n hash.update(fs.readFileSync(entryPath));\n hash.update(\"\\0\");\n } else {\n hash.update(\"target-other\\0\");\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n hash.update(\"target-missing\\0\");\n }\n } else {\n hash.update(`other\\0${relativePath}\\0`);\n }\n }\n } finally {\n activeDirectories.delete(realDirectoryPath);\n }\n}\n\n/**\n * Capture an exact set of input files.\n * @param filePaths - Files whose names and contents affect an operation\n * @returns SHA-256 digest of the sorted file set\n */\nexport function captureFileState(filePaths: ReadonlyArray<string>): string {\n const hash = createHash(\"sha256\");\n for (const filePath of [...new Set(filePaths)].toSorted()) {\n hash.update(filePath);\n hash.update(\"\\0\");\n if (fs.existsSync(filePath)) {\n hash.update(fs.readFileSync(filePath));\n } else {\n hash.update(\"<missing>\");\n }\n hash.update(\"\\0\");\n }\n return hash.digest(\"hex\");\n}\n\n/**\n * Capture the migration files that an operation depends on.\n * @param namespacesWithMigrations - Configured migration directories by namespace\n * @returns SHA-256 digest by namespace\n */\nexport function captureMigrationFileState(\n namespacesWithMigrations: ReadonlyArray<NamespaceWithMigrations>,\n): Record<string, string> {\n const state = Object.create(null) as Record<string, string>;\n for (const { namespace, migrationsDir } of namespacesWithMigrations.toSorted((a, b) =>\n a.namespace.localeCompare(b.namespace),\n )) {\n const hash = createHash(\"sha256\");\n const migrationNumbers = getMigrationArtifactNumbers(migrationsDir);\n for (const migrationNumber of migrationNumbers) {\n const migrationDirectoryName = formatMigrationNumber(migrationNumber);\n hash.update(`migration\\0${migrationDirectoryName}\\0`);\n updateHashWithDirectory(hash, path.join(migrationsDir, migrationDirectoryName));\n }\n state[namespace] = hash.digest(\"hex\");\n }\n return state;\n}\n","/**\n * Snapshot-based Proto manifest generation for TailorDB migrations\n *\n * This module provides utilities for generating TailorDB proto manifests\n * directly from schema snapshots, enabling migration-based deployments\n * without relying on local TypeScript definitions.\n */\n\nimport { fromJson, type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport {\n TailorDBGQLPermission_Action,\n TailorDBGQLPermission_Operator,\n TailorDBGQLPermission_Permit,\n type TailorDBGQLPermission_ConditionSchema,\n type TailorDBGQLPermission_OperandSchema,\n type TailorDBGQLPermission_PolicySchema,\n type TailorDBGQLPermissionSchema,\n TailorDBType_Permission_Operator,\n TailorDBType_Permission_Permit,\n type TailorDBType_FieldConfigSchema,\n type TailorDBType_FileConfigSchema,\n type TailorDBType_IndexSchema,\n type TailorDBType_Permission_ConditionSchema,\n type TailorDBType_Permission_OperandSchema,\n type TailorDBType_Permission_PolicySchema,\n type TailorDBType_PermissionSchema,\n type TailorDBType_RelationshipConfigSchema,\n type TailorDBTypeSchema,\n} from \"@tailor-platform/tailor-proto/tailordb_resource_pb\";\nimport * as inflection from \"inflection\";\nimport { publishEventsConflict, resolvePublishEvents } from \"#/cli/shared/publish-events\";\nimport { buildTypeScripts } from \"#/parser/service/tailordb/type-script\";\nimport { isSnapshotFieldRefOperand } from \"./snapshot\";\nimport type {\n SchemaSnapshot,\n SnapshotEnumValue,\n SnapshotFieldConfig,\n TailorDBSnapshotType,\n SnapshotRelationship,\n SnapshotRecordPermission,\n SnapshotActionPermission,\n SnapshotGqlPermission,\n SnapshotGqlPermissionPolicy,\n SnapshotPermissionCondition,\n SnapshotPermissionOperand,\n SnapshotIndexConfig,\n} from \"./snapshot\";\n\n/**\n * Options for generating TailorDB type manifest from snapshot\n */\nexport interface GenerateManifestOptions {\n /** Whether an executor taking part in the same run subscribes to its record events */\n subscribed?: boolean;\n /** Default gqlOperations for the namespace */\n namespaceGqlOperations?: {\n create?: boolean;\n update?: boolean;\n delete?: boolean;\n read?: boolean;\n };\n}\n\n/**\n * Generate a TailorDB type manifest from a snapshot type\n * @param {TailorDBSnapshotType} snapshotType - Snapshot type to generate manifest from\n * @param {GenerateManifestOptions} options - Generation options\n * @returns {MessageInitShape<typeof TailorDBTypeSchema>} Type manifest\n */\nexport function generateTailorDBTypeManifestFromSnapshot(\n snapshotType: TailorDBSnapshotType,\n options: GenerateManifestOptions = {},\n): MessageInitShape<typeof TailorDBTypeSchema> {\n const pluralForm = inflection.camelize(snapshotType.pluralForm, true);\n\n // Build settings\n const defaultSettings: {\n aggregation: boolean;\n bulkUpsert: boolean;\n draft: boolean;\n defaultQueryLimitSize: bigint;\n maxBulkUpsertSize: bigint;\n pluralForm: string;\n publishRecordEvents: boolean;\n disableGqlOperations?: {\n create: boolean;\n update: boolean;\n delete: boolean;\n read: boolean;\n };\n } = {\n aggregation: snapshotType.settings?.aggregation ?? false,\n bulkUpsert: snapshotType.settings?.bulkUpsert ?? false,\n draft: false,\n defaultQueryLimitSize: 100n,\n maxBulkUpsertSize: 1000n,\n pluralForm,\n publishRecordEvents: resolvePublishEvents({\n explicit: snapshotType.settings?.publishEvents,\n subscribed: options.subscribed ?? false,\n conflict: publishEventsConflict.tailorDBType(snapshotType.name),\n }),\n };\n\n // Apply gqlOperations from snapshot settings or namespace default\n const ops = snapshotType.settings?.gqlOperations ?? options.namespaceGqlOperations;\n if (ops) {\n defaultSettings.disableGqlOperations = {\n create: ops.create === false,\n update: ops.update === false,\n delete: ops.delete === false,\n read: ops.read === false,\n };\n }\n\n // Build fields\n const fields: Record<\n string,\n MessageInitShape<typeof TailorDBType_FieldConfigSchema>\n > = Object.fromEntries(\n Object.entries(snapshotType.fields)\n .filter(([fieldName]) => fieldName !== \"id\")\n .map(([fieldName, fieldConfig]) => [fieldName, convertFieldConfigToProto(fieldConfig)]),\n );\n\n // Build relationships\n const relationships: Record<\n string,\n MessageInitShape<typeof TailorDBType_RelationshipConfigSchema>\n > = {};\n\n if (snapshotType.forwardRelationships) {\n for (const [relationName, rel] of Object.entries(snapshotType.forwardRelationships)) {\n relationships[relationName] = convertRelationshipToProto(rel, \"forward\");\n }\n }\n\n if (snapshotType.backwardRelationships) {\n for (const [relationName, rel] of Object.entries(snapshotType.backwardRelationships)) {\n relationships[relationName] = convertRelationshipToProto(rel, \"backward\");\n }\n }\n\n // Build indexes\n const indexes: Record<string, MessageInitShape<typeof TailorDBType_IndexSchema>> = {};\n if (snapshotType.indexes) {\n for (const [indexName, indexConfig] of Object.entries(snapshotType.indexes)) {\n indexes[indexName] = convertIndexToProto(indexConfig);\n }\n }\n\n // Build files\n const files: Record<string, MessageInitShape<typeof TailorDBType_FileConfigSchema>> = {};\n if (snapshotType.files) {\n for (const [fileName, description] of Object.entries(snapshotType.files)) {\n files[fileName] = { description: description || \"\" };\n }\n }\n\n // Build permission\n const defaultPermission: MessageInitShape<typeof TailorDBType_PermissionSchema> = {\n create: [],\n read: [],\n update: [],\n delete: [],\n };\n const permission = snapshotType.permissions?.record\n ? convertRecordPermissionToProto(snapshotType.permissions.record)\n : defaultPermission;\n\n // Field hooks/validators are aggregated into type-level scripts so that a\n // single shared timestamp is observed across every field in one operation.\n const { typeHook, typeValidate } = buildTypeScripts(snapshotType.fields, {\n typeHookExpr: snapshotType.typeHookExpr,\n typeValidateExpr: snapshotType.typeValidateExpr,\n });\n\n return {\n name: snapshotType.name,\n schema: {\n description: snapshotType.description || \"\",\n fields,\n relationships,\n settings: defaultSettings,\n extends: false,\n directives: [],\n indexes,\n files,\n permission,\n ...(typeHook && { typeHook }),\n ...(typeValidate && { typeValidate }),\n },\n };\n}\n\nfunction optionalOnCreate(\n config: Pick<SnapshotFieldConfig, \"hooks\" | \"default\">,\n): Pick<MessageInitShape<typeof TailorDBType_FieldConfigSchema>, \"optionalOnCreate\"> {\n return config.hooks?.create || config.default !== undefined ? { optionalOnCreate: true } : {};\n}\n\n/**\n * Convert a snapshot field config to proto format\n * @param {SnapshotFieldConfig} config - Snapshot field config\n * @returns {MessageInitShape<typeof TailorDBType_FieldConfigSchema>} Proto field config\n */\nexport function convertFieldConfigToProto(\n config: SnapshotFieldConfig,\n): MessageInitShape<typeof TailorDBType_FieldConfigSchema> {\n const fieldEntry: MessageInitShape<typeof TailorDBType_FieldConfigSchema> = {\n type: config.type,\n allowedValues:\n config.type === \"enum\"\n ? (config.allowedValues?.map((v: SnapshotEnumValue) => ({ ...v })) ?? [])\n : [],\n description: config.description || \"\",\n array: config.array ?? false,\n index: config.index ?? false,\n unique: config.unique ?? false,\n foreignKey: config.foreignKey ?? false,\n foreignKeyType: config.foreignKeyType,\n foreignKeyField: config.foreignKeyField,\n required: config.required,\n vector: config.vector ?? false,\n ...optionalOnCreate(config),\n ...(config.serial && {\n serial: {\n start: BigInt(config.serial.start),\n ...(config.serial.maxValue !== undefined && {\n maxValue: BigInt(config.serial.maxValue),\n }),\n ...(config.serial.format && {\n format: config.serial.format,\n }),\n },\n }),\n ...(config.scale !== undefined && { scale: config.scale }),\n };\n\n // Handle nested fields\n if (config.type === \"nested\" && config.fields) {\n fieldEntry.fields = processNestedFieldsFromSnapshot(config.fields);\n }\n\n return fieldEntry;\n}\n\n/**\n * Process nested fields from snapshot format to proto format\n * @param {Record<string, SnapshotFieldConfig>} fields - Nested fields\n * @returns {Record<string, MessageInitShape<typeof TailorDBType_FieldConfigSchema>>} Proto nested fields\n */\nfunction processNestedFieldsFromSnapshot(\n fields: Record<string, SnapshotFieldConfig>,\n): Record<string, MessageInitShape<typeof TailorDBType_FieldConfigSchema>> {\n const nestedFields: Record<string, MessageInitShape<typeof TailorDBType_FieldConfigSchema>> = {};\n\n for (const [fieldName, fieldConfig] of Object.entries(fields)) {\n if (fieldConfig.type === \"nested\" && fieldConfig.fields) {\n const deepNestedFields = processNestedFieldsFromSnapshot(fieldConfig.fields);\n nestedFields[fieldName] = {\n type: \"nested\",\n allowedValues: fieldConfig.allowedValues?.map((v: SnapshotEnumValue) => ({ ...v })) ?? [],\n description: fieldConfig.description || \"\",\n required: fieldConfig.required,\n array: fieldConfig.array ?? false,\n index: false,\n unique: false,\n foreignKey: false,\n vector: false,\n fields: deepNestedFields,\n ...(fieldConfig.scale !== undefined && { scale: fieldConfig.scale }),\n };\n } else {\n nestedFields[fieldName] = {\n type: fieldConfig.type,\n allowedValues:\n fieldConfig.type === \"enum\"\n ? (fieldConfig.allowedValues?.map((v: SnapshotEnumValue) => ({ ...v })) ?? [])\n : [],\n description: fieldConfig.description || \"\",\n required: fieldConfig.required,\n array: fieldConfig.array ?? false,\n index: false,\n unique: false,\n foreignKey: false,\n vector: false,\n ...optionalOnCreate(fieldConfig),\n ...(fieldConfig.serial && {\n serial: {\n start: BigInt(fieldConfig.serial.start),\n ...(fieldConfig.serial.maxValue !== undefined && {\n maxValue: BigInt(fieldConfig.serial.maxValue),\n }),\n ...(fieldConfig.serial.format && {\n format: fieldConfig.serial.format,\n }),\n },\n }),\n ...(fieldConfig.scale !== undefined && { scale: fieldConfig.scale }),\n };\n }\n }\n\n return nestedFields;\n}\n\n/**\n * Convert a snapshot relationship to proto format\n * @param {SnapshotRelationship} rel - Snapshot relationship\n * @param {\"forward\" | \"backward\"} direction - Relationship direction\n * @returns {MessageInitShape<typeof TailorDBType_RelationshipConfigSchema>} Proto relationship config\n */\nfunction convertRelationshipToProto(\n rel: SnapshotRelationship,\n direction: \"forward\" | \"backward\",\n): MessageInitShape<typeof TailorDBType_RelationshipConfigSchema> {\n if (direction === \"forward\") {\n return {\n refType: rel.targetType,\n refField: rel.sourceField,\n srcField: rel.targetField,\n array: rel.isArray,\n description: rel.description,\n };\n }\n // backward\n return {\n refType: rel.targetType,\n refField: rel.targetField,\n srcField: rel.sourceField,\n array: rel.isArray,\n description: rel.description,\n };\n}\n\n/**\n * Convert a snapshot index config to proto format\n * @param {SnapshotIndexConfig} indexConfig - Snapshot index config\n * @returns {MessageInitShape<typeof TailorDBType_IndexSchema>} Proto index config\n */\nexport function convertIndexToProto(\n indexConfig: SnapshotIndexConfig,\n): MessageInitShape<typeof TailorDBType_IndexSchema> {\n return {\n fieldNames: indexConfig.fields,\n unique: indexConfig.unique ?? false,\n };\n}\n\n/**\n * Convert a snapshot record permission to proto format\n * @param {SnapshotRecordPermission} permission - Snapshot record permission\n * @returns {MessageInitShape<typeof TailorDBType_PermissionSchema>} Proto permission\n */\nfunction convertRecordPermissionToProto(\n permission: SnapshotRecordPermission,\n): MessageInitShape<typeof TailorDBType_PermissionSchema> {\n return {\n create: permission.create.map(convertActionPermissionToProto),\n read: permission.read.map(convertActionPermissionToProto),\n update: permission.update.map(convertActionPermissionToProto),\n delete: permission.delete.map(convertActionPermissionToProto),\n };\n}\n\n/**\n * Convert a snapshot action permission to proto format\n * @param {SnapshotActionPermission} policy - Snapshot action permission\n * @returns {MessageInitShape<typeof TailorDBType_Permission_PolicySchema>} Proto policy\n */\nfunction convertActionPermissionToProto(\n policy: SnapshotActionPermission,\n): MessageInitShape<typeof TailorDBType_Permission_PolicySchema> {\n let permit: TailorDBType_Permission_Permit;\n switch (policy.permit) {\n case \"allow\":\n permit = TailorDBType_Permission_Permit.ALLOW;\n break;\n case \"deny\":\n permit = TailorDBType_Permission_Permit.DENY;\n break;\n default:\n throw new Error(`Unknown permission: ${policy.permit satisfies never}`);\n }\n\n return {\n conditions: policy.conditions.map(convertConditionToProto),\n permit,\n description: policy.description,\n };\n}\n\n/**\n * Convert a snapshot permission condition to proto format\n * @param {SnapshotPermissionCondition} condition - Snapshot permission condition\n * @returns {MessageInitShape<typeof TailorDBType_Permission_ConditionSchema>} Proto condition\n */\nfunction convertConditionToProto(\n condition: SnapshotPermissionCondition,\n): MessageInitShape<typeof TailorDBType_Permission_ConditionSchema> {\n const [left, operator, right] = condition;\n\n const l = convertOperandToProto(left);\n const r = convertOperandToProto(right);\n\n let op: TailorDBType_Permission_Operator;\n switch (operator) {\n case \"eq\":\n op = TailorDBType_Permission_Operator.EQ;\n break;\n case \"ne\":\n op = TailorDBType_Permission_Operator.NE;\n break;\n case \"in\":\n op = TailorDBType_Permission_Operator.IN;\n break;\n case \"nin\":\n op = TailorDBType_Permission_Operator.NIN;\n break;\n case \"hasAny\":\n op = TailorDBType_Permission_Operator.HAS_ANY;\n break;\n case \"nhasAny\":\n op = TailorDBType_Permission_Operator.NHAS_ANY;\n break;\n default:\n throw new Error(`Unknown operator: ${operator satisfies never}`);\n }\n\n return {\n left: l,\n operator: op,\n right: r,\n };\n}\n\n/**\n * Convert a snapshot permission operand to proto format\n * @param {SnapshotPermissionOperand} operand - Snapshot permission operand\n * @returns {MessageInitShape<typeof TailorDBType_Permission_OperandSchema>} Proto operand\n */\nfunction convertOperandToProto(\n operand: SnapshotPermissionOperand,\n): MessageInitShape<typeof TailorDBType_Permission_OperandSchema> {\n if (isSnapshotFieldRefOperand(operand)) {\n if (\"user\" in operand) {\n return { kind: { case: \"userField\", value: operand.user } };\n }\n if (\"record\" in operand) {\n return { kind: { case: \"recordField\", value: operand.record } };\n }\n if (\"newRecord\" in operand) {\n return { kind: { case: \"newRecordField\", value: operand.newRecord } };\n }\n if (\"oldRecord\" in operand) {\n return { kind: { case: \"oldRecordField\", value: operand.oldRecord } };\n }\n operand satisfies never;\n throw new Error(`Unknown field-ref operand shape: ${JSON.stringify(operand)}`);\n }\n\n return {\n kind: { case: \"value\", value: fromJson(ValueSchema, operand) },\n };\n}\n\n/**\n * Options for generating all type manifests from a snapshot\n */\nexport interface GenerateAllManifestsOptions extends GenerateManifestOptions {\n /** Set of type names that should have publishRecordEvents enabled */\n executorUsedTypes?: ReadonlySet<string>;\n}\n\n/**\n * Generate all TailorDB type manifests from a schema snapshot\n * @param {SchemaSnapshot} snapshot - Schema snapshot\n * @param {GenerateAllManifestsOptions} options - Generation options\n * @returns {Map<string, MessageInitShape<typeof TailorDBTypeSchema>>} Map of type name to manifest\n */\nexport function generateAllTypeManifestsFromSnapshot(\n snapshot: SchemaSnapshot,\n options: GenerateAllManifestsOptions = {},\n): Map<string, MessageInitShape<typeof TailorDBTypeSchema>> {\n const manifests = new Map<string, MessageInitShape<typeof TailorDBTypeSchema>>();\n const { executorUsedTypes, ...baseOptions } = options;\n\n for (const [typeName, snapshotType] of Object.entries(snapshot.types)) {\n const typeOptions: GenerateManifestOptions = {\n ...baseOptions,\n subscribed: executorUsedTypes?.has(typeName) ?? false,\n };\n manifests.set(typeName, generateTailorDBTypeManifestFromSnapshot(snapshotType, typeOptions));\n }\n\n return manifests;\n}\n\n/**\n * Result of comparing snapshot types with existing remote types\n */\nexport interface SnapshotTypeComparison {\n /** Types to create (exist in snapshot but not in remote) */\n creates: string[];\n /** Types to update (exist in both) */\n updates: string[];\n /** Types to delete (exist in remote but not in snapshot) */\n deletes: string[];\n}\n\n/**\n * Compare snapshot types with existing remote type names\n * @param {SchemaSnapshot} snapshot - Schema snapshot\n * @param {ReadonlySet<string>} existingTypeNames - Set of existing type names in remote\n * @returns {SnapshotTypeComparison} Comparison result\n */\nexport function compareSnapshotWithRemote(\n snapshot: SchemaSnapshot,\n existingTypeNames: ReadonlySet<string>,\n): SnapshotTypeComparison {\n const snapshotTypeNames = new Set(Object.keys(snapshot.types));\n\n const creates: string[] = [];\n const updates: string[] = [];\n const deletes: string[] = [];\n\n // Types in snapshot\n for (const typeName of snapshotTypeNames) {\n if (existingTypeNames.has(typeName)) {\n updates.push(typeName);\n } else {\n creates.push(typeName);\n }\n }\n\n // Types only in remote (to be deleted)\n for (const typeName of existingTypeNames) {\n if (!snapshotTypeNames.has(typeName)) {\n deletes.push(typeName);\n }\n }\n\n return { creates, updates, deletes };\n}\n\n/**\n * Convert snapshot GQL permission policies to the proto request shape.\n * @param permission - Snapshot GQL permission policies\n * @returns Proto GQL permission\n */\nexport function protoGqlPermission(\n permission: SnapshotGqlPermission,\n): MessageInitShape<typeof TailorDBGQLPermissionSchema> {\n return {\n policies: permission.map((policy) => protoGqlPolicy(policy)),\n };\n}\n\nfunction protoGqlPolicy(\n policy: SnapshotGqlPermissionPolicy,\n): MessageInitShape<typeof TailorDBGQLPermission_PolicySchema> {\n const actions: TailorDBGQLPermission_Action[] = [];\n for (const action of policy.actions) {\n switch (action) {\n case \"all\":\n actions.push(TailorDBGQLPermission_Action.ALL);\n break;\n case \"create\":\n actions.push(TailorDBGQLPermission_Action.CREATE);\n break;\n case \"read\":\n actions.push(TailorDBGQLPermission_Action.READ);\n break;\n case \"update\":\n actions.push(TailorDBGQLPermission_Action.UPDATE);\n break;\n case \"delete\":\n actions.push(TailorDBGQLPermission_Action.DELETE);\n break;\n case \"aggregate\":\n actions.push(TailorDBGQLPermission_Action.AGGREGATE);\n break;\n case \"bulkUpsert\":\n actions.push(TailorDBGQLPermission_Action.BULK_UPSERT);\n break;\n default:\n throw new Error(`Unknown action: ${action satisfies never}`);\n }\n }\n let permit: TailorDBGQLPermission_Permit;\n switch (policy.permit) {\n case \"allow\":\n permit = TailorDBGQLPermission_Permit.ALLOW;\n break;\n case \"deny\":\n permit = TailorDBGQLPermission_Permit.DENY;\n break;\n default:\n throw new Error(`Unknown permission: ${policy.permit satisfies never}`);\n }\n return {\n conditions: policy.conditions.map((cond) => protoGqlCondition(cond)),\n actions,\n permit,\n description: policy.description,\n };\n}\n\nfunction protoGqlCondition(\n condition: SnapshotPermissionCondition,\n): MessageInitShape<typeof TailorDBGQLPermission_ConditionSchema> {\n const [left, operator, right] = condition;\n\n const l = protoGqlOperand(left);\n const r = protoGqlOperand(right);\n let op: TailorDBGQLPermission_Operator;\n switch (operator) {\n case \"eq\":\n op = TailorDBGQLPermission_Operator.EQ;\n break;\n case \"ne\":\n op = TailorDBGQLPermission_Operator.NE;\n break;\n case \"in\":\n op = TailorDBGQLPermission_Operator.IN;\n break;\n case \"nin\":\n op = TailorDBGQLPermission_Operator.NIN;\n break;\n case \"hasAny\":\n op = TailorDBGQLPermission_Operator.HAS_ANY;\n break;\n case \"nhasAny\":\n op = TailorDBGQLPermission_Operator.NHAS_ANY;\n break;\n default:\n throw new Error(`Unknown operator: ${operator satisfies never}`);\n }\n return {\n left: l,\n operator: op,\n right: r,\n };\n}\n\nfunction protoGqlOperand(\n operand: SnapshotPermissionOperand,\n): MessageInitShape<typeof TailorDBGQLPermission_OperandSchema> {\n if (isSnapshotFieldRefOperand(operand)) {\n if (\"user\" in operand) {\n return { kind: { case: \"userField\", value: operand.user } };\n }\n throw new Error(\n `Unsupported field-ref operand in GQL permission: ${JSON.stringify(operand)} ` +\n `— GQL permissions only support { user } field references`,\n );\n }\n\n return {\n kind: { case: \"value\", value: fromJson(ValueSchema, operand) },\n };\n}\n","/**\n * Pre-migration field config adjustments\n *\n * The Pre-phase sends a \"relaxed\" version of the target schema so that\n * `migrate.ts` scripts can still operate on the previous shape of the data.\n * This module handles the field-level adjustments:\n *\n * - `field_removed`: re-insert the removed field so migrate.ts can read it\n * (the physical drop happens in Post-phase).\n * - `field_added` with `required: true`: relax to `required: false`.\n * - `field_modified` optional→required, unique constraint added, enum\n * value removed: keep the looser side until Post-phase.\n * - `field_type_modified`: keep the complete previous field config until\n * Post-phase so migrate.ts runs against the previous type contract.\n *\n * and the type-level index adjustments:\n *\n * - `index_added` with `unique: true`: withhold the index until Post-phase.\n * - `index_modified` that gains a unique constraint or re-points a unique\n * index at different fields: keep the previous definition until Post-phase.\n *\n * Type-level deletions (`type_removed`) are handled by the deploy flow,\n * which retains the type until Post-phase rather than via this module.\n *\n * Post-phase then sends the final schema, after migrate.ts has had a chance\n * to fix up data.\n */\n\nimport { isBreakingIndexChange } from \"./snapshot\";\nimport { convertFieldConfigToProto, convertIndexToProto } from \"./snapshot-manifest\";\nimport type {\n DiffChange,\n FieldDiffChange,\n IndexDiffChange,\n TypeScriptsModifiedChange,\n} from \"./diff-calculator\";\nimport type { TailorDBSnapshotType } from \"./snapshot-types\";\nimport type { PendingMigration } from \"./types\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type {\n TailorDBType_FieldConfigSchema,\n TailorDBType_IndexSchema,\n} from \"@tailor-platform/tailor-proto/tailordb_resource_pb\";\n\n/**\n * Diff change kinds that require pre-migration schema adjustments.\n */\nconst PRE_MIGRATION_FIELD_KINDS = new Set<DiffChange[\"kind\"]>([\n \"field_added\",\n \"field_modified\",\n \"field_type_modified\",\n \"field_removed\",\n]);\n\n/**\n * Type guard: is the change a field-level change that needs pre-migration\n * schema adjustment?\n * @param {DiffChange} change - Diff change to test\n * @returns {boolean} True if the change is a field-level change\n */\nfunction isPreMigrationFieldChange(change: DiffChange): change is FieldDiffChange {\n return PRE_MIGRATION_FIELD_KINDS.has(change.kind);\n}\n\n/**\n * Map of pre-migration field changes: typeName -> fieldName -> change.\n *\n * Includes both breaking changes (required-add, unique-add, enum value\n * removal) and warning changes (field_removed). The Pre-phase needs to\n * adjust the schema for both so that migrate.ts can still see the previous\n * shape.\n */\nexport type PreMigrationChangesMap = Map<string, Map<string, FieldDiffChange>>;\n\n/**\n * Create the type snapshot used to build a Pre-phase manifest.\n *\n * This adjustment happens before manifest generation because field hooks and\n * validators are aggregated into type-level scripts by the manifest builder.\n * Replacing only the generated field proto would leave those scripts on the\n * target field contract while migrate.ts still runs against the previous one.\n * @param snapshotType - Final snapshot state for this migration\n * @param typeChanges - Field changes for this type, keyed by field name\n * @param typeScriptsChange - Type-level scripts changed by the same migration\n * @returns A snapshot with Pre-phase field contracts\n */\nexport function createPreMigrationSnapshotType(\n snapshotType: TailorDBSnapshotType,\n typeChanges: Map<string, FieldDiffChange>,\n typeScriptsChange?: TypeScriptsModifiedChange,\n): TailorDBSnapshotType {\n const fields = structuredClone(snapshotType.fields);\n let hasFieldTypeChange = false;\n\n for (const [fieldName, change] of typeChanges) {\n if (change.kind !== \"field_type_modified\") continue;\n hasFieldTypeChange = true;\n fields[fieldName] = structuredClone(change.before);\n }\n\n const preSnapshotType = { ...snapshotType, fields };\n if (!hasFieldTypeChange || !typeScriptsChange) return preSnapshotType;\n\n const {\n typeHookExpr: _targetHook,\n typeValidateExpr: _targetValidate,\n ...withoutTypeScripts\n } = preSnapshotType;\n return {\n ...withoutTypeScripts,\n ...(typeScriptsChange.before.typeHookExpr && {\n typeHookExpr: structuredClone(typeScriptsChange.before.typeHookExpr),\n }),\n ...(typeScriptsChange.before.typeValidateExpr !== undefined && {\n typeValidateExpr: typeScriptsChange.before.typeValidateExpr,\n }),\n };\n}\n\n/**\n * Build a map of field changes that require pre-migration schema adjustment.\n * @param {PendingMigration[]} pendingMigrations - Pending migrations to scan\n * @returns {PreMigrationChangesMap} Map of changes keyed by typeName/fieldName\n */\nexport function buildPreMigrationChangesMap(\n pendingMigrations: PendingMigration[],\n): PreMigrationChangesMap {\n const map: PreMigrationChangesMap = new Map();\n for (const migration of pendingMigrations) {\n for (const change of migration.diff.changes) {\n if (!isPreMigrationFieldChange(change)) continue;\n if (!change.fieldName) continue;\n const perType = map.get(change.typeName) ?? new Map<string, FieldDiffChange>();\n perType.set(change.fieldName, change);\n map.set(change.typeName, perType);\n }\n }\n return map;\n}\n\n/**\n * Apply pre-migration schema adjustments to a single field map in place.\n *\n * The fields map is the proto-shape `TailorDBType.schema.fields` that will\n * be sent in the Pre-phase. We mutate it so that:\n *\n * - Removed fields are re-inserted using their pre-migration config.\n * - Newly added required fields are relaxed to optional.\n * - Modified fields keep the looser side of unique/required/enum.\n *\n * @param {Record<string, MessageInitShape<typeof TailorDBType_FieldConfigSchema>>} fields - Field map to adjust (mutated in place)\n * @param {Map<string, FieldDiffChange>} typeChanges - Changes for this type, keyed by fieldName\n */\nexport function applyPreMigrationFieldAdjustments(\n fields: Record<string, MessageInitShape<typeof TailorDBType_FieldConfigSchema>>,\n typeChanges: Map<string, FieldDiffChange>,\n): void {\n for (const [fieldName, change] of typeChanges) {\n if (change.kind === \"field_removed\") {\n fields[fieldName] = convertFieldConfigToProto(change.before);\n continue;\n }\n\n const field = fields[fieldName];\n if (!field) continue;\n\n if (change.kind === \"field_added\") {\n if (change.after.required) {\n field.required = false;\n }\n continue;\n }\n\n if (change.kind === \"field_type_modified\") {\n fields[fieldName] = convertFieldConfigToProto(change.before);\n continue;\n }\n\n const { before, after } = change;\n\n if (!before.required && after.required) {\n field.required = false;\n }\n\n if (!(before.unique ?? false) && (after.unique ?? false)) {\n field.unique = false;\n }\n\n if (before.allowedValues && after.allowedValues) {\n const afterValues = new Set(after.allowedValues.map((v) => v.value));\n const removedValues = before.allowedValues.filter((v) => !afterValues.has(v.value));\n if (removedValues.length > 0) {\n const valueMap = new Map<string, string>();\n for (const v of before.allowedValues) {\n valueMap.set(v.value, v.description ?? \"\");\n }\n for (const v of after.allowedValues) {\n if (!valueMap.has(v.value)) {\n valueMap.set(v.value, v.description ?? \"\");\n }\n }\n field.allowedValues = Array.from(valueMap.entries()).map(([value, description]) => ({\n value,\n description,\n }));\n }\n }\n }\n}\n\n/**\n * Map of pre-migration index changes needing relaxation:\n * typeName -> indexName -> change.\n */\nexport type PreMigrationIndexChangesMap = Map<string, Map<string, IndexDiffChange>>;\n\n/**\n * Build a map of type-level index changes that require pre-migration schema\n * adjustment (the breaking ones — see {@link isBreakingIndexChange}).\n * @param {PendingMigration[]} pendingMigrations - Pending migrations to scan\n * @returns {PreMigrationIndexChangesMap} Map of changes keyed by typeName/indexName\n */\nexport function buildPreMigrationIndexChangesMap(\n pendingMigrations: PendingMigration[],\n): PreMigrationIndexChangesMap {\n const map: PreMigrationIndexChangesMap = new Map();\n for (const migration of pendingMigrations) {\n for (const change of migration.diff.changes) {\n if (change.kind !== \"index_added\" && change.kind !== \"index_modified\") continue;\n const before = change.kind === \"index_modified\" ? change.before : undefined;\n if (!isBreakingIndexChange(change.typeName, change.indexName, before, change.after)) {\n continue;\n }\n const perType = map.get(change.typeName) ?? new Map<string, IndexDiffChange>();\n perType.set(change.indexName, change);\n map.set(change.typeName, perType);\n }\n }\n return map;\n}\n\n/**\n * Apply pre-migration schema adjustments to a type's index map in place.\n *\n * The indexes map is the proto-shape `TailorDBType.schema.indexes` that will\n * be sent in the Pre-phase. We mutate it so that:\n *\n * - Newly added unique indexes are withheld until Post-phase.\n * - Modified indexes keep their previous definition until Post-phase.\n *\n * @param {Record<string, MessageInitShape<typeof TailorDBType_IndexSchema>>} indexes - Index map to adjust (mutated in place)\n * @param {Map<string, IndexDiffChange>} typeIndexChanges - Changes for this type, keyed by indexName\n */\nexport function applyPreMigrationIndexAdjustments(\n indexes: Record<string, MessageInitShape<typeof TailorDBType_IndexSchema>>,\n typeIndexChanges: Map<string, IndexDiffChange>,\n): void {\n for (const [indexName, change] of typeIndexChanges) {\n if (change.kind === \"index_added\") {\n delete indexes[indexName];\n continue;\n }\n if (change.kind === \"index_modified\") {\n indexes[indexName] = convertIndexToProto(change.before);\n }\n }\n}\n","import { getOrNull, type OperatorClient } from \"#/cli/shared/client\";\nimport {\n MIGRATION_HISTORY_LABEL_KEY,\n MIGRATION_LABEL_KEY,\n parseMigrationHistoryId,\n parseMigrationLabelNumber,\n} from \"./types\";\n\nexport interface RemoteMigrationState {\n metadataExists: boolean;\n number: number | null;\n historyId: string | null;\n historyIdInvalid: boolean;\n}\n\n/**\n * Fetch the namespace's migration checkpoint and history ID.\n * @param client - Operator client\n * @param trn - Namespace TRN\n * @returns Parsed migration state with invalid history labels kept distinct from missing labels\n */\nexport async function fetchRemoteMigrationState(\n client: OperatorClient,\n trn: string,\n): Promise<RemoteMigrationState> {\n const metadata = await getOrNull(async () => {\n const { metadata } = await client.getMetadata({ trn });\n return metadata;\n });\n if (!metadata) {\n return {\n metadataExists: false,\n number: null,\n historyId: null,\n historyIdInvalid: false,\n };\n }\n\n const migrationLabel = metadata.labels[MIGRATION_LABEL_KEY];\n const historyLabel = metadata.labels[MIGRATION_HISTORY_LABEL_KEY];\n const historyId = historyLabel ? parseMigrationHistoryId(historyLabel) : null;\n return {\n metadataExists: true,\n number: migrationLabel ? parseMigrationLabelNumber(migrationLabel) : null,\n historyId,\n historyIdInvalid: historyLabel !== undefined && historyId === null,\n };\n}\n\n/**\n * Fetch the namespace's current migration number from its metadata labels.\n *\n * Only a namespace that has not been deployed yet reads as \"no current\n * migration\". Every other lookup failure must propagate: treating it as\n * unset would misreport a transient error as \"no checkpoint\", showing\n * every migration as pending to callers.\n * @param client - Operator client\n * @param trn - Namespace TRN\n * @returns Parsed current migration number, or null when unset or unparseable\n */\nexport async function fetchRemoteMigrationNumber(\n client: OperatorClient,\n trn: string,\n): Promise<number | null> {\n return (await fetchRemoteMigrationState(client, trn)).number;\n}\n","/**\n * Schema validation checks shared between `deploy` and\n * `tailordb migration validate`.\n *\n * These checks are read-only: they compare local type definitions, the\n * migration snapshot history, and the remote schema without mutating any\n * state.\n */\n\nimport { resourceTrn } from \"#/cli/commands/deploy/label\";\nimport { fetchAllTolerant, type OperatorClient } from \"#/cli/shared/client\";\nimport { logger } from \"#/cli/shared/logger\";\nimport {\n hasChanges,\n formatMigrationDiff,\n formatDiffSummary,\n type MigrationDiff,\n} from \"./diff-calculator\";\nimport { fetchRemoteMigrationState } from \"./remote-state\";\nimport {\n reconstructSnapshotFromMigrations,\n compareLocalTypesWithSnapshot,\n compareRemoteWithSnapshot,\n formatMigrationNumber,\n formatSchemaDrifts,\n createSnapshotType,\n createSnapshotFromRemoteTypes,\n getLatestMigrationNumber,\n type RemoteGqlPermission,\n type SchemaSnapshot,\n type SnapshotGqlOperations,\n type SnapshotSettings,\n type TailorDBSnapshotType,\n type NormalizedSchemaSnapshot,\n} from \"./snapshot\";\nimport { type RemoteSchemaVerificationResult } from \"./types\";\nimport type { TailorDBService } from \"#/cli/services/tailordb/service\";\nimport type { LoadedConfig } from \"#/cli/shared/config-loader\";\nimport type { TailorDBServiceConfig } from \"#/types/tailordb.generated\";\nimport type { NamespaceWithMigrations } from \"./config\";\nimport type { TailorDBType as ProtoTailorDBType } from \"@tailor-platform/tailor-proto/tailordb_resource_pb\";\n\n/**\n * Canonical input shape consumed by every TailorDB plan/proto step.\n * The deploy pipeline funnels `TailorDBService` through `createSnapshotType` so\n * that comparison, manifest generation and migration drift checks all read the\n * same snapshot-shaped data, keeping platform-side normalization (e.g. decimal\n * scale) in one place.\n */\nexport type TailorDBDeployInput = {\n namespace: string;\n config: TailorDBServiceConfig;\n types: Record<string, TailorDBSnapshotType>;\n};\n\n/**\n * Convert a runtime TailorDBService to the snapshot-shaped deploy input.\n * @param service - Loaded TailorDB service (after `loadTypes()`)\n * @returns The canonical snapshot-shaped deploy input for downstream plan/apply phases.\n */\nexport function toTailorDBDeployInput(service: TailorDBService): TailorDBDeployInput {\n const types: Record<string, TailorDBSnapshotType> = {};\n for (const [typeName, type] of Object.entries(service.types)) {\n types[typeName] = createSnapshotType(type);\n }\n return {\n namespace: service.namespace,\n config: service.config,\n types,\n };\n}\n\n// ============================================================================\n// Remote Schema Verification\n// ============================================================================\n\n/**\n * Fetch all TailorDB types from remote for a namespace\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {string} namespace - TailorDB namespace\n * @returns {Promise<ProtoTailorDBType[]>} Remote TailorDB types\n */\nasync function fetchRemoteTypes(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n): Promise<ProtoTailorDBType[]> {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { tailordbTypes, nextPageToken } = await client.listTailorDBTypes({\n workspaceId,\n namespaceName: namespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbTypes, nextPageToken];\n });\n}\n\nasync function fetchRemoteGqlPermissions(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n): Promise<RemoteGqlPermission[]> {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { permissions, nextPageToken } = await client.listTailorDBGQLPermissions({\n workspaceId,\n namespaceName: namespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [permissions, nextPageToken];\n });\n}\n\n/**\n * Fetch a namespace's deployed schema as a normalized snapshot.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param namespace - TailorDB namespace\n * @returns The deployed schema snapshot\n */\nexport async function fetchRemoteSchemaSnapshot(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n): Promise<NormalizedSchemaSnapshot> {\n const [remoteTypes, remoteGqlPermissions] = await Promise.all([\n fetchRemoteTypes(client, workspaceId, namespace),\n fetchRemoteGqlPermissions(client, workspaceId, namespace),\n ]);\n return createSnapshotFromRemoteTypes(remoteTypes, namespace, remoteGqlPermissions);\n}\n\ntype RemoteTailorDBSettings = NonNullable<NonNullable<ProtoTailorDBType[\"schema\"]>[\"settings\"]>;\ntype DeployGqlOperations = SnapshotGqlOperations | \"query\" | undefined;\n\nfunction definedWhenNotEmpty<T extends object>(value: T): T | undefined {\n return Object.keys(value).length > 0 ? value : undefined;\n}\n\nfunction namespaceConfig(\n config: LoadedConfig,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n namespace: string,\n): TailorDBServiceConfig | undefined {\n const inputConfig = tailorDBInputs.find((input) => input.namespace === namespace)?.config;\n return inputConfig ?? (config.db?.[namespace] as TailorDBServiceConfig | undefined);\n}\n\nfunction namespaceGqlOperations(\n config: LoadedConfig,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n namespace: string,\n): DeployGqlOperations {\n return namespaceConfig(config, tailorDBInputs, namespace)?.gqlOperations;\n}\n\nconst GQL_OPERATION_KEYS = [\"create\", \"update\", \"delete\", \"read\"] as const;\n\nfunction configuredDisabledGqlOperations(\n operations: DeployGqlOperations,\n): SnapshotGqlOperations | undefined {\n if (!operations) return undefined;\n if (operations === \"query\") {\n return { create: false, update: false, delete: false };\n }\n\n const disabled: SnapshotGqlOperations = {};\n for (const key of GQL_OPERATION_KEYS) {\n if (operations[key] === false) disabled[key] = false;\n }\n\n return definedWhenNotEmpty(disabled);\n}\n\nfunction appliedConfiguredDisabledGqlOperations(\n remoteDisabled: RemoteTailorDBSettings[\"disableGqlOperations\"] | undefined,\n configuredDisabled: SnapshotGqlOperations | undefined,\n): SnapshotGqlOperations | undefined {\n if (!remoteDisabled || !configuredDisabled) return undefined;\n\n const disabled: SnapshotGqlOperations = {};\n for (const key of GQL_OPERATION_KEYS) {\n if (configuredDisabled[key] === false && remoteDisabled[key]) disabled[key] = false;\n }\n\n return definedWhenNotEmpty(disabled);\n}\n\nfunction deployComparableSnapshot(\n snapshot: SchemaSnapshot,\n remoteTypes: ReadonlyArray<ProtoTailorDBType>,\n gqlOperations: DeployGqlOperations,\n): SchemaSnapshot {\n const remoteTypesByName = new Map(remoteTypes.map((type) => [type.name, type]));\n const configuredDisabled = configuredDisabledGqlOperations(gqlOperations);\n const types: Record<string, TailorDBSnapshotType> = {};\n\n for (const [typeName, type] of Object.entries(snapshot.types)) {\n const settings: SnapshotSettings = { ...type.settings };\n const remoteSettings = remoteTypesByName.get(typeName)?.schema?.settings;\n\n if (type.settings?.publishEvents === undefined && remoteSettings?.publishRecordEvents) {\n settings.publishEvents = true;\n }\n\n if (type.settings?.gqlOperations === undefined) {\n const disabled = appliedConfiguredDisabledGqlOperations(\n remoteSettings?.disableGqlOperations,\n configuredDisabled,\n );\n if (disabled) settings.gqlOperations = disabled;\n }\n\n const comparableType = { ...type };\n const comparableSettings = definedWhenNotEmpty(settings);\n if (comparableSettings) {\n comparableType.settings = comparableSettings;\n } else {\n delete comparableType.settings;\n }\n types[typeName] = comparableType;\n }\n\n return { ...snapshot, types };\n}\n\n/**\n * Verify remote schema matches the expected snapshot state\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {NamespaceWithMigrations[]} namespacesWithMigrations - Namespaces with migration config\n * @param {LoadedConfig} config - Loaded application config\n * @param {ReadonlyArray<TailorDBDeployInput>} tailorDBInputs - Deploy inputs for namespace defaults\n * @returns {Promise<RemoteSchemaVerificationResult[]>} Verification results per namespace\n */\nexport async function verifyRemoteSchema(\n client: OperatorClient,\n workspaceId: string,\n namespacesWithMigrations: NamespaceWithMigrations[],\n config: LoadedConfig,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n): Promise<RemoteSchemaVerificationResult[]> {\n const results: RemoteSchemaVerificationResult[] = [];\n\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n // Get current remote migration number\n const remoteState = await fetchRemoteMigrationState(\n client,\n resourceTrn(workspaceId, \"tailordb\", namespace),\n );\n const { metadataExists, number: remoteMigrationNumber } = remoteState;\n\n if (\n remoteState.historyIdInvalid ||\n (remoteMigrationNumber === null && remoteState.historyId !== null)\n ) {\n results.push({\n namespace,\n remoteMigrationNumber: remoteMigrationNumber ?? 0,\n drifts: [],\n hasDrift: false,\n checkpointMissingLocal: true,\n });\n continue;\n }\n\n // If no migration label exists, this is likely a first apply - skip verification\n // Remote verification only makes sense when there's an established migration history\n if (remoteMigrationNumber === null) {\n results.push({\n namespace,\n remoteMigrationNumber: 0,\n drifts: [],\n hasDrift: false,\n skipped: metadataExists ? \"no_migration_label\" : \"not_deployed\",\n });\n continue;\n }\n\n const latestMigrationNumber = getLatestMigrationNumber(migrationsDir);\n const baselineSnapshot = reconstructSnapshotFromMigrations(migrationsDir, 0);\n const rebaseline = baselineSnapshot?.rebaseline;\n const historyMatchesCurrent = rebaseline\n ? remoteState.historyId === rebaseline.historyId\n : remoteState.historyId === null;\n const historyMatchesReplaced = rebaseline\n ? remoteState.historyId === rebaseline.replacedHistoryId\n : false;\n const checkpointRepair =\n rebaseline &&\n historyMatchesReplaced &&\n remoteMigrationNumber === rebaseline.replacedLatestMigration\n ? ({\n from: remoteMigrationNumber,\n to: 0,\n fromHistoryId: remoteState.historyId,\n toHistoryId: rebaseline.historyId,\n } as const)\n : undefined;\n const checkpointMissingLocal =\n (!historyMatchesCurrent && !checkpointRepair) ||\n (remoteMigrationNumber > latestMigrationNumber && !checkpointRepair);\n if (checkpointMissingLocal) {\n results.push({\n namespace,\n remoteMigrationNumber,\n drifts: [],\n hasDrift: false,\n checkpointMissingLocal: true,\n });\n continue;\n }\n const expectedMigrationNumber = checkpointRepair?.to ?? remoteMigrationNumber;\n\n // Reconstruct the snapshot that the remote schema must match.\n const expectedSnapshot = reconstructSnapshotFromMigrations(\n migrationsDir,\n expectedMigrationNumber,\n );\n if (!expectedSnapshot) {\n // No snapshots exist - skip verification\n results.push({\n namespace,\n remoteMigrationNumber,\n drifts: [],\n hasDrift: false,\n skipped: \"no_snapshot\",\n });\n continue;\n }\n\n // Fetch remote types\n const [remoteTypes, remoteGqlPermissions] = await Promise.all([\n fetchRemoteTypes(client, workspaceId, namespace),\n fetchRemoteGqlPermissions(client, workspaceId, namespace),\n ]);\n const expectedDeploySnapshot = deployComparableSnapshot(\n expectedSnapshot,\n remoteTypes,\n namespaceGqlOperations(config, tailorDBInputs, namespace),\n );\n\n // Compare remote with expected snapshot\n const drifts = compareRemoteWithSnapshot(\n remoteTypes,\n expectedDeploySnapshot,\n remoteGqlPermissions,\n );\n\n results.push({\n namespace,\n remoteMigrationNumber,\n drifts,\n hasDrift: drifts.length > 0,\n ...(checkpointRepair && drifts.length === 0 ? { checkpointRepair } : {}),\n });\n }\n\n return results;\n}\n\n/**\n * Log common causes of remote schema drift and how to resolve them\n */\nexport function logRemoteDriftGuidance(): void {\n logger.info(\"This may indicate:\");\n logger.info(\" - Another developer applied different migrations\", { mode: \"plain\" });\n logger.info(\" - Manual schema changes were made directly\", { mode: \"plain\" });\n logger.info(\" - Migration history is out of sync\", { mode: \"plain\" });\n logger.newline();\n logger.info(\"To resolve:\");\n logger.info(\" - Run 'tailor tailordb migration status' to compare local vs remote.\", {\n mode: \"plain\",\n });\n logger.info(\" - If remote is correct, update local types and run 'migration generate'.\", {\n mode: \"plain\",\n });\n logger.info(\n \" - If local migration history is correct, run 'migration sync <N>' to overwrite remote.\",\n { mode: \"plain\" },\n );\n logger.info(\" - If only bookkeeping is stale, run 'migration set <N>'.\", { mode: \"plain\" });\n}\n\n/**\n * Format remote schema verification results for display\n * @param {RemoteSchemaVerificationResult[]} results - Verification results\n * @returns {string} Formatted results string\n */\nexport function formatRemoteVerificationResults(results: RemoteSchemaVerificationResult[]): string {\n const lines: string[] = [];\n\n for (const result of results) {\n if (!result.hasDrift) continue;\n\n lines.push(`Namespace: ${result.namespace}`);\n lines.push(` Remote migration: ${formatMigrationNumber(result.remoteMigrationNumber)}`);\n lines.push(` Differences:`);\n lines.push(formatSchemaDrifts(result.drifts));\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Local Migration Diff Check\n// ============================================================================\n\nexport interface MigrationCheckResult {\n namespace: string;\n migrationsDir: string;\n hasDiff: boolean;\n diff?: MigrationDiff;\n}\n\n/**\n * Check if there are schema differences between migration snapshots and local definitions\n * @param {ReadonlyMap<string, Record<string, TailorDBSnapshotType>>} typesByNamespace - Snapshot-shaped local types by namespace\n * @param {NamespaceWithMigrations[]} namespacesWithMigrations - Namespaces with migrations config\n * @returns {Promise<MigrationCheckResult[]>} Results for each namespace\n */\nexport async function checkMigrationDiffs(\n typesByNamespace: ReadonlyMap<string, Record<string, TailorDBSnapshotType>>,\n namespacesWithMigrations: NamespaceWithMigrations[],\n): Promise<MigrationCheckResult[]> {\n const results: MigrationCheckResult[] = [];\n\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n const localTypes = typesByNamespace.get(namespace);\n if (!localTypes) {\n continue;\n }\n\n // Returns null when the migrations directory is missing or empty;\n // throws when existing migration files are invalid.\n const previousSnapshot = reconstructSnapshotFromMigrations(migrationsDir);\n\n if (!previousSnapshot) {\n // No snapshots yet - user should run migrate generate first\n results.push({\n namespace,\n migrationsDir,\n hasDiff: true,\n diff: undefined, // Indicates no snapshot exists\n });\n continue;\n }\n\n // Compare with local types\n const diff = compareLocalTypesWithSnapshot(previousSnapshot, localTypes, namespace);\n\n results.push({\n namespace,\n migrationsDir,\n hasDiff: hasChanges(diff),\n diff: hasChanges(diff) ? diff : undefined,\n });\n }\n\n return results;\n}\n\n/**\n * Format migration check results for display\n * @param {MigrationCheckResult[]} results - Migration check results\n * @returns {string} Formatted results string\n */\nexport function formatMigrationCheckResults(results: MigrationCheckResult[]): string {\n const lines: string[] = [];\n\n for (const result of results) {\n if (!result.hasDiff) {\n continue;\n }\n\n lines.push(`Namespace: ${result.namespace}`);\n\n if (!result.diff) {\n lines.push(\" No migration snapshot found. Run 'tailor tailordb migration generate' first.\");\n } else {\n lines.push(` ${formatDiffSummary(result.diff)}`);\n lines.push(\"\");\n lines.push(formatMigrationDiff(result.diff));\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Migration script bundler for TailorDB migrations\n *\n * Bundles migration scripts to be executed via TestExecScript API\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { createTsconfigPathsPlugin } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createGeneratedEntryResolverPlugin } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\n\nexport interface MigrationBundleResult {\n namespace: string;\n migrationNumber: number;\n bundledCode: string;\n}\n\n/**\n * Bundle a single migration script\n *\n * Creates an entry that:\n * 1. Imports the migration script's main function\n * 2. Defines getDB() function inline\n * 3. Wraps migration in a transaction using getDB()\n * 4. Exports as main() for server-side execution\n * @param {string} sourceFile - Path to the migration script file\n * @param {string} namespace - TailorDB namespace\n * @param {number} migrationNumber - Migration number\n * @param {Record<string, string | number | boolean>} env - Environment variables to inject into the migration context\n * @param {string} [baseDir] - Directory to resolve the bundler's tsconfig against; defaults to the migration script's directory\n * @returns {Promise<MigrationBundleResult>} Bundled migration result\n */\nexport async function bundleMigrationScript(\n sourceFile: string,\n namespace: string,\n migrationNumber: number,\n env: Record<string, string | number | boolean> = {},\n baseDir?: string,\n): Promise<MigrationBundleResult> {\n // Output directory in .tailor (relative to project root)\n const outputDir = path.resolve(getDistDir(), \"migrations\");\n fs.mkdirSync(outputDir, { recursive: true });\n\n // Entry file in output directory (consistent with resolver/executor bundlers)\n const entryPath = path.join(outputDir, `migration_${namespace}_${migrationNumber}.entry.js`);\n\n const absoluteSourcePath = path.resolve(sourceFile).replace(/\\\\/g, \"/\");\n\n // Create entry file that wraps migration in a transaction\n // getDB function is defined inline to avoid dependency on generated types\n const entryContent = ml /* js */ `\n import { main as _migrationMain } from \"${absoluteSourcePath}\";\n import { Kysely, TailordbDialect } from \"@tailor-platform/sdk/kysely\";\n\n function getDB(namespace) {\n const client = new tailordb.Client({ namespace });\n return new Kysely({\n dialect: new TailordbDialect(client),\n });\n }\n\n export async function main(input) {\n const env = ${JSON.stringify(env)};\n const db = getDB(\"${namespace}\");\n await db.transaction().execute(async (trx) => {\n await _migrationMain(trx, { env });\n });\n return { success: true };\n }\n `;\n fs.writeFileSync(entryPath, entryContent);\n\n const projectDir = baseDir ?? path.dirname(absoluteSourcePath);\n const tsconfig = await resolveTSConfigWithFallback(projectDir);\n\n // Bundle with tree-shaking (write: false to avoid unnecessary disk I/O)\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n plugins: [\n createGeneratedEntryResolverPlugin(entryPath, projectDir),\n createTsconfigPathsPlugin(),\n platformBundleDefinePlugin,\n ],\n input: entryPath,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: false,\n minify: false,\n codeSplitting: false,\n globals: {\n tailordb: \"tailordb\",\n },\n },\n external: [\"tailordb\"],\n resolve: {\n conditionNames: [\"node\", \"import\"],\n },\n tsconfig,\n treeshake: {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n },\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n\n // Entry file remains in output directory (consistent with resolver/executor bundlers)\n\n return {\n namespace,\n migrationNumber,\n bundledCode,\n };\n}\n","/**\n * Copyable command hints for migration remediation\n */\n\nimport { formatConfigArg } from \"#/cli/shared/args\";\nimport { formatCopyableCommand } from \"#/cli/shared/errors\";\nimport { formatMigrationNumber } from \"./migration-number\";\n\nexport interface MigrationScriptCommandOptions {\n migrationNumber: number;\n namespace: string;\n /** Config path the current run used; omitted from the command when it resolves to the default */\n configPath?: string;\n /** Append `--no-script --reason` with a placeholder reason */\n noScript?: boolean;\n}\n\n/**\n * Build the copyable `tailor tailordb migration script` command for\n * remediation hints, reproducing the current run's invocation context.\n * @param {MigrationScriptCommandOptions} options - Target migration and invocation context\n * @returns {string} Command line quoted for the current platform's shell\n */\nexport function formatMigrationScriptCommand(options: MigrationScriptCommandOptions): string {\n const { migrationNumber, namespace, configPath, noScript } = options;\n const argv = [\n \"tailor\",\n \"tailordb\",\n \"migration\",\n \"script\",\n formatMigrationNumber(migrationNumber),\n \"--namespace\",\n namespace,\n ];\n const configArg = formatConfigArg(configPath);\n if (configArg !== undefined) {\n argv.push(configArg);\n }\n if (noScript) {\n argv.push(\"--no-script\", \"--reason\", \"<reason>\");\n }\n return formatCopyableCommand(argv);\n}\n","/**\n * Script execution service for TestExecScript API\n *\n * Provides a reusable utility for executing scripts via the TestExecScript API\n * with polling for completion status.\n */\n\nimport { FunctionExecution_Status } from \"@tailor-platform/tailor-proto/function_resource_pb\";\nimport type { OperatorClient } from \"#/cli/shared/client\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { AuthInvokerSchema } from \"@tailor-platform/tailor-proto/auth_resource_pb\";\nimport type { Jsonifiable } from \"type-fest\";\n\n/** Authentication context for script execution, provided as a plain object. */\nexport type ScriptInvoker = MessageInitShape<typeof AuthInvokerSchema>;\n\n/**\n * Default polling interval for script execution status in milliseconds (1 second)\n */\nexport const DEFAULT_POLL_INTERVAL = 1000;\n\n/**\n * Options for script execution\n */\nexport interface ScriptExecutionOptions<T extends Jsonifiable = Jsonifiable> {\n /** Operator client instance */\n client: OperatorClient;\n /** Workspace ID */\n workspaceId: string;\n /** Script name (for identification) */\n name: string;\n /** Bundled script code to execute */\n code: string;\n /** Optional JSON-serializable argument to pass to the script */\n arg?: T;\n /** Auth invoker for script execution */\n invoker: ScriptInvoker;\n /** Polling interval in milliseconds (default: 1000ms) */\n pollInterval?: number;\n}\n\n/**\n * Result of script execution\n */\nexport interface ScriptExecutionResult {\n /** Whether the script executed successfully */\n success: boolean;\n /** Logs output from the script execution */\n logs: string;\n /** Result value from the script execution */\n result: string;\n /** Error message if execution failed */\n error?: string;\n}\n\n/**\n * Result from waiting for execution completion\n */\nexport interface ExecutionWaitResult {\n /** Execution status */\n status: FunctionExecution_Status;\n /** Logs output from the execution */\n logs: string;\n /** Result value from the execution */\n result: string;\n}\n\n/**\n * Wait for a function execution to complete\n *\n * Polls the getFunctionExecution API until the execution reaches a terminal state\n * (SUCCESS or FAILED).\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {string} executionId - Execution ID to wait for\n * @param {number} [pollInterval] - Polling interval in milliseconds (default: 1000ms)\n * @returns {Promise<ExecutionWaitResult>} Execution result\n * @throws {Error} If execution is not found\n */\nexport async function waitForExecution(\n client: OperatorClient,\n workspaceId: string,\n executionId: string,\n pollInterval: number = DEFAULT_POLL_INTERVAL,\n): Promise<ExecutionWaitResult> {\n // loop exits when the function execution reaches a terminal status\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const { execution } = await client.getFunctionExecution({\n workspaceId,\n executionId,\n });\n\n if (!execution) {\n throw new Error(`Execution '${executionId}' not found.`);\n }\n\n // Check for terminal states\n if (\n execution.status === FunctionExecution_Status.SUCCESS ||\n execution.status === FunctionExecution_Status.FAILED\n ) {\n return {\n status: execution.status,\n logs: execution.logs,\n result: execution.result,\n };\n }\n\n // Wait before polling again\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n}\n\n/**\n * Execute a script via TestExecScript API and wait for completion\n *\n * This function:\n * 1. Calls testExecScript API to start execution\n * 2. Polls getFunctionExecution until completion\n * 3. Returns structured result with success/failure status\n * @param {ScriptExecutionOptions} options - Execution options\n * @returns {Promise<ScriptExecutionResult>} Execution result\n */\nexport async function executeScript<T extends Jsonifiable = Jsonifiable>(\n options: ScriptExecutionOptions<T>,\n): Promise<ScriptExecutionResult> {\n const { client, workspaceId, name, code, arg, invoker, pollInterval } = options;\n\n // Execute the script\n const response = await client.testExecScript({\n workspaceId,\n name,\n code,\n arg: JSON.stringify(arg === undefined ? {} : arg),\n invoker,\n });\n const executionId = response.executionId;\n\n // Wait for completion\n const result = await waitForExecution(client, workspaceId, executionId, pollInterval);\n\n if (result.status === FunctionExecution_Status.SUCCESS) {\n return {\n success: true,\n logs: result.logs,\n result: result.result,\n };\n } else {\n return {\n success: false,\n logs: result.logs,\n result: result.result || response.result,\n error: result.result || response.result || \"Script execution failed with unknown error\",\n };\n }\n}\n","import { renderFor } from \"@tailor-platform/shared/color\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { styles, symbols } from \"./logger\";\n\nconst FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\nconst FRAME_INTERVAL_MS = 80;\n\nconst CURSOR_HIDE = \"\\x1B[?25l\";\nconst CURSOR_SHOW = \"\\x1B[?25h\";\nconst CLEAR_LINE = \"\\x1B[2K\";\nconst CURSOR_TO_START = \"\\r\";\nconst CURSOR_UP = \"\\x1B[1A\";\n// DEC mode 2026: synchronized output. Brackets a frame redraw so supporting\n// terminals render the clear+rewrite atomically and avoid flicker on slow links.\nconst SYNC_BEGIN = \"\\x1B[?2026h\";\nconst SYNC_END = \"\\x1B[?2026l\";\n\n// eslint-disable-next-line no-control-regex -- ANSI escapes include ESC (U+001B) by definition\nconst ANSI_RE = /\\u001B\\[[0-9;]*[a-zA-Z]/g;\n\nfunction visibleLength(s: string): number {\n return s.replace(ANSI_RE, \"\").length;\n}\n\nexport type SpinnerOptions = {\n indent?: number;\n stream?: NodeJS.WriteStream;\n};\n\nconst activeSpinners = new Set<Spinner>();\nlet exitHookInstalled = false;\nlet signalHookInstalled = false;\n\nfunction installExitHook(): void {\n if (exitHookInstalled) return;\n exitHookInstalled = true;\n // Restore the terminal cursor when the process exits even if a spinner is still active\n // (e.g. on Ctrl+C the SIGINT handler typically calls process.exit which fires this).\n process.on(\"exit\", () => {\n for (const s of activeSpinners) {\n s.cleanupOnExit();\n }\n });\n}\n\nfunction installSignalHook(): void {\n if (signalHookInstalled) return;\n signalHookInstalled = true;\n // Clear the spinner's drawn line on Ctrl+C so any subsequent stderr output\n // (e.g. politty's \"✖ Process interrupted\") starts at column 0 on its own\n // line instead of being appended after the spinner frame and the\n // TTY-echoed \"^C\".\n //\n // We use prependListener so our handler runs before any pre-existing one.\n // In particular, politty registers an async SIGINT handler whose body runs\n // synchronously up to its first `await`, and that prefix calls\n // `logger.error(\"Process interrupted\")`. If our handler were appended, the\n // error message would already have been written to stderr — appended after\n // the spinner frame on the same line — by the time we got control. Running\n // first lets us tear down the spinner line cleanly first.\n const handler = (): void => {\n for (const s of activeSpinners) s.stop();\n };\n process.prependListener(\"SIGINT\", handler);\n process.prependListener(\"SIGTERM\", handler);\n}\n\nexport class Spinner {\n text: string;\n readonly #indent: number;\n readonly #stream: NodeJS.WriteStream;\n readonly #isEnabled: boolean;\n #frame = 0;\n #timer?: NodeJS.Timeout;\n #linesDrawn = 0;\n #started = false;\n\n constructor(options: SpinnerOptions = {}) {\n this.text = \"\";\n this.#indent = options.indent ?? 0;\n this.#stream = options.stream ?? process.stderr;\n this.#isEnabled = Boolean(this.#stream.isTTY);\n }\n\n start(text?: string): this {\n if (text !== undefined) this.text = text;\n\n if (!this.#isEnabled) {\n this.#writeLine(`- ${this.text}`);\n return this;\n }\n\n if (this.#started) {\n // Already running; just update text. The next render frame will pick it up.\n return this;\n }\n\n installExitHook();\n installSignalHook();\n activeSpinners.add(this);\n this.#started = true;\n this.#stream.write(CURSOR_HIDE);\n this.#renderFrame();\n this.#timer = setInterval(() => this.#renderFrame(), FRAME_INTERVAL_MS);\n if (typeof this.#timer.unref === \"function\") this.#timer.unref();\n return this;\n }\n\n stop(): this {\n if (!this.#started) return this;\n this.#started = false;\n if (this.#timer) {\n clearInterval(this.#timer);\n this.#timer = undefined;\n }\n if (this.#isEnabled) {\n this.#clearDrawn();\n this.#stream.write(CURSOR_SHOW);\n }\n activeSpinners.delete(this);\n return this;\n }\n\n succeed(text?: string): this {\n return this.#stopAndPersist(symbols.success, text);\n }\n\n fail(text?: string): this {\n return this.#stopAndPersist(symbols.error, text);\n }\n\n warn(text?: string): this {\n return this.#stopAndPersist(symbols.warning, text);\n }\n\n /**\n * Called by the global exit hook to restore the cursor.\n * @internal\n */\n cleanupOnExit(): void {\n if (this.#timer) {\n clearInterval(this.#timer);\n this.#timer = undefined;\n }\n if (this.#isEnabled) {\n this.#stream.write(CURSOR_SHOW);\n }\n }\n\n #stopAndPersist(symbol: string, text?: string): this {\n if (text !== undefined) this.text = text;\n if (this.#started) {\n this.#started = false;\n if (this.#timer) {\n clearInterval(this.#timer);\n this.#timer = undefined;\n }\n if (this.#isEnabled) {\n this.#clearDrawn();\n this.#stream.write(CURSOR_SHOW);\n }\n activeSpinners.delete(this);\n }\n this.#writeLine(`${symbol} ${this.text}`);\n return this;\n }\n\n #renderFrame(): void {\n this.#stream.write(SYNC_BEGIN);\n this.#clearDrawn();\n const frame = styles.info(\n FRAMES[this.#frame] ?? assertDefined(FRAMES[0], \"spinner frames empty\"),\n );\n this.#frame = (this.#frame + 1) % FRAMES.length;\n const indent = \" \".repeat(this.#indent);\n const line = `${indent}${frame} ${this.text}`;\n this.#stream.write(renderFor(this.#stream, line));\n this.#stream.write(SYNC_END);\n const cols = this.#stream.columns || 80;\n this.#linesDrawn = Math.max(1, Math.ceil(visibleLength(line) / cols));\n }\n\n #clearDrawn(): void {\n if (this.#linesDrawn === 0) return;\n this.#stream.write(CURSOR_TO_START);\n this.#stream.write(CLEAR_LINE);\n for (let i = 1; i < this.#linesDrawn; i++) {\n this.#stream.write(CURSOR_UP);\n this.#stream.write(CLEAR_LINE);\n }\n this.#linesDrawn = 0;\n }\n\n #writeLine(content: string): void {\n const indent = \" \".repeat(this.#indent);\n this.#stream.write(renderFor(this.#stream, `${indent}${content}\\n`));\n }\n}\n\n/**\n * Create a terminal spinner. Falls back to a single line write in non-TTY\n * environments so output stays useful in CI logs.\n * @param options - Spinner options\n * @returns A Spinner instance\n */\nexport function spinner(options?: SpinnerOptions): Spinner {\n return new Spinner(options);\n}\n","/**\n * Migration execution service for TailorDB migrations\n *\n * Handles detection and execution of pending migration scripts via TestExecScript API.\n */\n\nimport * as fs from \"node:fs\";\nimport { create } from \"@bufbuild/protobuf\";\nimport {\n AuthInvokerSchema,\n type AuthInvoker,\n} from \"@tailor-platform/tailor-proto/auth_resource_pb\";\nimport { bundleMigrationScript } from \"#/cli/commands/tailordb/migrate/bundler\";\nimport { type NamespaceWithMigrations } from \"#/cli/commands/tailordb/migrate/config\";\nimport { formatMigrationScriptCommand } from \"#/cli/commands/tailordb/migrate/hints\";\nimport {\n loadDiff,\n getMigrationFiles,\n getMigrationFilePath,\n formatMigrationNumber,\n} from \"#/cli/commands/tailordb/migrate/snapshot\";\nimport {\n type PendingMigration,\n MIGRATION_HISTORY_LABEL_KEY,\n MIGRATION_LABEL_KEY,\n parseMigrationLabelNumber,\n sanitizeMigrationLabel,\n} from \"#/cli/commands/tailordb/migrate/types\";\nimport { isNotFoundError, type OperatorClient } from \"#/cli/shared/client\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { executeScript } from \"#/cli/shared/script-executor\";\nimport { spinner } from \"#/cli/shared/spinner\";\nimport { resourceTrn, writeMetadataLabels } from \"../label\";\nimport type { TailorDBServiceConfig } from \"#/types/tailordb.generated\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface MigrationExecutionOptions {\n client: OperatorClient;\n workspaceId: string;\n invoker: AuthInvoker;\n env: Record<string, string | number | boolean>;\n configDir: string;\n}\n\n/**\n * Context for migration execution with per-namespace configuration\n */\nexport interface MigrationContext {\n client: OperatorClient;\n workspaceId: string;\n authNamespace: string;\n machineUsers: string[] | undefined;\n dbConfig: Record<string, TailorDBServiceConfig | undefined>;\n env: Record<string, string | number | boolean>;\n configDir: string;\n}\n\ninterface ExecutionResult {\n namespace: string;\n migrationNumber: number;\n success: boolean;\n logs?: string;\n error?: string;\n}\n\n// ============================================================================\n// Migration Detection\n// ============================================================================\n\n/**\n * Get the current migration label from TailorDB Service metadata\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {string} namespace - TailorDB namespace\n * @returns {Promise<number>} Current migration number (0 if none)\n */\nasync function getCurrentMigrationNumber(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n): Promise<number> {\n try {\n const trn = resourceTrn(workspaceId, \"tailordb\", namespace);\n\n const { metadata } = await client.getMetadata({ trn });\n\n const label = metadata?.labels[MIGRATION_LABEL_KEY];\n\n if (!label) {\n return 0;\n }\n const num = parseMigrationLabelNumber(label);\n return num ?? 0;\n } catch (error) {\n if (isNotFoundError(error)) {\n return 0;\n }\n throw error;\n }\n}\n\n/**\n * Detect pending migrations that need to be executed\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {NamespaceWithMigrations[]} namespacesWithMigrations - Namespaces with migrations config\n * @param {string} [configPath] - Config file path, included in remediation guidance when provided\n * @param {ReadonlyMap<string, number>} [currentMigrationOverrides] - Confirmed current migration numbers to use instead of remote metadata\n * @returns {Promise<PendingMigration[]>} List of pending migrations\n */\nexport async function detectPendingMigrations(\n client: OperatorClient,\n workspaceId: string,\n namespacesWithMigrations: NamespaceWithMigrations[],\n configPath?: string,\n currentMigrationOverrides?: ReadonlyMap<string, number>,\n): Promise<PendingMigration[]> {\n const pendingMigrations: PendingMigration[] = [];\n\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n // Get current applied migration number\n const currentMigration =\n currentMigrationOverrides?.get(namespace) ??\n (await getCurrentMigrationNumber(client, workspaceId, namespace));\n\n // Get all migration files\n const migrationFiles = getMigrationFiles(migrationsDir);\n\n // Find migrations that haven't been applied yet\n for (const file of migrationFiles) {\n if (file.number <= currentMigration) {\n continue;\n }\n\n // Check for diff file (all migrations must have a diff)\n const diffPath = getMigrationFilePath(migrationsDir, file.number, \"diff\");\n if (!fs.existsSync(diffPath)) {\n continue;\n }\n\n // Load the diff to inspect breaking/warning classification\n const diff = loadDiff(diffPath);\n\n // The migration script is executed when migrate.ts exists on disk.\n // Breaking changes hard-require a script unless the user recorded an\n // explicit skip acknowledgment; warnings (e.g. field_removed) may\n // optionally have one added via `tailordb migration script <num>`.\n const scriptPath = getMigrationFilePath(migrationsDir, file.number, \"migrate\");\n const hasScript = fs.existsSync(scriptPath);\n if (diff.requiresMigrationScript && !hasScript && !diff.scriptSkipped) {\n const commandOptions = { migrationNumber: file.number, namespace, configPath };\n throw new Error(\n `Migration ${namespace}/${formatMigrationNumber(file.number)} requires a migration script but migrate.ts was not found.\\n` +\n `To resolve, either:\\n` +\n ` - Add a script: ${formatMigrationScriptCommand(commandOptions)}\\n` +\n ` - Or record that no script is needed: ${formatMigrationScriptCommand({ ...commandOptions, noScript: true })}`,\n );\n }\n if (diff.scriptSkipped) {\n const migrationLabel = `${namespace}/${formatMigrationNumber(file.number)}`;\n if (hasScript) {\n logger.warn(\n `Migration ${migrationLabel} has both a skip acknowledgment and migrate.ts; executing migrate.ts.`,\n );\n } else {\n logger.info(\n `Migration ${migrationLabel} runs without a script (skip acknowledged at ${diff.scriptSkipped.acknowledgedAt}: ${diff.scriptSkipped.reason})`,\n );\n }\n }\n\n pendingMigrations.push({\n number: file.number,\n scriptPath,\n hasScript,\n diffPath,\n namespace,\n migrationsDir,\n diff,\n });\n }\n }\n\n // Sort by namespace and migration number\n return pendingMigrations.toSorted((a, b) => {\n if (a.namespace !== b.namespace) {\n return a.namespace.localeCompare(b.namespace);\n }\n return a.number - b.number;\n });\n}\n\n// ============================================================================\n// Migration Execution\n// ============================================================================\n\n/**\n * Execute a single migration script\n * @param {MigrationExecutionOptions} options - Execution options\n * @param {PendingMigration} migration - Migration to execute\n * @returns {Promise<ExecutionResult>} Execution result\n */\nasync function executeSingleMigration(\n options: MigrationExecutionOptions,\n migration: PendingMigration,\n): Promise<ExecutionResult> {\n const { client, workspaceId, invoker, env, configDir } = options;\n\n const migrationName = `migration-${migration.namespace}-${formatMigrationNumber(migration.number)}.js`;\n\n // Bundle the migration script\n const bundleResult = await bundleMigrationScript(\n migration.scriptPath,\n migration.namespace,\n migration.number,\n env,\n configDir,\n );\n\n // Execute the script using the shared script executor\n const result = await executeScript({\n client,\n workspaceId,\n name: migrationName,\n code: bundleResult.bundledCode,\n invoker,\n });\n\n return {\n namespace: migration.namespace,\n migrationNumber: migration.number,\n success: result.success,\n logs: result.logs,\n error: result.error,\n };\n}\n\n/**\n * Update the migration label on TailorDB Service metadata\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {string} namespace - TailorDB namespace\n * @param {number} migrationNumber - Migration number to set\n * @param historyId - Optional migration history ID to set atomically with the checkpoint\n * @returns {Promise<void>}\n */\nexport async function updateMigrationLabel(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n migrationNumber: number,\n historyId?: string,\n): Promise<void> {\n const trn = resourceTrn(workspaceId, \"tailordb\", namespace);\n\n await writeMetadataLabels(client, {\n trn,\n labels: {\n [MIGRATION_LABEL_KEY]: sanitizeMigrationLabel(migrationNumber),\n ...(historyId ? { [MIGRATION_HISTORY_LABEL_KEY]: historyId } : {}),\n },\n remove: historyId ? undefined : [MIGRATION_HISTORY_LABEL_KEY],\n });\n}\n\n/**\n * Execute all pending migrations, grouping by namespace and using appropriate machine user\n * @param {MigrationContext} context - Migration context with per-namespace configuration\n * @param {PendingMigration[]} migrations - Migrations to execute\n * @returns {Promise<void>}\n */\nexport async function executeMigrations(\n context: MigrationContext,\n migrations: PendingMigration[],\n): Promise<void> {\n // Run migrate.ts whenever the file exists on disk. Required for breaking changes,\n // optional for warning-tier changes (e.g. field_removed).\n const migrationsWithScripts = migrations.filter((m) => m.hasScript);\n\n if (migrationsWithScripts.length === 0) {\n return;\n }\n\n // Group migrations by namespace\n const migrationsByNamespace = groupMigrationsByNamespace(migrationsWithScripts);\n\n // Execute migrations for each namespace with appropriate machine user\n for (const [namespace, namespaceMigrations] of migrationsByNamespace) {\n const dbConfig = context.dbConfig[namespace];\n const migrationConfig = dbConfig?.migration;\n\n // Get machine user name for this namespace\n const machineUserName = getMigrationMachineUser(migrationConfig, context.machineUsers);\n if (!machineUserName) {\n throw new Error(\n `No machine user available for migration execution in namespace '${namespace}'. ` +\n \"Either configure 'migration.machineUser' in db config or define machine users in auth config.\",\n );\n }\n\n const invoker = create(AuthInvokerSchema, {\n namespace: context.authNamespace,\n machineUserName,\n });\n\n const options: MigrationExecutionOptions = {\n client: context.client,\n workspaceId: context.workspaceId,\n invoker,\n env: context.env,\n configDir: context.configDir,\n };\n\n logger.info(`Using machine user: ${styles.bold(machineUserName)} for namespace '${namespace}'`);\n\n for (const migration of namespaceMigrations) {\n const migrationLabel = `${migration.namespace}/${formatMigrationNumber(migration.number)}`;\n const sp = spinner().start(`Executing migration ${migrationLabel}...`);\n\n const result = await executeSingleMigration(options, migration);\n\n if (result.success) {\n sp.succeed(`Migration ${migrationLabel} completed successfully`);\n\n // Show logs if any\n if (result.logs && result.logs.trim()) {\n logger.log(`Logs:\\n${result.logs}`);\n }\n } else {\n sp.fail(`Migration ${migrationLabel} failed`);\n if (result.logs) {\n logger.error(`Logs:\\n${result.logs}`);\n }\n throw new Error(result.error ?? \"Migration failed\");\n }\n }\n }\n}\n\n/**\n * Get the machine user name for migration execution\n *\n * Priority:\n * 1. machineUser from migration config (if set)\n * 2. First machine user from auth config\n * @param {object | undefined} migrationConfig - Migration config for namespace\n * @param {string[] | undefined} machineUsers - Machine users from auth config\n * @returns {string | undefined} Machine user name or undefined if none available\n */\nexport function getMigrationMachineUser(\n migrationConfig: { machineUser?: string } | undefined,\n machineUsers: string[] | undefined,\n): string | undefined {\n // Priority 1: Explicit config\n if (migrationConfig?.machineUser) {\n return migrationConfig.machineUser;\n }\n\n // Priority 2: First machine user from auth\n if (machineUsers && machineUsers.length > 0) {\n return machineUsers[0];\n }\n\n return undefined;\n}\n\n/**\n * Group migrations by namespace\n * @param {PendingMigration[]} migrations - Migrations to group\n * @returns {Map<string, PendingMigration[]>} Migrations grouped by namespace\n */\nexport function groupMigrationsByNamespace(\n migrations: PendingMigration[],\n): Map<string, PendingMigration[]> {\n const grouped = new Map<string, PendingMigration[]>();\n for (const migration of migrations) {\n const existing = grouped.get(migration.namespace) ?? [];\n existing.push(migration);\n grouped.set(migration.namespace, existing);\n }\n return grouped;\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport {\n type CreateTailorDBGQLPermissionRequestSchema,\n type CreateTailorDBServiceRequestSchema,\n type CreateTailorDBTypeRequestSchema,\n type DeleteTailorDBGQLPermissionRequestSchema,\n type DeleteTailorDBServiceRequestSchema,\n type DeleteTailorDBTypeRequestSchema,\n type UpdateTailorDBGQLPermissionRequestSchema,\n type UpdateTailorDBTypeRequestSchema,\n} from \"@tailor-platform/tailor-proto/tailordb_pb\";\nimport { TailorDBTypeSchema } from \"@tailor-platform/tailor-proto/tailordb_resource_pb\";\nimport * as path from \"pathe\";\nimport {\n getNamespacesWithMigrations,\n type NamespaceWithMigrations,\n} from \"#/cli/commands/tailordb/migrate/config\";\nimport { captureMigrationFileState } from \"#/cli/commands/tailordb/migrate/file-state\";\nimport {\n applyPreMigrationFieldAdjustments,\n applyPreMigrationIndexAdjustments,\n buildPreMigrationChangesMap,\n buildPreMigrationIndexChangesMap,\n createPreMigrationSnapshotType,\n} from \"#/cli/commands/tailordb/migrate/pre-migration-schema\";\nimport { fetchRemoteMigrationState } from \"#/cli/commands/tailordb/migrate/remote-state\";\nimport {\n checkMigrationDiffs,\n formatMigrationCheckResults,\n formatRemoteVerificationResults,\n logRemoteDriftGuidance,\n toTailorDBDeployInput,\n verifyRemoteSchema,\n type TailorDBDeployInput,\n} from \"#/cli/commands/tailordb/migrate/schema-checks\";\nimport {\n reconstructSnapshotFromMigrations,\n assertValidMigrationFiles,\n formatMigrationNumber,\n getLatestMigrationNumber,\n getMigrationFiles,\n INITIAL_SCHEMA_NUMBER,\n type SchemaSnapshot,\n type TailorDBSnapshotType,\n} from \"#/cli/commands/tailordb/migrate/snapshot\";\nimport {\n generateTailorDBTypeManifestFromSnapshot,\n protoGqlPermission,\n} from \"#/cli/commands/tailordb/migrate/snapshot-manifest\";\nimport { handleOptionalToRequiredError } from \"#/cli/commands/tailordb/migrate/types\";\nimport { byName } from \"#/cli/shared/apply-concurrency\";\nimport { fetchAllTolerant, type OperatorClient } from \"#/cli/shared/client\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertNoPublishEventsConflict, publishEventsConflict } from \"#/cli/shared/publish-events\";\nimport { createChangeSet, type HasName, type ChangeSet } from \"../change-set\";\nimport { areNormalizedEqual, normalizeProtoConfig, toComparableProtoJson } from \"../compare\";\nimport { ACTION_SYMBOLS, type DisplayAction, type GroupedDisplayEntry } from \"../grouped-display\";\nimport {\n addDependencyRecords,\n buildMetaRequest,\n type DependentAppsByResource,\n eventSourceKey,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n tailorDBTypeTrn,\n writeMetadataLabels,\n} from \"../label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"../owned-resource\";\nimport {\n executeMigrations,\n detectPendingMigrations,\n updateMigrationLabel,\n type MigrationContext,\n} from \"./migration\";\nimport type {\n FieldDiffChange,\n TypeScriptsModifiedChange,\n} from \"#/cli/commands/tailordb/migrate/diff-calculator\";\nimport type {\n MigrationCheckpointRepair,\n PendingMigration,\n} from \"#/cli/commands/tailordb/migrate/types\";\nimport type { LoadedConfig } from \"#/cli/shared/config-loader\";\nimport type { TailorDBServiceConfig } from \"#/types/tailordb.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"../confirm\";\nimport type { ApplyPhase, PlanContext } from \"../types\";\n\n// ============================================================================\n// Migration Validation\n// ============================================================================\n\ntype ValidateAndDetectResult = {\n pendingMigrations: PendingMigration[];\n checkpointRepairs: MigrationCheckpointRepair[];\n namespacesWithMigrations: NamespaceWithMigrations[];\n migrationFileState: Record<string, string>;\n migrationHistoryIds: Record<string, string | null>;\n};\n\nexport { captureMigrationFileState } from \"#/cli/commands/tailordb/migrate/file-state\";\n\nfunction migrationFileStatesEqual(\n planned: Readonly<Record<string, string>>,\n current: Readonly<Record<string, string>>,\n): boolean {\n const plannedNamespaces = Object.keys(planned).toSorted();\n const currentNamespaces = Object.keys(current).toSorted();\n return (\n plannedNamespaces.length === currentNamespaces.length &&\n plannedNamespaces.every(\n (namespace, index) =>\n namespace === currentNamespaces[index] && planned[namespace] === current[namespace],\n )\n );\n}\n\n/**\n * Validate migration files and detect pending migrations\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {ReadonlyMap<string, Record<string, TailorDBSnapshotType>>} typesByNamespace - Types by namespace\n * @param {LoadedConfig} config - Loaded application config (includes path)\n * @param {boolean} noSchemaCheck - Whether to skip schema diff check\n * @param {ReadonlyArray<TailorDBDeployInput>} tailorDBInputs - Deploy inputs for namespace defaults\n * @returns {Promise<ValidateAndDetectResult>} Pending migrations and namespaces that have migration directories configured\n */\nexport async function validateAndDetectMigrations(\n client: OperatorClient,\n workspaceId: string,\n typesByNamespace: ReadonlyMap<string, Record<string, TailorDBSnapshotType>>,\n config: LoadedConfig,\n noSchemaCheck: boolean,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n): Promise<ValidateAndDetectResult> {\n const configDir = path.dirname(config.path);\n const namespacesWithMigrations = getNamespacesWithMigrations(config, configDir);\n let pendingMigrations: PendingMigration[] = [];\n let checkpointRepairs: MigrationCheckpointRepair[] = [];\n const migrationHistoryIds = Object.create(null) as Record<string, string | null>;\n\n if (namespacesWithMigrations.length > 0) {\n // Validate migration file integrity (sequential numbers, no gaps, no duplicates)\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n assertValidMigrationFiles(migrationsDir, namespace);\n migrationHistoryIds[namespace] =\n reconstructSnapshotFromMigrations(migrationsDir)?.rebaseline?.historyId ?? null;\n }\n\n // Check for schema diffs if not skipped\n if (!noSchemaCheck) {\n // 1. Check local types vs local snapshot (existing check)\n const migrationResults = await checkMigrationDiffs(\n typesByNamespace,\n namespacesWithMigrations,\n );\n const hasDiffs = migrationResults.some((r) => r.hasDiff);\n\n if (hasDiffs) {\n logger.error(\"Schema changes detected that are not in migration files:\");\n logger.log(formatMigrationCheckResults(migrationResults));\n logger.newline();\n logger.info(\"Run 'tailor tailordb migration generate' to create migration files.\");\n logger.info(\"Or use '--no-schema-check' to skip this check.\");\n throw new Error(\"Schema migration check failed\");\n }\n\n // 2. Check remote schema vs local snapshot (new check)\n const remoteVerificationResults = await verifyRemoteSchema(\n client,\n workspaceId,\n namespacesWithMigrations,\n config,\n tailorDBInputs,\n );\n checkpointRepairs = remoteVerificationResults.flatMap((result) =>\n result.checkpointRepair\n ? [{ namespace: result.namespace, ...result.checkpointRepair }]\n : [],\n );\n const missingCheckpointResults = remoteVerificationResults.filter(\n (result) => result.checkpointMissingLocal,\n );\n if (missingCheckpointResults.length > 0) {\n logger.error(\"Remote migration checkpoint is not in the local migration history:\");\n for (const result of missingCheckpointResults) {\n logger.log(\n ` ${result.namespace}: ${formatMigrationNumber(result.remoteMigrationNumber)}`,\n );\n }\n logger.newline();\n logger.info(\n \"Pull the latest migration files, or run 'tailor tailordb migration status' to compare.\",\n );\n throw new Error(\"Remote migration checkpoint verification failed\");\n }\n const hasRemoteDrift = remoteVerificationResults.some((r) => r.hasDrift);\n\n if (hasRemoteDrift) {\n logger.error(\"Remote schema drift detected:\");\n logger.log(formatRemoteVerificationResults(remoteVerificationResults));\n logger.newline();\n logRemoteDriftGuidance();\n logger.newline();\n logger.info(\"Use '--no-schema-check' to skip this check (not recommended).\");\n throw new Error(\"Remote schema verification failed\");\n }\n for (const repair of checkpointRepairs) {\n logger.warn(\n `Remote migration checkpoint for ${repair.namespace} will be reset to 0000 after confirmation (${formatMigrationNumber(repair.from)} → 0000); the remote schema already matches the local baseline.`,\n );\n }\n }\n\n // Detect pending migrations (migration scripts that haven't been executed yet)\n const currentMigrationOverrides = new Map(\n checkpointRepairs.map((repair) => [repair.namespace, repair.to]),\n );\n pendingMigrations = await detectPendingMigrations(\n client,\n workspaceId,\n namespacesWithMigrations,\n config.path,\n currentMigrationOverrides,\n );\n\n if (pendingMigrations.length > 0) {\n logger.newline();\n\n // Classify migrations by whether a migrate.ts will run for them.\n const withScripts = pendingMigrations.filter((m) => m.hasScript);\n const withoutScripts = pendingMigrations.filter((m) => !m.hasScript);\n\n logger.info(`${pendingMigrations.length} pending migration(s) will be applied:`);\n if (withoutScripts.length > 0) {\n logger.info(\n ` • ${withoutScripts.length} schema change(s) (applied automatically with schema deployment)`,\n { mode: \"plain\" },\n );\n }\n if (withScripts.length > 0) {\n logger.info(\n ` • ${withScripts.length} data migration(s) (requires migration script execution)`,\n { mode: \"plain\" },\n );\n }\n }\n }\n\n return {\n pendingMigrations,\n checkpointRepairs,\n namespacesWithMigrations,\n migrationFileState: captureMigrationFileState(namespacesWithMigrations),\n migrationHistoryIds,\n };\n}\n\n/**\n * Reconcile each namespace's migration checkpoint and history ID to\n * the working tree after a create-update apply.\n *\n * This records the initial baseline (`0000`), which is deployed via the normal\n * flow and never bumps the label itself, and keeps the label `<= working_tree_max`\n * after a `--no-schema-check` deploy from an older revision. Namespaces without a\n * baseline are skipped so no phantom label is written.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param namespacesWithMigrations - Namespaces that have migration directories configured\n * @param migrationHistoryIds - Migration history ID captured during preflight for each namespace\n */\nasync function reconcileMigrationLabels(\n client: OperatorClient,\n workspaceId: string,\n namespacesWithMigrations: NamespaceWithMigrations[],\n migrationHistoryIds: Readonly<Record<string, string | null>>,\n): Promise<void> {\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n if (getMigrationFiles(migrationsDir).length === 0) {\n continue;\n }\n const targetVersion = getLatestMigrationNumber(migrationsDir);\n const historyId = migrationHistoryIds[namespace] ?? null;\n const remoteState = await fetchRemoteMigrationState(\n client,\n resourceTrn(workspaceId, \"tailordb\", namespace),\n ).catch(() => null);\n const currentVersion = remoteState?.number ?? null;\n if (remoteState && currentVersion === targetVersion && remoteState.historyId === historyId) {\n continue;\n }\n await updateMigrationLabel(\n client,\n workspaceId,\n namespace,\n targetVersion,\n historyId ?? undefined,\n );\n if (remoteState) {\n const from = currentVersion === null ? \"<unset>\" : formatMigrationNumber(currentVersion);\n logger.info(\n `Migration label for namespace ${namespace} reconciled: ${from} → ${formatMigrationNumber(targetVersion)}.`,\n );\n } else {\n logger.info(\n `Migration label for namespace ${namespace} reconciled to ${formatMigrationNumber(targetVersion)}.`,\n );\n }\n }\n}\n\n/**\n * Build migration execution context for script-based migrations.\n * @param client - Operator client instance\n * @param migrationContext - Planned TailorDB context\n * @param migrationsRequiringScripts - Migrations that require scripts\n * @returns Migration context for script execution\n */\nfunction buildMigrationContextForScripts(\n client: OperatorClient,\n migrationContext: Awaited<ReturnType<typeof planTailorDB>>[\"context\"],\n migrationsRequiringScripts: PendingMigration[],\n): MigrationContext {\n const authService = migrationContext.application.authService;\n if (!authService) {\n throw new Error(\"Auth configuration is required to execute migration scripts.\");\n }\n\n const dbConfigMap: Record<string, TailorDBServiceConfig | undefined> = {};\n for (const migration of migrationsRequiringScripts) {\n if (!(migration.namespace in dbConfigMap)) {\n dbConfigMap[migration.namespace] = migrationContext.config.db?.[migration.namespace] as\n | TailorDBServiceConfig\n | undefined;\n }\n }\n\n return {\n client,\n workspaceId: migrationContext.workspaceId,\n authNamespace: authService.config.name,\n machineUsers: authService.config.machineUsers\n ? Object.keys(authService.config.machineUsers)\n : undefined,\n dbConfig: dbConfigMap,\n env: migrationContext.config.env ?? {},\n configDir: path.dirname(migrationContext.config.path),\n };\n}\n\ntype TailorDBPlanResult = Awaited<ReturnType<typeof planTailorDB>>;\n\nasync function validateTailorDBMigrationState(\n client: OperatorClient,\n result: TailorDBPlanResult,\n): Promise<ValidateAndDetectResult> {\n const { context } = result;\n if (context.migrationTestBaselines) {\n const currentMigrationFileState = captureMigrationFileState(\n getNamespacesWithMigrations(context.config, path.dirname(context.config.path)),\n );\n if (!migrationFileStatesEqual(context.migrationFileState, currentMigrationFileState)) {\n throw new Error(\n \"Migration files changed after deployment planning. Run the migration test again to create a fresh plan.\",\n );\n }\n return {\n pendingMigrations: [],\n checkpointRepairs: [],\n namespacesWithMigrations: [],\n migrationFileState: currentMigrationFileState,\n migrationHistoryIds: {},\n };\n }\n const typesByNamespace = new Map<string, Record<string, TailorDBSnapshotType>>();\n for (const tailordb of context.tailorDBInputs) {\n typesByNamespace.set(tailordb.namespace, tailordb.types);\n }\n\n const validation = await validateAndDetectMigrations(\n client,\n context.workspaceId,\n typesByNamespace,\n context.config,\n context.noSchemaCheck,\n context.tailorDBInputs,\n );\n const approvedRepairs = context.checkpointRepairs;\n const repairPlanChanged =\n approvedRepairs.length !== validation.checkpointRepairs.length ||\n validation.checkpointRepairs.some(\n (repair) =>\n !approvedRepairs.some(\n (approved) =>\n approved.namespace === repair.namespace &&\n approved.from === repair.from &&\n approved.fromHistoryId === repair.fromHistoryId &&\n approved.toHistoryId === repair.toHistoryId,\n ),\n );\n if (repairPlanChanged) {\n throw new Error(\n \"Remote migration checkpoint repair changed after deployment planning. Run the deployment again to review the updated repair.\",\n );\n }\n if (!migrationFileStatesEqual(context.migrationFileState, validation.migrationFileState)) {\n throw new Error(\n \"Migration files changed after deployment planning. Run the deployment again to create a fresh plan.\",\n );\n }\n return validation;\n}\n\n/**\n * Revalidate migration state before the deployment enters any mutation phase.\n * @param client - Operator client instance\n * @param result - Planned TailorDB changes\n */\nexport async function preflightTailorDB(\n client: OperatorClient,\n result: TailorDBPlanResult,\n): Promise<void> {\n await validateTailorDBMigrationState(client, result);\n}\n\n/**\n * Apply TailorDB-related changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned TailorDB changes\n * @param phase - Apply phase (defaults to \"create-update\")\n */\nexport async function applyTailorDB(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planTailorDB>>,\n phase: Exclude<ApplyPhase, \"delete\"> = \"create-update\",\n): Promise<void> {\n const { changeSet, context: migrationContext } = result;\n\n if (phase === \"create-update\") {\n // Plan-time validation makes dry runs fail fast. Repeat the full validation\n // at the apply boundary because migration files, remote checkpoints, or the\n // remote schema may have changed while waiting for confirmation.\n const { pendingMigrations, checkpointRepairs, namespacesWithMigrations, migrationHistoryIds } =\n await validateTailorDBMigrationState(client, result);\n\n for (const repair of checkpointRepairs) {\n await updateMigrationLabel(\n client,\n migrationContext.workspaceId,\n repair.namespace,\n repair.to,\n repair.toHistoryId,\n );\n logger.info(\n `Migration checkpoint for namespace ${repair.namespace} reset: ${formatMigrationNumber(repair.from)} → 0000.`,\n );\n }\n\n if (pendingMigrations.length > 0) {\n // Migration flow: Execute each migration sequentially (pre -> script -> post)\n // This ensures intermediate states are properly handled when scripts depend on them\n\n // Reset tracking state for this migration run\n processedTypes.reset();\n deletedResources.reset();\n migrationSnapshotCache.reset();\n\n // Step 1: Create/update services once at the beginning (services don't need per-migration handling)\n await executeServicesCreation(client, changeSet);\n\n // Step 1.5: The migration loop below only touches the namespaces of the\n // pending migrations; changes planned for every other namespace must go\n // through the normal flow or they would be silently dropped.\n // Creates/updates run before the loop so migration scripts see the\n // complete world; deletes are irreversible and stay last (Step 5).\n const migratingNamespaces = new Set(pendingMigrations.map((m) => m.namespace));\n const isOutsideMigrations = (namespaceName: string | undefined) =>\n namespaceName !== undefined && !migratingNamespaces.has(namespaceName);\n\n try {\n for (const create of changeSet.type.creates) {\n if (!isOutsideMigrations(create.request.namespaceName)) continue;\n await client.createTailorDBType(create.request);\n }\n for (const update of changeSet.type.updates) {\n if (!isOutsideMigrations(update.request.namespaceName)) continue;\n await client.updateTailorDBType(update.request);\n }\n } catch (error) {\n handleOptionalToRequiredError(error, [\n \"Run 'tailor tailordb migration generate' to create migration files.\",\n \"Migration scripts allow you to handle existing data before applying the schema change.\",\n ]);\n }\n await Promise.all([\n ...changeSet.gqlPermission.creates\n .filter((create) => isOutsideMigrations(create.request.namespaceName))\n .map((create) => client.createTailorDBGQLPermission(create.request)),\n ...changeSet.gqlPermission.updates\n .filter((update) => isOutsideMigrations(update.request.namespaceName))\n .map((update) => client.updateTailorDBGQLPermission(update.request)),\n ]);\n\n const migrationsRequiringScripts = pendingMigrations.filter((m) => m.hasScript);\n\n // Step 2: Build migration context for script execution (if any migrations require scripts)\n const migrationCtx =\n migrationsRequiringScripts.length > 0\n ? buildMigrationContextForScripts(client, migrationContext, migrationsRequiringScripts)\n : undefined;\n\n // Step 3: Execute each migration sequentially: pre -> script -> post\n if (migrationsRequiringScripts.length > 0) {\n logger.info(`Executing ${migrationsRequiringScripts.length} data migration(s)...`);\n logger.newline();\n }\n\n for (const migration of pendingMigrations) {\n try {\n // Pre-migration phase: Create/update types with breaking fields as optional\n await executeSingleMigrationPrePhase(\n client,\n changeSet,\n migration,\n migrationContext.tailorDBInputs,\n migrationContext.executorUsedTypes,\n );\n\n // Script execution (only if migrate.ts exists for this migration)\n if (migration.hasScript && migrationCtx) {\n await executeMigrations(migrationCtx, [migration]);\n }\n } catch (error) {\n await rollbackSingleMigrationAfterFailure(\n client,\n changeSet,\n migration,\n migrationContext.workspaceId,\n migrationContext.tailorDBInputs,\n migrationContext.executorUsedTypes,\n );\n throw error;\n }\n\n try {\n await executeSingleMigrationPostPhase(\n client,\n changeSet,\n migration,\n migrationContext.tailorDBInputs,\n migrationContext.executorUsedTypes,\n );\n } catch (error) {\n await rollbackSingleMigrationAfterFailure(\n client,\n changeSet,\n migration,\n migrationContext.workspaceId,\n migrationContext.tailorDBInputs,\n migrationContext.executorUsedTypes,\n );\n throw error;\n }\n\n try {\n await updateMigrationLabel(\n client,\n migrationContext.workspaceId,\n migration.namespace,\n migration.number,\n migrationHistoryIds[migration.namespace] ?? undefined,\n );\n } catch (error) {\n let remoteMigrationNumber: number | undefined;\n try {\n remoteMigrationNumber =\n (\n await fetchRemoteMigrationState(\n client,\n resourceTrn(migrationContext.workspaceId, \"tailordb\", migration.namespace),\n )\n ).number ?? undefined;\n } catch (readbackError) {\n logger.warn(\n `Could not verify migration checkpoint ${migration.namespace}/${formatMigrationNumber(migration.number)} after its update failed: ` +\n `${readbackError instanceof Error ? readbackError.message : String(readbackError)}. ` +\n \"Leaving the post-migration schema unchanged to avoid rolling back a committed checkpoint.\",\n );\n throw error;\n }\n\n if (remoteMigrationNumber !== undefined && remoteMigrationNumber > migration.number) {\n throw new Error(\n `Migration checkpoint ${migration.namespace}/${formatMigrationNumber(migration.number)} advanced concurrently to ${formatMigrationNumber(remoteMigrationNumber)}. ` +\n \"Leaving the post-migration schema unchanged and aborting this deployment.\",\n { cause: error },\n );\n }\n\n if (remoteMigrationNumber !== migration.number) {\n logger.warn(\n `Migration checkpoint ${migration.namespace}/${formatMigrationNumber(migration.number)} could not be confirmed after its update failed; remote remains at ${\n remoteMigrationNumber === undefined\n ? \"<unset>\"\n : formatMigrationNumber(remoteMigrationNumber)\n }. ` +\n \"Leaving the post-migration schema unchanged to avoid rolling back a concurrent deployment. Repair the checkpoint before retrying.\",\n );\n throw error;\n }\n }\n\n try {\n await executeSingleMigrationPostPhaseDeletions(client, changeSet, migration);\n } catch (error) {\n logger.warn(\n `Migration checkpoint ${migration.namespace}/${formatMigrationNumber(migration.number)} was committed, but post-checkpoint cleanup failed. ` +\n \"Remove the leftover resources manually before the next deployment; remote schema verification will fail closed until then.\",\n );\n throw error;\n }\n }\n\n if (migrationsRequiringScripts.length > 0) {\n logger.newline();\n logger.success(`All data migrations completed successfully.`);\n }\n\n // Step 4: Delete remaining GQL permissions that weren't deleted with their types\n const remainingGqlPermissionDeletes = changeSet.gqlPermission.deletes.filter((del) => {\n const permKey = `${del.request.namespaceName}/${del.name}`;\n return !deletedResources.gqlPermissions.has(permKey);\n });\n if (remainingGqlPermissionDeletes.length > 0) {\n await Promise.all(\n remainingGqlPermissionDeletes.map((del) =>\n client.deleteTailorDBGQLPermission(del.request),\n ),\n );\n }\n\n // Step 5: Delete types outside the migrating namespaces (their GQL\n // permissions were just removed above; migration postPhases never see them)\n await Promise.all(\n changeSet.type.deletes\n .filter(\n (del) =>\n isOutsideMigrations(del.request.namespaceName) &&\n !deletedResources.types.has(del.name),\n )\n .map((del) => client.deleteTailorDBType(del.request)),\n );\n\n // Step 6: Write type metadata, which the migration phases above do not.\n // Types inside migrating namespaces only exist once their phases have run,\n // so this waits until every type in the change set is present. Skipping it\n // would leave a cross-config dependency record unwritten on any deploy that\n // carries a migration, and the owner's next solo deploy would turn\n // publishing off without asking.\n await Promise.all(\n [...changeSet.type.creates, ...changeSet.type.updates, ...changeSet.type.unchanged]\n .filter((entry) => entry.metaRequest && !deletedResources.types.has(entry.name))\n .flatMap((entry) =>\n entry.metaRequest ? [writeMetadataLabels(client, entry.metaRequest)] : [],\n ),\n );\n } else {\n // Normal create-update flow without migrations\n // Services\n await Promise.all([\n ...changeSet.service.creates.map(async (create) => {\n await client.createTailorDBService(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.service.updates.map((update) =>\n writeMetadataLabels(client, update.metaRequest),\n ),\n ]);\n\n // Types. An unchanged type still gets its labels written, because its\n // dependency records can change while its schema does not.\n try {\n for (const create of changeSet.type.creates) {\n await client.createTailorDBType(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }\n for (const update of changeSet.type.updates) {\n await client.updateTailorDBType(update.request);\n await writeMetadataLabels(client, update.metaRequest);\n }\n await Promise.all(\n changeSet.type.unchanged.flatMap((entry) =>\n entry.metaRequest ? [writeMetadataLabels(client, entry.metaRequest)] : [],\n ),\n );\n } catch (error) {\n handleOptionalToRequiredError(error, [\n \"Run 'tailor tailordb migration generate' to create migration files.\",\n \"Migration scripts allow you to handle existing data before applying the schema change.\",\n ]);\n }\n\n // GQLPermissions\n await Promise.all([\n ...changeSet.gqlPermission.creates.map((create) =>\n client.createTailorDBGQLPermission(create.request),\n ),\n ...changeSet.gqlPermission.updates.map((update) =>\n client.updateTailorDBGQLPermission(update.request),\n ),\n ]);\n\n // Delete resources (only when no migrations occurred)\n // Migrations already handle deletions in post-migration phase\n await Promise.all(\n changeSet.gqlPermission.deletes.map((del) =>\n client.deleteTailorDBGQLPermission(del.request),\n ),\n );\n await Promise.all(\n changeSet.type.deletes.map((del) => client.deleteTailorDBType(del.request)),\n );\n }\n\n // Skip when pending migrations ran: each already bumped the label, and\n // re-pinning to working_tree_max could mask one left intentionally pending\n // (e.g. a missing script). --no-schema-check always re-pins to repair drift.\n if (\n namespacesWithMigrations.length > 0 &&\n (migrationContext.noSchemaCheck || pendingMigrations.length === 0)\n ) {\n await reconcileMigrationLabels(\n client,\n migrationContext.workspaceId,\n namespacesWithMigrations,\n migrationHistoryIds,\n );\n }\n } else if (phase === \"delete-resources\") {\n // Delete GQL permissions first, then types\n await Promise.all(\n changeSet.gqlPermission.deletes.map((del) => client.deleteTailorDBGQLPermission(del.request)),\n );\n await Promise.all(changeSet.type.deletes.map((del) => client.deleteTailorDBType(del.request)));\n } else {\n // Services only\n await Promise.all(\n changeSet.service.deletes.map((del) => client.deleteTailorDBService(del.request)),\n );\n }\n}\n\n// ============================================================================\n// Error Handling Helpers\n// ============================================================================\n\n// ============================================================================\n// Migration Execution Helpers\n// ============================================================================\n\ntype TailorDBChangeSet = Awaited<ReturnType<typeof planTailorDB>>[\"changeSet\"];\n\n/**\n * Get the set of type names affected by a migration\n * @param {PendingMigration} migration - Pending migration\n * @returns {Set<string>} Set of affected type names\n */\nfunction getAffectedTypeNames(migration: PendingMigration): Set<string> {\n const typeNames = new Set<string>();\n for (const change of migration.diff.changes) {\n typeNames.add(change.typeName);\n }\n return typeNames;\n}\n\n/**\n * Get the set of type names to be deleted by a migration\n * @param {PendingMigration} migration - Pending migration\n * @returns {Set<string>} Set of type names to delete\n */\nfunction getDeletedTypeNames(migration: PendingMigration): Set<string> {\n const typeNames = new Set<string>();\n for (const change of migration.diff.changes) {\n if (change.kind === \"type_removed\") {\n typeNames.add(change.typeName);\n }\n }\n return typeNames;\n}\n\n/**\n * Execute services creation (called once at the beginning of migration flow)\n * @param {OperatorClient} client - Operator client instance\n * @param {TailorDBChangeSet} changeSet - TailorDB change set\n * @returns {Promise<void>} Promise that resolves when services are created\n */\nasync function executeServicesCreation(\n client: OperatorClient,\n changeSet: TailorDBChangeSet,\n): Promise<void> {\n await Promise.all([\n ...changeSet.service.creates.map(async (create) => {\n await client.createTailorDBService(create.request);\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.service.updates.map((update) => writeMetadataLabels(client, update.metaRequest)),\n ]);\n}\n\n/**\n * Track which types have been created/updated across migrations\n */\nconst processedTypes = {\n created: new Set<string>(),\n updated: new Set<string>(),\n gqlPermissionsProcessed: new Set<string>(),\n reset() {\n this.created.clear();\n this.updated.clear();\n this.gqlPermissionsProcessed.clear();\n },\n};\n\n/**\n * Snapshot cache for per-migration schema lookups during a single apply run.\n *\n * Only the initial baseline `0000/schema.json` is stored on disk; later migrations\n * ship `diff.json` only. To get the schema state AFTER migration N we replay the\n * initial snapshot through all diffs up to N via `reconstructSnapshotFromMigrations`.\n * Results are memoized per (namespace, migration number) for the apply run.\n */\nconst migrationSnapshotCache = {\n cache: new Map<string, SchemaSnapshot>(),\n reset() {\n this.cache.clear();\n },\n load(migration: PendingMigration): SchemaSnapshot {\n const key = `${migration.namespace}/${migration.number}`;\n let snapshot = this.cache.get(key);\n if (!snapshot) {\n const reconstructed = reconstructSnapshotFromMigrations(\n migration.migrationsDir,\n migration.number,\n );\n if (!reconstructed) {\n throw new Error(\n `Cannot reconstruct snapshot for ${migration.namespace} migration ${migration.number}: no migrations found in ${migration.migrationsDir}`,\n );\n }\n snapshot = reconstructed;\n this.cache.set(key, snapshot);\n }\n return snapshot;\n },\n};\n\nfunction buildSnapshotTypeManifest(\n migration: PendingMigration,\n typeName: string,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\n typeChanges?: Map<string, FieldDiffChange>,\n): MessageInitShape<typeof TailorDBTypeSchema> | undefined {\n const snapshot = migrationSnapshotCache.load(migration);\n const snapshotType = snapshot.types[typeName];\n if (!snapshotType) return undefined;\n const input = tailorDBInputs.find((i) => i.namespace === migration.namespace);\n const typeScriptsChange = migration.diff.changes.find(\n (change): change is TypeScriptsModifiedChange =>\n change.kind === \"type_scripts_modified\" && change.typeName === typeName,\n );\n const manifestSnapshotType = typeChanges\n ? createPreMigrationSnapshotType(snapshotType, typeChanges, typeScriptsChange)\n : snapshotType;\n return generateTailorDBTypeManifestFromSnapshot(manifestSnapshotType, {\n subscribed: executorUsedTypes.has(snapshotType.name),\n namespaceGqlOperations: input?.config.gqlOperations,\n });\n}\n\n/**\n * Await every promise to settle, then throw the first rejection. Unlike\n * `Promise.all`, this never leaves sibling operations in flight after a failure,\n * so a following rollback cannot race with still-pending DDL.\n * @param promises - Promises (or already-resolved values) to await\n * @returns {Promise<void>} Resolves once all settle; rejects with the first failure\n */\nasync function awaitAllSettledOrThrow(\n promises: ReadonlyArray<Promise<unknown> | undefined>,\n): Promise<void> {\n const results = await Promise.allSettled(promises);\n const rejected = results.find((r): r is PromiseRejectedResult => r.status === \"rejected\");\n if (rejected) {\n throw rejected.reason;\n }\n}\n\n/**\n * Execute pre-migration phase for a single migration\n * @param {OperatorClient} client - Operator client instance\n * @param {TailorDBChangeSet} changeSet - TailorDB change set\n * @param {PendingMigration} migration - Single pending migration\n * @param tailorDBInputs - Deploy inputs, used to resolve namespace gqlOperations for the snapshot\n * @param executorUsedTypes - Types used by executors (drives publishRecordEvents default)\n * @returns {Promise<void>} Promise that resolves when pre-migration phase completes\n */\nasync function executeSingleMigrationPrePhase(\n client: OperatorClient,\n changeSet: TailorDBChangeSet,\n migration: PendingMigration,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\n): Promise<void> {\n // Build pre-migration changes maps for this single migration. Includes both\n // breaking changes (required-add, unique-add, enum value removal) and the\n // warning-tier field_removed, since the Pre-phase relaxes both, plus the\n // breaking type-level index changes.\n const preMigrationChanges = buildPreMigrationChangesMap([migration]);\n const preMigrationIndexChanges = buildPreMigrationIndexChangesMap([migration]);\n const affectedTypes = getAffectedTypeNames(migration);\n const createdBeforeMigration = new Set(processedTypes.created);\n\n for (const create of changeSet.type.creates) {\n const typeName = create.request.tailordbType?.name;\n if (!typeName || !affectedTypes.has(typeName) || createdBeforeMigration.has(typeName)) {\n continue;\n }\n const typeChanges = preMigrationChanges.get(typeName);\n const snapshotType = buildSnapshotTypeManifest(\n migration,\n typeName,\n tailorDBInputs,\n executorUsedTypes,\n typeChanges,\n );\n if (!snapshotType) continue;\n\n const clonedRequest = structuredClone(create.request);\n clonedRequest.tailordbType = snapshotType;\n\n if (typeChanges && typeChanges.size > 0 && clonedRequest.tailordbType.schema?.fields) {\n applyPreMigrationFieldAdjustments(clonedRequest.tailordbType.schema.fields, typeChanges);\n }\n const indexChanges = preMigrationIndexChanges.get(typeName);\n if (indexChanges && indexChanges.size > 0 && clonedRequest.tailordbType.schema?.indexes) {\n applyPreMigrationIndexAdjustments(clonedRequest.tailordbType.schema.indexes, indexChanges);\n }\n\n processedTypes.created.add(typeName);\n await client.createTailorDBType(clonedRequest);\n }\n\n for (const create of changeSet.type.creates) {\n const typeName = create.request.tailordbType?.name;\n if (!typeName || !affectedTypes.has(typeName) || !createdBeforeMigration.has(typeName)) {\n continue;\n }\n const typeChanges = preMigrationChanges.get(typeName);\n const snapshotType = buildSnapshotTypeManifest(\n migration,\n typeName,\n tailorDBInputs,\n executorUsedTypes,\n typeChanges,\n );\n if (!snapshotType) continue;\n\n const clonedTypeRequest = structuredClone(snapshotType);\n if (typeChanges && typeChanges.size > 0 && clonedTypeRequest.schema?.fields) {\n applyPreMigrationFieldAdjustments(clonedTypeRequest.schema.fields, typeChanges);\n }\n const indexChanges = preMigrationIndexChanges.get(typeName);\n if (indexChanges && indexChanges.size > 0 && clonedTypeRequest.schema?.indexes) {\n applyPreMigrationIndexAdjustments(clonedTypeRequest.schema.indexes, indexChanges);\n }\n\n processedTypes.updated.add(typeName);\n await client.updateTailorDBType({\n workspaceId: create.request.workspaceId,\n namespaceName: create.request.namespaceName,\n tailordbType: clonedTypeRequest,\n });\n }\n\n for (const update of changeSet.type.updates) {\n const typeName = update.request.tailordbType?.name;\n if (!typeName || !affectedTypes.has(typeName)) continue;\n const typeChanges = preMigrationChanges.get(typeName);\n const snapshotType = buildSnapshotTypeManifest(\n migration,\n typeName,\n tailorDBInputs,\n executorUsedTypes,\n typeChanges,\n );\n if (!snapshotType) continue;\n\n const clonedRequest = structuredClone(update.request);\n clonedRequest.tailordbType = snapshotType;\n\n if (typeChanges && typeChanges.size > 0 && clonedRequest.tailordbType.schema?.fields) {\n applyPreMigrationFieldAdjustments(clonedRequest.tailordbType.schema.fields, typeChanges);\n }\n const indexChanges = preMigrationIndexChanges.get(typeName);\n if (indexChanges && indexChanges.size > 0 && clonedRequest.tailordbType.schema?.indexes) {\n applyPreMigrationIndexAdjustments(clonedRequest.tailordbType.schema.indexes, indexChanges);\n }\n\n processedTypes.updated.add(typeName);\n await client.updateTailorDBType(clonedRequest);\n }\n\n // GQLPermissions - process once (on the first migration)\n if (!processedTypes.gqlPermissionsProcessed.has(migration.namespace)) {\n const gqlPermissionCreatesForNamespace = changeSet.gqlPermission.creates.filter(\n (create) => create.request.namespaceName === migration.namespace,\n );\n const gqlPermissionUpdatesForNamespace = changeSet.gqlPermission.updates.filter(\n (update) => update.request.namespaceName === migration.namespace,\n );\n const gqlPermissionTypeNames = new Set(\n gqlPermissionCreatesForNamespace.map((create) => create.name),\n );\n const missingTypeCreates = changeSet.type.creates.filter((create) => {\n const typeName = create.request.tailordbType?.name;\n const namespaceName = create.request.namespaceName;\n return (\n namespaceName === migration.namespace &&\n typeName &&\n gqlPermissionTypeNames.has(typeName) &&\n !processedTypes.created.has(typeName)\n );\n });\n if (missingTypeCreates.length > 0) {\n for (const create of missingTypeCreates) {\n const typeName = create.request.tailordbType?.name;\n if (typeName) processedTypes.created.add(typeName);\n await client.createTailorDBType(create.request);\n }\n }\n processedTypes.gqlPermissionsProcessed.add(migration.namespace);\n await awaitAllSettledOrThrow([\n ...gqlPermissionCreatesForNamespace.map((create) =>\n client.createTailorDBGQLPermission(create.request),\n ),\n ...gqlPermissionUpdatesForNamespace.map((update) =>\n client.updateTailorDBGQLPermission(update.request),\n ),\n ]);\n }\n}\n\n/**\n * Track which types/permissions have been deleted across migrations\n */\nconst deletedResources = {\n types: new Set<string>(),\n gqlPermissions: new Set<string>(),\n reset() {\n this.types.clear();\n this.gqlPermissions.clear();\n },\n};\n\nasync function rollbackSingleMigrationAfterFailure(\n client: OperatorClient,\n changeSet: TailorDBChangeSet,\n migration: PendingMigration,\n workspaceId: string,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\n): Promise<void> {\n try {\n await rollbackSingleMigrationPrePhase(\n client,\n changeSet,\n migration,\n workspaceId,\n tailorDBInputs,\n executorUsedTypes,\n );\n } catch (rollbackError) {\n logger.warn(\n `Failed to roll back migration ${migration.namespace}/${formatMigrationNumber(migration.number)}: ` +\n `${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`,\n );\n }\n}\n\n/**\n * Execute post-migration phase for a single migration: Apply final types (with required: true)\n * @param {OperatorClient} client - Operator client instance\n * @param {TailorDBChangeSet} changeSet - TailorDB change set\n * @param {PendingMigration} migration - Single pending migration\n * @param tailorDBInputs - Deploy inputs, used to resolve namespace gqlOperations for the snapshot\n * @param executorUsedTypes - Types used by executors (drives publishRecordEvents default)\n * @returns {Promise<void>} Promise that resolves when post-migration phase completes\n */\nasync function executeSingleMigrationPostPhase(\n client: OperatorClient,\n changeSet: TailorDBChangeSet,\n migration: PendingMigration,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\n): Promise<void> {\n // Re-use the pre-migration changes maps to know which types were touched in\n // this migration (so we send the post-phase final-schema update for them).\n const preMigrationChanges = buildPreMigrationChangesMap([migration]);\n const preMigrationIndexChanges = buildPreMigrationIndexChangesMap([migration]);\n const adjustedTypes = new Set([\n ...preMigrationChanges.keys(),\n ...preMigrationIndexChanges.keys(),\n ]);\n const affectedTypes = getAffectedTypeNames(migration);\n\n // Types - apply schema as of migration N (= snapshot[N]) with all breaking\n // changes enforced. The prePhase sent the same schema with breaking fields\n // relaxed; here we send it again without relaxation so required/unique/etc.\n // take effect after the data script has reconciled records.\n try {\n // For newly created types that had pre-migration adjustments in this migration, send update with snapshot[N] values\n for (const create of changeSet.type.creates) {\n const typeName = create.request.tailordbType?.name;\n if (!typeName || !affectedTypes.has(typeName) || !adjustedTypes.has(typeName)) {\n continue;\n }\n const snapshotType = buildSnapshotTypeManifest(\n migration,\n typeName,\n tailorDBInputs,\n executorUsedTypes,\n );\n if (!snapshotType) continue;\n await client.updateTailorDBType({\n workspaceId: create.request.workspaceId,\n namespaceName: create.request.namespaceName,\n tailordbType: snapshotType,\n });\n }\n\n // For updated types affected by this migration, send update with snapshot[N] values\n for (const update of changeSet.type.updates) {\n const typeName = update.request.tailordbType?.name;\n if (!typeName || !affectedTypes.has(typeName) || !adjustedTypes.has(typeName)) {\n continue;\n }\n const snapshotType = buildSnapshotTypeManifest(\n migration,\n typeName,\n tailorDBInputs,\n executorUsedTypes,\n );\n if (!snapshotType) continue;\n await client.updateTailorDBType({\n workspaceId: update.request.workspaceId,\n namespaceName: update.request.namespaceName,\n tailordbType: snapshotType,\n });\n }\n } catch (error) {\n handleOptionalToRequiredError(error, [\n \"This error occurred during post-migration phase. Please check your migration script.\",\n \"Ensure all existing records have values for fields being changed to required.\",\n ]);\n }\n}\n\nasync function executeSingleMigrationPostPhaseDeletions(\n client: OperatorClient,\n changeSet: TailorDBChangeSet,\n migration: PendingMigration,\n): Promise<void> {\n const deletedTypeNames = getDeletedTypeNames(migration);\n if (deletedTypeNames.size > 0) {\n const gqlPermissionsToDelete = changeSet.gqlPermission.deletes.filter((del) => {\n const permKey = `${del.request.namespaceName}/${del.name}`;\n if (deletedResources.gqlPermissions.has(permKey)) return false;\n const typeName = del.name;\n return deletedTypeNames.has(typeName);\n });\n for (const del of gqlPermissionsToDelete) {\n await client.deleteTailorDBGQLPermission(del.request);\n deletedResources.gqlPermissions.add(`${del.request.namespaceName}/${del.name}`);\n }\n\n const typesToDelete = changeSet.type.deletes.filter((del) => {\n const typeName = del.name;\n if (!typeName || deletedResources.types.has(typeName)) return false;\n return deletedTypeNames.has(typeName);\n });\n for (const del of typesToDelete) {\n await client.deleteTailorDBType(del.request);\n deletedResources.types.add(del.name);\n }\n }\n}\n\n/**\n * Revert a single migration's Pre-phase DDL to the prior checkpoint's schema.\n * @param client - Operator client instance\n * @param changeSet - TailorDB change set\n * @param migration - The migration whose Pre-phase DDL must be reverted\n * @param workspaceId - Workspace ID\n * @param tailorDBInputs - Deploy inputs, used to resolve namespace gqlOperations for the snapshot\n * @param executorUsedTypes - Types used by executors (drives publishRecordEvents default)\n * @returns {Promise<void>} Promise that resolves when rollback attempts complete\n */\nasync function rollbackSingleMigrationPrePhase(\n client: OperatorClient,\n changeSet: TailorDBChangeSet,\n migration: PendingMigration,\n workspaceId: string,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\n): Promise<void> {\n // The baseline migration has no prior checkpoint to revert to.\n if (migration.number <= INITIAL_SCHEMA_NUMBER) return;\n\n // `processedTypes` spans every namespace touched in this apply run; restrict\n // rollback to this migration's namespace (its diff plus this namespace's\n // change-set entries). Type names are unique across namespaces, so a name from\n // another namespace simply won't appear in this set.\n const namespaceTypes = getAffectedTypeNames(migration);\n for (const create of changeSet.type.creates) {\n const name = create.request.tailordbType?.name;\n if (create.request.namespaceName === migration.namespace && name) namespaceTypes.add(name);\n }\n for (const update of changeSet.type.updates) {\n const name = update.request.tailordbType?.name;\n if (update.request.namespaceName === migration.namespace && name) namespaceTypes.add(name);\n }\n\n // Of those, only the types this apply run actually created or updated (so\n // rollback is a no-op when nothing was applied and never touches drift).\n const applied = new Set([...processedTypes.created, ...processedTypes.updated]);\n const rollbackTypes = new Set([...namespaceTypes].filter((name) => applied.has(name)));\n if (rollbackTypes.size === 0) return;\n\n const priorSnapshot = reconstructSnapshotFromMigrations(\n migration.migrationsDir,\n migration.number - 1,\n );\n // Without the prior snapshot, pre-existing and new types are indistinguishable;\n // deleting them all would be destructive, so leave the schema untouched.\n if (!priorSnapshot) {\n logger.warn(\n `Cannot roll back migration ${migration.namespace}/${formatMigrationNumber(migration.number)}: ` +\n `prior snapshot (migration ${formatMigrationNumber(migration.number - 1)}) could not be reconstructed. ` +\n \"Leaving schema as-is; manual repair may be required.\",\n );\n return;\n }\n const input = tailorDBInputs.find((i) => i.namespace === migration.namespace);\n\n logger.warn(\n `Migration ${migration.namespace}/${formatMigrationNumber(migration.number)} failed; ` +\n \"rolling back its pre-migration schema changes.\",\n );\n\n for (const typeName of rollbackTypes) {\n const priorType = priorSnapshot.types[typeName];\n try {\n if (priorType) {\n const manifest = generateTailorDBTypeManifestFromSnapshot(priorType, {\n subscribed: executorUsedTypes.has(priorType.name),\n namespaceGqlOperations: input?.config.gqlOperations,\n });\n await client.updateTailorDBType({\n workspaceId,\n namespaceName: migration.namespace,\n tailordbType: manifest,\n });\n } else {\n // New type: its GQL permission must go first (type deletion does not\n // cascade). The permission may not exist, so the delete is best-effort.\n await client\n .deleteTailorDBGQLPermission({\n workspaceId,\n namespaceName: migration.namespace,\n typeName,\n })\n .catch(() => undefined);\n await client.deleteTailorDBType({\n workspaceId,\n namespaceName: migration.namespace,\n tailordbTypeName: typeName,\n });\n }\n } catch (rollbackError) {\n logger.warn(\n `Failed to roll back type '${typeName}' in namespace '${migration.namespace}': ` +\n `${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`,\n );\n }\n }\n}\n\n/**\n * Plan TailorDB-related changes based on current and desired state.\n * @param context - Planning context\n * @returns Planned changes\n */\nexport async function planTailorDB(context: PlanContext) {\n const {\n client,\n workspaceId,\n application,\n forRemoval,\n config,\n noSchemaCheck,\n forceApplyAll = false,\n } = context;\n const tailordbs: TailorDBDeployInput[] = [];\n const migrationTestSnapshots =\n context.migrationTestSnapshots ??\n (context.migrationTestBaselines\n ? new Map(\n [...context.migrationTestBaselines].map(([namespace, baseline]) => [\n namespace,\n baseline.snapshot,\n ]),\n )\n : undefined);\n if (!forRemoval) {\n for (const tailordb of application.tailorDBServices) {\n await tailordb.loadTypes();\n const input = toTailorDBDeployInput(tailordb);\n const snapshot = migrationTestSnapshots?.get(tailordb.namespace);\n tailordbs.push(snapshot ? { ...input, types: snapshot.types } : input);\n }\n }\n const executors = forRemoval\n ? []\n : Object.values((await application.executorService?.loadExecutors()) ?? {});\n const executorUsedTypes = new Set(context.executorUsedTailorDBTypes ?? []);\n for (const executor of executors) {\n if (executor.trigger.kind === \"tailordb\") {\n executorUsedTypes.add(executor.trigger.typeName);\n }\n }\n\n // Validate migrations at plan time so a missing migration script fails the\n // deploy (including --dry-run) before any resource is applied.\n const typesByNamespace = new Map<string, Record<string, TailorDBSnapshotType>>();\n for (const tailordb of tailordbs) {\n typesByNamespace.set(tailordb.namespace, tailordb.types);\n }\n const migrationTestBaselines = context.migrationTestBaselines;\n if (migrationTestSnapshots) {\n for (const namespace of migrationTestSnapshots.keys()) {\n if (!tailordbs.some((tailordb) => tailordb.namespace === namespace)) {\n throw new Error(\n `Migration test snapshot targets unknown TailorDB namespace \"${namespace}\".`,\n );\n }\n }\n const namespaceByType = new Map<string, string>();\n for (const tailordb of tailordbs) {\n for (const typeName of Object.keys(tailordb.types)) {\n const existingNamespace = namespaceByType.get(typeName);\n if (existingNamespace) {\n throw new Error(\n `Migration test snapshot has duplicate TailorDB type name \"${typeName}\" in namespaces \"${existingNamespace}\" and \"${tailordb.namespace}\".`,\n );\n }\n namespaceByType.set(typeName, tailordb.namespace);\n }\n }\n }\n const migrationConfig = getNamespacesWithMigrations(config, path.dirname(config.path));\n const { namespacesWithMigrations, migrationFileState, checkpointRepairs } = forRemoval\n ? { namespacesWithMigrations: [], migrationFileState: {}, checkpointRepairs: [] }\n : migrationTestBaselines\n ? {\n namespacesWithMigrations: migrationConfig,\n migrationFileState: captureMigrationFileState(migrationConfig),\n checkpointRepairs: [],\n }\n : await validateAndDetectMigrations(\n client,\n workspaceId,\n typesByNamespace,\n config,\n noSchemaCheck ?? false,\n tailordbs,\n );\n\n const {\n changeSet: serviceChangeSet,\n conflicts,\n unmanaged,\n resourceOwners,\n } = await planServices(client, workspaceId, application.name, application.id, tailordbs);\n const deletedServices = serviceChangeSet.deletes.map((del) => del.name);\n const [typeChangeSet, gqlPermissionChangeSet] = await Promise.all([\n planTypes(\n client,\n workspaceId,\n tailordbs,\n executorUsedTypes,\n deletedServices,\n undefined,\n forceApplyAll,\n {\n appName: application.name,\n appId: application.id,\n dependentApps: context.dependentApps,\n runAppIds: context.runAppIds,\n },\n ),\n planGqlPermissions(client, workspaceId, tailordbs, deletedServices, forceApplyAll),\n ]);\n\n // Apply type DDL in a stable, name-sorted order so the create burst (capped\n // by the operator client's concurrency limiter) is reproducible across runs.\n typeChangeSet.creates.sort(byName);\n typeChangeSet.updates.sort(byName);\n typeChangeSet.deletes.sort(byName);\n\n return {\n changeSet: {\n service: serviceChangeSet,\n type: typeChangeSet,\n gqlPermission: gqlPermissionChangeSet,\n },\n conflicts,\n unmanaged,\n resourceOwners,\n context: {\n workspaceId,\n application,\n tailorDBInputs: tailordbs,\n executorUsedTypes,\n config,\n noSchemaCheck: noSchemaCheck ?? false,\n ...(migrationTestBaselines ? { migrationTestBaselines } : {}),\n namespacesWithMigrations,\n migrationFileState,\n checkpointRepairs,\n },\n };\n}\n\ntype TailorDBDisplayEntry = GroupedDisplayEntry;\n\ntype NamespacedItem = HasName & { request?: { namespaceName?: string } };\n\nfunction itemKey(item: NamespacedItem): string {\n return `${item.request?.namespaceName ?? \"\"}/${item.name}`;\n}\n\nfunction collectTailorDBDisplayEntries(\n action: DisplayAction,\n typeItems: ReadonlyArray<NamespacedItem>,\n gqlPermissionItems: ReadonlyArray<NamespacedItem>,\n): TailorDBDisplayEntry[] {\n const typeKeys = new Set(typeItems.map(itemKey));\n const gqlPermissionKeys = new Set(gqlPermissionItems.map(itemKey));\n const typeEntries = typeItems.map((item) => ({\n action,\n symbol: ACTION_SYMBOLS[action],\n name: item.name,\n labels: gqlPermissionKeys.has(itemKey(item)) ? [\"type\", \"gqlPermission\"] : [\"type\"],\n namespace: item.request?.namespaceName,\n }));\n const gqlPermissionOnlyEntries = gqlPermissionItems\n .filter((item) => !typeKeys.has(itemKey(item)))\n .map((item) => ({\n action,\n symbol: ACTION_SYMBOLS[action],\n name: item.name,\n labels: [\"gqlPermission\"],\n namespace: item.request?.namespaceName,\n }));\n\n return [...typeEntries, ...gqlPermissionOnlyEntries];\n}\n\n/**\n * Format TailorDB type and gqlPermission changes as grouped dry-run entries.\n * @param typeChangeSet - TailorDB type changes\n * @param gqlPermissionChangeSet - TailorDB gqlPermission changes\n * @returns Display entries for TailorDB resource output\n */\nexport function formatTailorDBResourceChangeEntries(\n typeChangeSet: Pick<\n ChangeSet<HasName, HasName, HasName>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n gqlPermissionChangeSet: Pick<\n ChangeSet<HasName, HasName, HasName>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n): TailorDBDisplayEntry[] {\n return [\n ...collectTailorDBDisplayEntries(\n \"create\",\n typeChangeSet.creates,\n gqlPermissionChangeSet.creates,\n ),\n ...collectTailorDBDisplayEntries(\n \"delete\",\n typeChangeSet.deletes,\n gqlPermissionChangeSet.deletes,\n ),\n ...collectTailorDBDisplayEntries(\n \"update\",\n typeChangeSet.updates,\n gqlPermissionChangeSet.updates,\n ),\n ...collectTailorDBDisplayEntries(\n \"replace\",\n typeChangeSet.replaces,\n gqlPermissionChangeSet.replaces,\n ),\n ];\n}\n\ntype CreateService = {\n name: string;\n request: MessageInitShape<typeof CreateTailorDBServiceRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateService = {\n name: string;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteService = {\n name: string;\n request: MessageInitShape<typeof DeleteTailorDBServiceRequestSchema>;\n};\n\nfunction normalizeComparableTailorDBService(service: {\n namespace?: string;\n defaultTimezone?: string;\n}) {\n return normalizeProtoConfig({\n namespace: service.namespace,\n defaultTimezone: service.defaultTimezone || \"UTC\",\n });\n}\n\nfunction areTailorDBServicesEqual(\n existing: {\n namespace?: { name?: string };\n defaultTimezone?: string;\n },\n desired: Readonly<TailorDBDeployInput>,\n): boolean {\n return areNormalizedEqual(\n normalizeComparableTailorDBService({\n namespace: existing.namespace?.name,\n defaultTimezone: existing.defaultTimezone,\n }),\n normalizeComparableTailorDBService({\n namespace: desired.namespace,\n defaultTimezone: \"UTC\",\n }),\n );\n}\n\nasync function planServices(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n tailordbs: ReadonlyArray<TailorDBDeployInput>,\n) {\n const changeSet = createChangeSet<CreateService, UpdateService, DeleteService>(\n \"TailorDB services\",\n );\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const existingServices = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, maxPageSize) => {\n const { tailordbServices, nextPageToken } = await client.listTailorDBServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbServices, nextPageToken];\n },\n getName: (resource) => resource.namespace?.name,\n getTrn: (name) => resourceTrn(workspaceId, \"tailordb\", name),\n });\n\n for (const tailordb of tailordbs) {\n const existing = existingServices[tailordb.namespace];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"tailordb\", tailordb.namespace),\n appName,\n appId,\n });\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"TailorDB service\",\n resourceName: tailordb.namespace,\n conflicts,\n unmanaged,\n });\n\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n areTailorDBServicesEqual(existing.resource, tailordb)\n ) {\n changeSet.unchanged.push({ name: tailordb.namespace });\n } else {\n changeSet.updates.push({\n name: tailordb.namespace,\n metaRequest,\n });\n }\n delete existingServices[tailordb.namespace];\n } else {\n changeSet.creates.push({\n name: tailordb.namespace,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n // Keep generated TailorDB services aligned with Terraform defaults.\n defaultTimezone: \"UTC\",\n },\n metaRequest,\n });\n }\n }\n Object.entries(existingServices).forEach(([namespaceName]) => {\n const entry = existingServices[namespaceName];\n const owned = trackRemainingResourceOwner({\n labels: entry?.allLabels,\n ownerLabel: entry?.label,\n appName,\n appId,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({\n name: namespaceName,\n request: {\n workspaceId,\n namespaceName,\n },\n });\n }\n });\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n\ntype CreateType = {\n name: string;\n request: MessageInitShape<typeof CreateTailorDBTypeRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateType = {\n name: string;\n request: MessageInitShape<typeof UpdateTailorDBTypeRequestSchema>;\n metaRequest: MetadataLabelWrite;\n};\n\n/**\n * A type whose schema is unchanged but whose dependency records may not be. The\n * plan shows it as unchanged; apply still writes its labels.\n */\ntype UnchangedType = {\n name: string;\n metaRequest?: MetadataLabelWrite;\n};\n\n/** What planTypes needs to record dependencies on each type. */\ntype TypeRecordInputs = {\n appName?: string;\n appId?: string;\n dependentApps?: DependentAppsByResource;\n runAppIds?: ReadonlySet<string>;\n};\n\ntype DeleteType = {\n name: string;\n request: MessageInitShape<typeof DeleteTailorDBTypeRequestSchema>;\n};\n\nasync function planTypes(\n client: OperatorClient,\n workspaceId: string,\n tailordbs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\n deletedServices: ReadonlyArray<string>,\n filteredTypesByNamespace?: Map<string, Record<string, TailorDBSnapshotType>>,\n forceApplyAll = false,\n records: TypeRecordInputs = {},\n) {\n const changeSet = createChangeSet<CreateType, UpdateType, DeleteType, never, UnchangedType>(\n \"TailorDB types\",\n );\n const { appName, appId, dependentApps, runAppIds } = records;\n\n /**\n * Build one type's metadata write, carrying the dependency records that belong\n * to it. The type is what publishes record events, so the record lives there.\n * @param namespace - Namespace holding the type\n * @param typeName - Type name\n * @param explicitPublishEvents - `publishEvents` declared on the type, if any\n * @returns The type's metadata write\n */\n const typeMetaRequest = async (\n namespace: string,\n typeName: string,\n explicitPublishEvents: boolean | undefined,\n ) => {\n const trn = tailorDBTypeTrn(workspaceId, namespace, typeName);\n return addDependencyRecords(await buildMetaRequest({ trn, appName: appName ?? \"\", appId }), {\n key: eventSourceKey.tailorDBType(namespace, typeName),\n dependentApps,\n runAppIds,\n pinned: explicitPublishEvents !== undefined,\n });\n };\n\n const fetchTypes = (namespaceName: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { tailordbTypes, nextPageToken } = await client.listTailorDBTypes({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbTypes, nextPageToken];\n });\n };\n\n // Reject a conflicting opt-out before any request, not partway through.\n for (const tailordb of tailordbs) {\n const types = filteredTypesByNamespace?.get(tailordb.namespace) ?? tailordb.types;\n for (const [typeName, type] of Object.entries(types)) {\n assertNoPublishEventsConflict({\n explicit: type.settings?.publishEvents,\n subscribed: executorUsedTypes.has(typeName),\n conflict: publishEventsConflict.tailorDBType(typeName),\n });\n }\n }\n\n for (const tailordb of tailordbs) {\n const existingTypes = await fetchTypes(tailordb.namespace);\n const existingTypesMap = new Map(existingTypes.map((type) => [type.name, type]));\n\n // Use filtered types if provided, otherwise use local types\n const types = filteredTypesByNamespace?.get(tailordb.namespace) ?? tailordb.types;\n const typeMeta = (typeName: string) =>\n typeMetaRequest(tailordb.namespace, typeName, types[typeName]?.settings?.publishEvents);\n\n for (const [typeName, tailordbTypeSnapshot] of Object.entries(types)) {\n const tailordbType = generateTailorDBTypeManifestFromSnapshot(tailordbTypeSnapshot, {\n subscribed: executorUsedTypes.has(typeName),\n namespaceGqlOperations: tailordb.config.gqlOperations,\n });\n const existingType = existingTypesMap.get(typeName);\n if (existingType) {\n if (\n !forceApplyAll &&\n areNormalizedEqual(\n normalizeComparableTailorDBType(existingType),\n normalizeComparableTailorDBType(tailordbType),\n )\n ) {\n // The schema matches, but the records may not, so the labels still go.\n changeSet.unchanged.push({ name: typeName, metaRequest: await typeMeta(typeName) });\n } else {\n changeSet.updates.push({\n name: typeName,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n tailordbType,\n },\n metaRequest: await typeMeta(typeName),\n });\n }\n existingTypesMap.delete(typeName);\n } else {\n changeSet.creates.push({\n name: typeName,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n tailordbType,\n },\n metaRequest: await typeMeta(typeName),\n });\n }\n }\n existingTypesMap.forEach((_type, name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n tailordbTypeName: name,\n },\n });\n });\n }\n for (const namespaceName of deletedServices) {\n const existingTypes = await fetchTypes(namespaceName);\n existingTypes.forEach((typ) => {\n changeSet.deletes.push({\n name: typ.name,\n request: {\n workspaceId,\n namespaceName,\n tailordbTypeName: typ.name,\n },\n });\n });\n }\n return changeSet;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst tailordbCompareKnownDefaults = {\n /**\n * Platform returns this object with explicit false flags even when the SDK omitted\n * gqlOperations entirely. Treat the all-false object as \"unset\" for diff purposes.\n */\n disableGqlOperations: {\n create: false,\n update: false,\n delete: false,\n read: false,\n },\n /**\n * Some remote validate expressions are emitted as an empty string when the SDK did\n * not define a script. Local manifests omit the field entirely.\n */\n emptyExpression: \"\",\n /**\n * Proto bigint-backed values can round-trip as numbers locally and strings remotely.\n * Canonicalize them to strings at compare time.\n */\n numericStringPaths: new Set([\n \"schema.fields.*.serial.start\",\n \"schema.fields.*.serial.maxValue\",\n \"schema.settings.defaultQueryLimitSize\",\n \"schema.settings.maxBulkUpsertSize\",\n ]),\n} as const;\n\nfunction normalizeComparableTailorDBType(type: MessageInitShape<typeof TailorDBTypeSchema>) {\n const canonical = toComparableProtoJson(TailorDBTypeSchema, type);\n const normalized = normalizeProtoConfig(canonical) as {\n name?: string;\n schema?: {\n description?: string;\n fields?: Record<string, unknown>;\n relationships?: Record<string, unknown>;\n settings?: Record<string, unknown>;\n indexes?: Record<string, unknown>;\n files?: Record<string, unknown>;\n permission?: Record<string, unknown>;\n typeHook?: Record<string, unknown>;\n typeValidate?: Record<string, unknown>;\n };\n } | null;\n return normalizeTailorDBCompareValue(\n {\n name: normalized?.name ?? \"\",\n schema: {\n description: normalized?.schema?.description ?? \"\",\n fields: normalized?.schema?.fields ?? {},\n relationships: normalized?.schema?.relationships ?? {},\n settings: normalized?.schema?.settings ?? {},\n indexes: normalized?.schema?.indexes ?? {},\n files: normalized?.schema?.files ?? {},\n permission: normalized?.schema?.permission ?? {},\n // Hooks/validators are sent as type-level scripts; include them so a\n // changed hook or validator is detected as an update.\n typeHook: normalized?.schema?.typeHook ?? {},\n typeValidate: normalized?.schema?.typeValidate ?? {},\n },\n },\n [],\n );\n}\n\nfunction isPermissionPolicyArrayPath(path: readonly (string | number)[]): boolean {\n return (\n path.length === 3 &&\n path[0] === \"schema\" &&\n path[1] === \"permission\" &&\n (path[2] === \"create\" || path[2] === \"read\" || path[2] === \"update\" || path[2] === \"delete\")\n );\n}\n\nfunction normalizeTailorDBCompareValue(\n value: unknown,\n path: readonly (string | number)[],\n): unknown {\n if (value === undefined || value === null) {\n return value;\n }\n\n if (typeof value === \"boolean\") {\n if (path.at(-1) === \"optionalOnCreate\" && value === false) {\n return undefined;\n }\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"bigint\" || typeof value === \"string\") {\n if (matchesNumericStringPath(path) && isNumericLikeValue(value)) {\n return String(value);\n }\n if (\n (path.at(-1) === \"expr\" || path.at(-1) === \"description\") &&\n value === tailordbCompareKnownDefaults.emptyExpression\n ) {\n return undefined;\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n const items = value\n .map((item, index) => normalizeTailorDBCompareValue(item, [...path, index]))\n .filter((item) => item !== undefined);\n // Field-level validators are no longer emitted by the SDK (they are aggregated\n // into type-level type_validate). The platform still returns an empty `validate`\n // array per field; treat it as unset so it matches the omitted local value.\n if (items.length === 0 && path.at(-1) === \"validate\") {\n return undefined;\n }\n // The platform evaluates permission policies order-insensitively (any\n // matching deny wins over any matching allow), while committed migration\n // snapshots can record the same policies in a different order than the\n // current config parse — so compare each action's policies as a set.\n if (isPermissionPolicyArrayPath(path)) {\n return items.toSorted((a, b) => (JSON.stringify(a) < JSON.stringify(b) ? -1 : 1));\n }\n return items;\n }\n\n if (!isPlainObject(value)) {\n return value;\n }\n\n const normalizedEntries = Object.entries(value)\n .map(\n ([key, entryValue]) =>\n [key, normalizeTailorDBCompareValue(entryValue, [...path, key])] as const,\n )\n .filter(([, entryValue]) => entryValue !== undefined);\n\n const normalizedObject = Object.fromEntries(normalizedEntries);\n\n if (path.at(-1) === \"fields\" && Object.keys(normalizedObject).length === 0) {\n return undefined;\n }\n\n if (\n path.at(-1) === \"disableGqlOperations\" &&\n (Object.keys(normalizedObject).length === 0 ||\n areNormalizedEqual(normalizedObject, tailordbCompareKnownDefaults.disableGqlOperations))\n ) {\n return undefined;\n }\n\n return normalizedObject;\n}\n\nfunction matchesNumericStringPath(path: readonly (string | number)[]): boolean {\n const pathKey = path.map((segment) => String(segment)).join(\".\");\n return [...tailordbCompareKnownDefaults.numericStringPaths].some((pattern) => {\n const patternParts = pattern.split(\".\");\n const pathParts = pathKey.split(\".\");\n if (patternParts.length !== pathParts.length) {\n return false;\n }\n return patternParts.every((part, index) => part === \"*\" || part === pathParts[index]);\n });\n}\n\nfunction isNumericLikeValue(value: string | number | bigint): boolean {\n return typeof value === \"number\" || typeof value === \"bigint\" || /^-?\\d+$/.test(value);\n}\n\ntype CreateGqlPermission = {\n name: string;\n request: MessageInitShape<typeof CreateTailorDBGQLPermissionRequestSchema>;\n};\n\ntype UpdateGqlPermission = {\n name: string;\n request: MessageInitShape<typeof UpdateTailorDBGQLPermissionRequestSchema>;\n};\n\ntype DeleteGqlPermission = {\n name: string;\n request: MessageInitShape<typeof DeleteTailorDBGQLPermissionRequestSchema>;\n};\n\nasync function planGqlPermissions(\n client: OperatorClient,\n workspaceId: string,\n tailordbs: ReadonlyArray<TailorDBDeployInput>,\n deletedServices: ReadonlyArray<string>,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateGqlPermission, UpdateGqlPermission, DeleteGqlPermission>(\n \"TailorDB gqlPermissions\",\n );\n\n const fetchGqlPermissions = (namespaceName: string) => {\n return fetchAllTolerant(async (pageToken, maxPageSize) => {\n const { permissions, nextPageToken } = await client.listTailorDBGQLPermissions({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [permissions, nextPageToken];\n });\n };\n\n for (const tailordb of tailordbs) {\n const existingGqlPermissions = await fetchGqlPermissions(tailordb.namespace);\n const existingNameSet = new Set<string>();\n existingGqlPermissions.forEach((gqlPermission) => {\n existingNameSet.add(gqlPermission.typeName);\n });\n\n const types = tailordb.types;\n for (const [typeName, typeEntry] of Object.entries(types)) {\n const gqlPermission = typeEntry.permissions?.gql;\n if (!gqlPermission) {\n continue;\n }\n const desiredPermission = protoGqlPermission(gqlPermission);\n const existingPermission = existingGqlPermissions.find(\n (entry) => entry.typeName === typeName,\n );\n if (existingNameSet.has(typeName)) {\n if (\n !forceApplyAll &&\n existingPermission &&\n areNormalizedEqual(\n normalizeComparableGqlPermission(existingPermission.permission),\n normalizeComparableGqlPermission(desiredPermission),\n )\n ) {\n changeSet.unchanged.push({ name: typeName });\n } else {\n changeSet.updates.push({\n name: typeName,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n typeName: typeName,\n permission: desiredPermission,\n },\n });\n }\n existingNameSet.delete(typeName);\n } else {\n changeSet.creates.push({\n name: typeName,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n typeName: typeName,\n permission: desiredPermission,\n },\n });\n }\n }\n existingNameSet.forEach((name) => {\n changeSet.deletes.push({\n name,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n typeName: name,\n },\n });\n });\n }\n for (const namespaceName of deletedServices) {\n const existingGqlPermissions = await fetchGqlPermissions(namespaceName);\n existingGqlPermissions.forEach((gqlPermission) => {\n changeSet.deletes.push({\n name: gqlPermission.typeName,\n request: {\n workspaceId,\n namespaceName,\n typeName: gqlPermission.typeName,\n },\n });\n });\n }\n return changeSet;\n}\n\nfunction normalizeComparableGqlPermission(permission: unknown) {\n const normalized = normalizeProtoConfig(permission) as {\n policies?: Array<{\n actions?: number[];\n conditions?: unknown[];\n permit?: number;\n description?: string;\n }>;\n } | null;\n return {\n policies: (normalized?.policies ?? []).map((policy) => ({\n ...policy,\n actions: (policy.actions ?? []).toSorted((left, right) => left - right),\n })),\n };\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { parseDuration } from \"#/cli/shared/args\";\nimport { type OperatorClient, fetchAll } from \"#/cli/shared/client\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { publishEventsConflict, resolvePublishEvents } from \"#/cli/shared/publish-events\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createChangeSet, type ChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport { workflowJobFunctionName } from \"./function-registry\";\nimport {\n formatChangeEntriesWithFunctionRegistry,\n type GroupedDisplayEntry,\n type RelatedFunctionRegistryChanges,\n} from \"./grouped-display\";\nimport {\n addDependencyRecords,\n buildMetaRequest,\n type DependentAppsByResource,\n eventSourceKey,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n sdkNameLabelKey,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { ConcurrencyPolicy, Workflow, RetryPolicy } from \"#/types/workflow.generated\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase } from \"./phase\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { CreateWorkflowRequestSchema } from \"@tailor-platform/tailor-proto/workflow_pb\";\nimport type {\n ConcurrencyPolicySchema,\n RetryPolicySchema,\n WorkflowJobFunctionSummary,\n} from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\n\n/**\n * Apply workflow changes for the given phase.\n * @param client - Operator client instance\n * @param result - Planned workflow changes\n * @param phase - Apply phase\n * @returns Promise that resolves when workflows are applied\n */\nexport async function applyWorkflow(\n client: OperatorClient,\n result: Awaited<ReturnType<typeof planWorkflow>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n) {\n const { changeSet, appName, appId } = result;\n if (phase === \"create-update\") {\n // Register job functions used by any workflow, returns map of job name to version\n const jobFunctionVersions = await registerJobFunctions(\n client,\n changeSet,\n appName,\n appId,\n result.unchangedWorkflowJobNames,\n result.jobFunctionPublishEvents,\n );\n\n // Create and update workflows in parallel\n // Each workflow only gets the job function versions it actually uses\n await Promise.all([\n ...changeSet.creates.map(async (create) => {\n const filteredVersions = filterJobFunctionVersions(\n jobFunctionVersions,\n create.usedJobNames,\n );\n const shape = buildWorkflowValidationShape(create.workspaceId, create.workflow);\n await client.createWorkflow({\n workspaceId: shape.workspaceId,\n workflowName: shape.workflowName,\n mainJobFunctionName: shape.mainJobFunctionName,\n retryPolicy: shape.retryPolicy,\n concurrencyPolicy: shape.concurrencyPolicy,\n jobFunctions: filteredVersions,\n publishExecutionEvents: shape.publishExecutionEvents,\n });\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n const filteredVersions = filterJobFunctionVersions(\n jobFunctionVersions,\n update.usedJobNames,\n );\n const shape = buildWorkflowValidationShape(update.workspaceId, update.workflow);\n await client.updateWorkflow({\n workspaceId: shape.workspaceId,\n workflowName: shape.workflowName,\n mainJobFunctionName: shape.mainJobFunctionName,\n retryPolicy: shape.retryPolicy,\n concurrencyPolicy: shape.concurrencyPolicy,\n jobFunctions: filteredVersions,\n publishExecutionEvents: shape.publishExecutionEvents,\n });\n await writeMetadataLabels(client, update.metaRequest);\n }),\n // An unchanged workflow still gets its labels written, because its dependency\n // records can change while its definition does not.\n ...changeSet.unchanged.flatMap((entry) =>\n entry.metaRequest ? [writeMetadataLabels(client, entry.metaRequest)] : [],\n ),\n ]);\n } else {\n await deleteAllSettled(\n changeSet.deletes.map((del) => ({\n resourceType: \"workflow\",\n resourceName: del.name,\n run: () =>\n client.deleteWorkflow({\n workspaceId: del.workspaceId,\n workflowId: del.workflowId,\n }),\n })),\n );\n\n await deleteAllSettled(\n result.jobFunctionDeletes.map((del) => ({\n resourceType: \"workflow job function\",\n resourceName: del.jobFunctionName,\n run: () =>\n client.deleteWorkflowJobFunction({\n workspaceId: del.workspaceId,\n jobFunctionName: del.jobFunctionName,\n }),\n })),\n );\n }\n}\n\ntype DeleteOperation = {\n resourceType: string;\n resourceName: string;\n run: () => Promise<unknown>;\n};\n\nasync function deleteAllSettled(operations: readonly DeleteOperation[]) {\n const results = await Promise.allSettled(operations.map((operation) => operation.run()));\n const errors: unknown[] = [];\n results.forEach((result, index) => {\n if (result.status === \"fulfilled\") {\n return;\n }\n const operation = assertDefined(operations[index], \"operation missing at index\");\n const error = result.reason;\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return;\n }\n if (error instanceof ConnectError && error.code === Code.FailedPrecondition) {\n logger.warn(\n `Skipped deleting ${operation.resourceType} \"${operation.resourceName}\" because it is still referenced.`,\n );\n return;\n }\n errors.push(error);\n });\n const firstError = errors[0];\n if (firstError) {\n throw firstError;\n }\n}\n\n/**\n * Filter job function versions to only include those used by a workflow\n * @param allVersions - Map of job function names to versions\n * @param usedJobNames - Job names used by the workflow\n * @returns Filtered job function versions\n */\nfunction filterJobFunctionVersions(\n allVersions: { [key: string]: bigint },\n usedJobNames: string[],\n): { [key: string]: bigint } {\n const filtered: { [key: string]: bigint } = {};\n for (const jobName of usedJobNames) {\n if (allVersions[jobName] !== undefined) {\n filtered[jobName] = allVersions[jobName];\n }\n }\n return filtered;\n}\n\n/**\n * Register job functions used by any workflow.\n * Only registers jobs that are actually used (based on usedJobNames in changeSet).\n * Uses create for new jobs and update for existing jobs.\n * Sets metadata on used JobFunctions.\n * @param client - Operator client instance\n * @param changeSet - Workflow change set\n * @param appName - Application name\n * @param appId - Application ID used for job function metadata when available\n * @param unchangedWorkflowJobNames - Job function names used by unchanged workflows\n * @param jobFunctionPublishEvents - Resolved `publishExecutionEvents` keyed by job function name\n * @returns Map of job function names to versions\n */\nasync function registerJobFunctions(\n client: OperatorClient,\n changeSet: ChangeSet<CreateWorkflow, UpdateWorkflow, DeleteWorkflow>,\n appName: string,\n appId: string | undefined,\n unchangedWorkflowJobNames: ReadonlySet<string> = new Set(),\n jobFunctionPublishEvents: ReadonlyMap<string, boolean> = new Map(),\n): Promise<{ [key: string]: bigint }> {\n const jobFunctionVersions: { [key: string]: bigint } = {};\n\n // Get workspaceId from the first workflow\n const firstWorkflow = changeSet.creates[0] || changeSet.updates[0] || changeSet.deletes[0];\n if (!firstWorkflow) {\n return jobFunctionVersions;\n }\n\n const { workspaceId } = firstWorkflow;\n\n // Collect all job names used by any workflow\n const allUsedJobNames = new Set<string>();\n unchangedWorkflowJobNames.forEach((jobName) => allUsedJobNames.add(jobName));\n for (const item of [...changeSet.creates, ...changeSet.updates]) {\n for (const jobName of item.usedJobNames) {\n allUsedJobNames.add(jobName);\n }\n }\n // Fetch existing job functions with their names\n const existingJobFunctions = await fetchAll(async (pageToken, maxPageSize) => {\n const response = await client.listWorkflowJobFunctions({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [response.jobFunctions.map((j) => j.name), response.nextPageToken];\n });\n const existingJobNamesSet = new Set(existingJobFunctions);\n\n if (changeSet.creates.length > 0 || changeSet.updates.length > 0) {\n // Register job functions in parallel\n // Use create for new jobs, update for existing jobs\n const results = await Promise.all(\n Array.from(allUsedJobNames).map(async (jobName) => {\n const isExisting = existingJobNamesSet.has(jobName);\n const request = {\n workspaceId,\n jobFunctionName: jobName,\n scriptRef: workflowJobFunctionName(jobName),\n publishExecutionEvents: jobFunctionPublishEvents.get(jobName) ?? false,\n };\n const response = isExisting\n ? await client.updateWorkflowJobFunction(request)\n : await client.createWorkflowJobFunction(request);\n\n // Set metadata to mark this JobFunction as owned by this app\n await writeMetadataLabels(\n client,\n await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"workflow_job_function\", jobName),\n appName,\n appId,\n }),\n );\n\n return { jobName, version: response.jobFunction?.version };\n }),\n );\n\n for (const { jobName, version } of results) {\n if (version) {\n jobFunctionVersions[jobName] = version;\n }\n }\n }\n\n return jobFunctionVersions;\n}\n\ntype CreateWorkflow = {\n name: string;\n workspaceId: string;\n workflow: Workflow;\n usedJobNames: string[];\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdateWorkflow = {\n name: string;\n workspaceId: string;\n workflow: Workflow;\n usedJobNames: string[];\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeleteWorkflow = {\n name: string;\n workspaceId: string;\n workflowId: string;\n usedJobNames: string[];\n deletableJobNames: string[];\n};\n\ntype DeleteWorkflowJobFunction = {\n workspaceId: string;\n jobFunctionName: string;\n};\n\nfunction parseDurationToProto(duration: string): { seconds: bigint; nanos: number } {\n const ms = parseDuration(duration);\n const seconds = Math.floor(ms / 1000);\n const nanos = (ms % 1000) * 1_000_000;\n return { seconds: BigInt(seconds), nanos };\n}\n\nfunction toRetryPolicy(policy: RetryPolicy): MessageInitShape<typeof RetryPolicySchema> {\n return {\n maxRetries: policy.maxRetries,\n initialBackoff: parseDurationToProto(policy.initialBackoff),\n maxBackoff: parseDurationToProto(policy.maxBackoff),\n backoffMultiplier: policy.backoffMultiplier,\n };\n}\n\nfunction toConcurrencyPolicy(\n policy: ConcurrencyPolicy,\n): MessageInitShape<typeof ConcurrencyPolicySchema> {\n return {\n maxConcurrentExecutions: policy.maxConcurrentExecutions,\n };\n}\n\n/** Plan-time init shape for Create/UpdateWorkflowRequest (jobFunctions excluded). */\nexport type WorkflowValidationShape = Omit<\n MessageInitShape<typeof CreateWorkflowRequestSchema>,\n \"jobFunctions\"\n>;\n\n/**\n * Build the plan-time validation init shape for a workflow.\n * @param workspaceId - Workspace ID\n * @param workflow - Parsed workflow object\n * @returns Init shape suitable for validating against CreateWorkflowRequestSchema and UpdateWorkflowRequestSchema\n */\nexport function buildWorkflowValidationShape(\n workspaceId: string,\n workflow: Workflow,\n): WorkflowValidationShape {\n return {\n workspaceId,\n workflowName: workflow.name,\n mainJobFunctionName: workflow.mainJob.name,\n ...(workflow.retryPolicy && { retryPolicy: toRetryPolicy(workflow.retryPolicy) }),\n ...(workflow.concurrencyPolicy && {\n concurrencyPolicy: toConcurrencyPolicy(workflow.concurrencyPolicy),\n }),\n publishExecutionEvents: workflow.publishEvents ?? false,\n };\n}\n\n/** Executors subscribing to one granularity level of workflow execution events. */\nexport type WorkflowEventSubscribers = {\n /** Workflow names named by executor triggers. */\n workflowNames: ReadonlySet<string>;\n};\n\n/**\n * A workflow whose definition is unchanged but whose dependency records may not\n * be. The plan shows it as unchanged; apply still writes its labels.\n */\ntype UnchangedWorkflow = {\n name: string;\n metaRequest?: MetadataLabelWrite;\n};\n\n/** Inputs deciding which workflows and job functions publish execution events. */\nexport type WorkflowEventPublishing = {\n /** Subscribers of `workflow.workflow_execution.*` events. */\n execution?: WorkflowEventSubscribers;\n /** Subscribers of `workflow.workflow_execution.job_execution.*` events. */\n jobExecution?: WorkflowEventSubscribers;\n /** `publishEvents` declared on jobs, keyed by job name. */\n jobPublishEvents?: ReadonlyMap<string, boolean>;\n /** Dependents the run resolved, keyed by resource. */\n dependentApps?: DependentAppsByResource;\n /** Stable ids of every application taking part in the run. */\n runAppIds?: ReadonlySet<string>;\n};\n\nconst NO_EVENT_SUBSCRIBERS: WorkflowEventSubscribers = {\n workflowNames: new Set(),\n};\n\nfunction isSubscribed(subscribers: WorkflowEventSubscribers, workflowName: string): boolean {\n return subscribers.workflowNames.has(workflowName);\n}\n\ntype ResolveJobPublishEventsParams = {\n workflows: Record<string, Workflow>;\n mainJobDeps: Record<string, string[]>;\n subscribers: WorkflowEventSubscribers;\n explicit: ReadonlyMap<string, boolean>;\n};\n\n/**\n * Job names the given workflows' subscriptions enable.\n *\n * A job execution trigger names a workflow rather than a job, so the value is\n * resolved per job name over the union of the workflows that run it: a job two\n * workflows share stays on while either one is subscribed. Whoever asks whether a\n * job still publishes has to apply that same union, which is why this is shared\n * rather than restated — the two answering it differently is what let a shared\n * job be reported as turning off while a peer subscription kept it on.\n * @param params - Workflows, the jobs each runs, and which are subscribed\n * @param params.workflows - Workflows whose job sets are considered\n * @param params.mainJobDeps - Job names each workflow runs, keyed by its main job\n * @param params.isSubscribed - Whether a workflow's jobs are subscribed in this run\n * @returns Job names those subscriptions enable\n */\nexport function subscribedWorkflowJobNames(params: {\n workflows: Iterable<{ name: string; mainJob: { name: string } }>;\n mainJobDeps: Record<string, string[]>;\n isSubscribed: (workflowName: string) => boolean;\n}): ReadonlySet<string> {\n const { workflows, mainJobDeps, isSubscribed } = params;\n const jobNames = new Set<string>();\n for (const workflow of workflows) {\n if (!isSubscribed(workflow.name)) continue;\n // A missing entry gets a fuller diagnostic from planWorkflow's own loop.\n for (const jobName of mainJobDeps[workflow.mainJob.name] ?? []) {\n jobNames.add(jobName);\n }\n }\n return jobNames;\n}\n\n/**\n * Resolve `publishExecutionEvents` for every job function used by a workflow.\n *\n * A job execution trigger names a workflow rather than a job, so a subscription\n * opts in every job that workflow runs.\n * @param params - Workflows, their job dependencies, subscribers, and explicit job flags\n * @returns Resolved flags keyed by job function name\n */\nfunction resolveJobPublishEvents(params: ResolveJobPublishEventsParams): Map<string, boolean> {\n const { workflows, mainJobDeps, subscribers, explicit } = params;\n const usedJobNames = new Set<string>();\n for (const workflow of Object.values(workflows)) {\n // A missing entry gets a fuller diagnostic from planWorkflow's own loop.\n for (const jobName of mainJobDeps[workflow.mainJob.name] ?? []) {\n usedJobNames.add(jobName);\n }\n }\n const subscribedJobNames = subscribedWorkflowJobNames({\n workflows: Object.values(workflows),\n mainJobDeps,\n isSubscribed: (workflowName) => isSubscribed(subscribers, workflowName),\n });\n\n const resolved = new Map<string, boolean>();\n for (const jobName of usedJobNames) {\n resolved.set(\n jobName,\n resolvePublishEvents({\n explicit: explicit.get(jobName),\n subscribed: subscribedJobNames.has(jobName),\n conflict: publishEventsConflict.workflowJob(jobName),\n }),\n );\n }\n return resolved;\n}\n\n/**\n * Collect job functions whose remote publishing flag no longer matches the plan.\n * @param existing - Existing job functions keyed by name\n * @param resolved - Resolved `publishExecutionEvents` keyed by job function name\n * @returns Job function names needing re-registration\n */\nfunction collectStaleJobFunctionNames(\n existing: ReadonlyMap<string, ExistingJobFunction>,\n resolved: ReadonlyMap<string, boolean>,\n): Set<string> {\n const stale = new Set<string>();\n for (const [jobName, publishEvents] of resolved) {\n const remote = existing.get(jobName);\n if (remote && remote.publishExecutionEvents !== publishEvents) {\n stale.add(jobName);\n }\n }\n return stale;\n}\n\n/**\n * Plan workflow changes and job functions based on current and desired state.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param appName - Application name\n * @param appId - Application ID used for workflow metadata when available\n * @param workflows - Parsed workflows\n * @param mainJobDeps - Main job dependencies by workflow\n * @param unchangedJobFunctions - Job functions already proven unchanged by function registry plan\n * @param eventPublishing - Executor subscriptions and explicit job flags driving execution event publishing\n * @returns Planned workflow changes\n */\nexport async function planWorkflow(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n workflows: Record<string, Workflow>,\n mainJobDeps: Record<string, string[]>,\n unchangedJobFunctions: ReadonlySet<string> = new Set<string>(),\n eventPublishing: WorkflowEventPublishing = {},\n) {\n const changeSet = createChangeSet<\n CreateWorkflow,\n UpdateWorkflow,\n DeleteWorkflow,\n never,\n UnchangedWorkflow\n >(\"Workflows\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n const unchangedWorkflowJobNames = new Set<string>();\n const retainedWorkflowJobNames = new Set<string>();\n\n const executionSubscribers = eventPublishing.execution ?? NO_EVENT_SUBSCRIBERS;\n const { dependentApps, runAppIds } = eventPublishing;\n // A workflowJobExecution subscription records on the workflow, so the workflow's\n // own declaration does not settle whether its records still matter. Dropping\n // them while a job it runs leaves publishEvents unset would delete the only\n // signal fetchMissingDependentApps looks for on that workflow.\n const everyJobDeclaresPublishEvents = (workflowName: string): boolean => {\n const jobNames = mainJobDeps[workflows[workflowName]?.mainJob.name ?? \"\"] ?? [];\n const explicit = eventPublishing.jobPublishEvents ?? new Map<string, boolean>();\n return jobNames.length > 0 && jobNames.every((jobName) => explicit.has(jobName));\n };\n const existingJobFunctions = await fetchExistingJobFunctions(client, workspaceId);\n const jobFunctionPublishEvents = resolveJobPublishEvents({\n workflows,\n mainJobDeps,\n subscribers: eventPublishing.jobExecution ?? NO_EVENT_SUBSCRIBERS,\n explicit: eventPublishing.jobPublishEvents ?? new Map<string, boolean>(),\n });\n const staleJobFunctionNames = collectStaleJobFunctionNames(\n existingJobFunctions,\n jobFunctionPublishEvents,\n );\n\n const existingWorkflows = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, pageSize) => {\n const response = await client.listWorkflows({\n workspaceId,\n pageToken,\n pageSize,\n });\n return [response.workflows, response.nextPageToken];\n },\n getName: (resource) => resource.name,\n getTrn: (name) => resourceTrn(workspaceId, \"workflow\", name),\n });\n\n for (const workflow of Object.values(workflows)) {\n const existing = existingWorkflows[workflow.name];\n const metaRequest = addDependencyRecords(\n await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"workflow\", workflow.name),\n appName,\n appId,\n }),\n {\n key: eventSourceKey.workflow(workflow.name),\n dependentApps,\n runAppIds,\n pinned: workflow.publishEvents !== undefined,\n },\n );\n // The jobs' value is driven by workflowJobExecution subscribers, independently\n // of the workflow's own, so its records live in their own namespace here.\n addDependencyRecords(metaRequest, {\n key: eventSourceKey.workflowJobs(workflow.name),\n dependentApps,\n runAppIds,\n pinned: everyJobDeclaresPublishEvents(workflow.name),\n scope: \"jobs\",\n });\n // Get jobs used by this workflow from mainJobDeps\n const usedJobNames = mainJobDeps[workflow.mainJob.name];\n if (!usedJobNames) {\n throw new Error(\n `Job \"${workflow.mainJob.name}\" (mainJob of workflow \"${workflow.name}\") was not found.\\n\\n` +\n `Possible causes:\\n` +\n ` - The job is not exported as a named export\\n` +\n ` - The file containing the job is not included in workflow.files glob pattern\\n\\n` +\n `Solution:\\n` +\n ` export const ${workflow.mainJob.name} = createWorkflowJob({ name: \"${workflow.mainJob.name}\", ... })`,\n );\n }\n usedJobNames.forEach((jobName) => retainedWorkflowJobNames.add(jobName));\n\n const desiredWorkflow: Workflow = {\n ...workflow,\n publishEvents: resolvePublishEvents({\n explicit: workflow.publishEvents,\n subscribed: isSubscribed(executionSubscribers, workflow.name),\n conflict: publishEventsConflict.workflow(workflow.name),\n }),\n };\n\n if (existing) {\n const owned = trackDesiredResourceOwnership({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceType: \"Workflow\",\n resourceName: workflow.name,\n conflicts,\n unmanaged,\n });\n\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n canTreatWorkflowAsUnchanged({\n existing: existing.resource,\n workflow: desiredWorkflow,\n usedJobNames,\n unchangedJobFunctions,\n staleJobFunctionNames,\n })\n ) {\n // The definition matches, but the records may not, so the labels still go.\n changeSet.unchanged.push({ name: workflow.name, metaRequest });\n for (const jobName of usedJobNames) {\n unchangedWorkflowJobNames.add(jobName);\n }\n } else {\n changeSet.updates.push({\n name: workflow.name,\n workspaceId,\n workflow: desiredWorkflow,\n usedJobNames,\n metaRequest,\n });\n }\n delete existingWorkflows[workflow.name];\n } else {\n changeSet.creates.push({\n name: workflow.name,\n workspaceId,\n workflow: desiredWorkflow,\n usedJobNames,\n metaRequest,\n });\n }\n }\n\n const deleteWorkflows: DeleteWorkflow[] = [];\n Object.values(existingWorkflows).forEach((existing) => {\n if (!existing) {\n return;\n }\n const owned = trackRemainingResourceOwner({\n labels: existing.allLabels,\n ownerLabel: existing.label,\n appName,\n appId,\n resourceOwners,\n });\n const usedJobNames = getExistingWorkflowJobNames(existing.resource);\n if (owned) {\n deleteWorkflows.push({\n name: existing.resource.name,\n workspaceId,\n workflowId: existing.resource.id,\n usedJobNames,\n deletableJobNames: [],\n });\n } else {\n usedJobNames.forEach((jobName) => retainedWorkflowJobNames.add(jobName));\n }\n });\n\n const jobFunctionDeletes = await planWorkflowJobFunctionDeletes({\n client,\n workspaceId,\n appName,\n appId,\n existingJobFunctionNames: [...existingJobFunctions.keys()],\n retainedWorkflowJobNames,\n resourceOwners,\n });\n const deletableJobNames = new Set(jobFunctionDeletes.map((del) => del.jobFunctionName));\n\n for (const del of deleteWorkflows) {\n changeSet.deletes.push({\n ...del,\n deletableJobNames: del.usedJobNames.filter(\n (jobName) => !retainedWorkflowJobNames.has(jobName) && deletableJobNames.has(jobName),\n ),\n });\n }\n\n return {\n changeSet,\n conflicts,\n unmanaged,\n resourceOwners,\n appName,\n appId,\n unchangedWorkflowJobNames,\n jobFunctionDeletes,\n jobFunctionPublishEvents,\n };\n}\n\n/** Existing job function as reported by the platform's job function listing. */\ntype ExistingJobFunction = Pick<WorkflowJobFunctionSummary, \"name\" | \"publishExecutionEvents\">;\n\nasync function fetchExistingJobFunctions(\n client: OperatorClient,\n workspaceId: string,\n): Promise<ReadonlyMap<string, ExistingJobFunction>> {\n const jobFunctions = await fetchAll(async (pageToken, maxPageSize) => {\n const response = await client.listWorkflowJobFunctions({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [response.jobFunctions, response.nextPageToken];\n });\n return new Map(jobFunctions.map((jobFunction) => [jobFunction.name, jobFunction]));\n}\n\ntype PlanWorkflowJobFunctionDeletesParams = {\n client: OperatorClient;\n workspaceId: string;\n appName: string;\n appId: string | undefined;\n existingJobFunctionNames: readonly string[];\n retainedWorkflowJobNames: ReadonlySet<string>;\n resourceOwners: Set<string>;\n};\n\nasync function planWorkflowJobFunctionDeletes(\n params: PlanWorkflowJobFunctionDeletesParams,\n): Promise<DeleteWorkflowJobFunction[]> {\n const {\n client,\n workspaceId,\n appName,\n appId,\n existingJobFunctionNames,\n retainedWorkflowJobNames,\n resourceOwners,\n } = params;\n const candidates = existingJobFunctionNames.filter(\n (jobName) => !retainedWorkflowJobNames.has(jobName),\n );\n const owned = await Promise.all(\n candidates.map(async (jobFunctionName) => {\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"workflow_job_function\", jobFunctionName),\n });\n // Record the owner of what is skipped, so remove can say it left something\n // behind instead of reporting that it deleted everything.\n return trackRemainingResourceOwner({\n labels: metadata?.labels,\n ownerLabel: metadata?.labels[sdkNameLabelKey],\n appName,\n appId,\n resourceOwners,\n })\n ? { workspaceId, jobFunctionName }\n : undefined;\n }),\n );\n return owned.filter((item): item is DeleteWorkflowJobFunction => item !== undefined);\n}\n\ntype WorkflowDisplayEntry = GroupedDisplayEntry;\n\n/**\n * Format workflow changes for grouped dry-run display.\n * @param changeSet - Workflow changes\n * @param workflowJobFunctionChanges - Related function registry changes for workflow jobs\n * @returns Display entries for workflow output\n */\nexport function formatWorkflowChangeEntries(\n changeSet: Pick<\n ChangeSet<CreateWorkflow, UpdateWorkflow, DeleteWorkflow>,\n \"creates\" | \"updates\" | \"deletes\" | \"replaces\"\n >,\n workflowJobFunctionChanges?: RelatedFunctionRegistryChanges,\n): WorkflowDisplayEntry[] {\n return formatChangeEntriesWithFunctionRegistry(\n \"workflow\",\n changeSet,\n workflowJobFunctionChanges,\n (item) =>\n \"usedJobNames\" in item\n ? item.usedJobNames.map((jobName) => workflowJobFunctionName(jobName))\n : [],\n );\n}\n\ntype ExistingWorkflowResource = {\n mainJobFunctionName?: string;\n retryPolicy?: {\n maxRetries?: number;\n backoffMultiplier?: number;\n initialBackoff?: { seconds?: bigint; nanos?: number };\n maxBackoff?: { seconds?: bigint; nanos?: number };\n };\n concurrencyPolicy?: {\n maxConcurrentExecutions?: number;\n };\n jobFunctions?: Record<string, string | bigint>;\n publishExecutionEvents?: boolean;\n};\n\ntype CanTreatWorkflowAsUnchangedParams = {\n existing: ExistingWorkflowResource;\n workflow: Workflow;\n usedJobNames: string[];\n unchangedJobFunctions: ReadonlySet<string>;\n staleJobFunctionNames: ReadonlySet<string>;\n};\n\nfunction canTreatWorkflowAsUnchanged(params: CanTreatWorkflowAsUnchangedParams) {\n const { existing, workflow, usedJobNames, unchangedJobFunctions, staleJobFunctionNames } = params;\n if (!usedJobNames.every((jobName) => unchangedJobFunctions.has(jobName))) {\n return false;\n }\n // Job functions are only re-registered while applying a workflow create/update.\n if (usedJobNames.some((jobName) => staleJobFunctionNames.has(jobName))) {\n return false;\n }\n return areWorkflowsEqual(existing, workflow, usedJobNames);\n}\n\nfunction areWorkflowsEqual(\n existing: ExistingWorkflowResource,\n workflow: Workflow,\n usedJobNames: readonly string[],\n) {\n return (\n existing.mainJobFunctionName === workflow.mainJob.name &&\n (existing.publishExecutionEvents ?? false) === (workflow.publishEvents ?? false) &&\n areNormalizedEqual(\n normalizeComparableExistingWorkflowRetryPolicy(existing.retryPolicy),\n normalizeComparableWorkflowRetryPolicy(workflow.retryPolicy),\n ) &&\n areNormalizedEqual(\n normalizeComparableConcurrencyPolicy(existing.concurrencyPolicy),\n normalizeComparableConcurrencyPolicy(workflow.concurrencyPolicy),\n ) &&\n areNormalizedEqual(\n normalizeComparableWorkflowJobNames(existing.jobFunctions),\n normalizeComparableWorkflowJobNames(usedJobNames),\n )\n );\n}\n\nfunction normalizeComparableExistingWorkflowRetryPolicy(\n policy:\n | {\n maxRetries?: number;\n backoffMultiplier?: number;\n initialBackoff?: { seconds?: bigint; nanos?: number };\n maxBackoff?: { seconds?: bigint; nanos?: number };\n }\n | undefined,\n) {\n if (!policy) {\n return undefined;\n }\n\n return normalizeRetryPolicyForCompare({\n maxRetries: policy.maxRetries ?? 0,\n backoffMultiplier: policy.backoffMultiplier ?? 0,\n initialBackoff: {\n seconds: policy.initialBackoff?.seconds ?? 0n,\n nanos: policy.initialBackoff?.nanos ?? 0,\n },\n maxBackoff: {\n seconds: policy.maxBackoff?.seconds ?? 0n,\n nanos: policy.maxBackoff?.nanos ?? 0,\n },\n });\n}\n\nfunction normalizeComparableWorkflowRetryPolicy(policy: RetryPolicy | undefined) {\n if (!policy) {\n return undefined;\n }\n\n return normalizeRetryPolicyForCompare({\n maxRetries: policy.maxRetries,\n backoffMultiplier: policy.backoffMultiplier,\n initialBackoff: parseDurationToProto(policy.initialBackoff),\n maxBackoff: parseDurationToProto(policy.maxBackoff),\n });\n}\n\nfunction normalizeComparableConcurrencyPolicy(\n policy: { maxConcurrentExecutions?: number } | undefined,\n) {\n if (!policy || !policy.maxConcurrentExecutions) {\n return undefined;\n }\n return { maxConcurrentExecutions: policy.maxConcurrentExecutions };\n}\n\nfunction normalizeComparableWorkflowJobNames(\n jobFunctions: Record<string, string | bigint> | readonly string[] | undefined,\n) {\n return Array.isArray(jobFunctions)\n ? jobFunctions.toSorted()\n : Object.keys(jobFunctions ?? {}).toSorted();\n}\n\nfunction getExistingWorkflowJobNames(existing: {\n mainJobFunctionName?: string;\n jobFunctions?: Record<string, string | bigint>;\n}) {\n const jobNames = new Set(Object.keys(existing.jobFunctions ?? {}));\n if (existing.mainJobFunctionName) {\n jobNames.add(existing.mainJobFunctionName);\n }\n return [...jobNames].toSorted();\n}\n\nfunction normalizeRetryPolicyForCompare(policy: {\n maxRetries: number;\n backoffMultiplier: number;\n initialBackoff: { seconds: bigint | number; nanos: number };\n maxBackoff: { seconds: bigint | number; nanos: number };\n}) {\n return {\n maxRetries: policy.maxRetries,\n backoffMultiplier: policy.backoffMultiplier,\n initialBackoff: {\n seconds: String(policy.initialBackoff.seconds),\n nanos: policy.initialBackoff.nanos,\n },\n maxBackoff: {\n seconds: String(policy.maxBackoff.seconds),\n nanos: policy.maxBackoff.nanos,\n },\n };\n}\n","import { type OperatorClient } from \"#/cli/shared/client\";\nimport { WorkflowJobFunctionExecutionPolicySchema } from \"#/parser/service/workflow/schema\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n type MetadataLabelWrite,\n resourceTrn,\n writeMetadataLabels,\n} from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { ExecutionPolicyInstance } from \"#/configure/services/workflow/execution-policy.types\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase } from \"./phase\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { ConcurrencyPolicySchema } from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\n\ntype CreatePolicy = {\n name: string;\n workspaceId: string;\n policy: ExecutionPolicyInstance;\n metaRequest: MetadataLabelWrite;\n};\n\ntype UpdatePolicy = {\n name: string;\n workspaceId: string;\n policy: ExecutionPolicyInstance;\n metaRequest: MetadataLabelWrite;\n};\n\ntype DeletePolicy = {\n name: string;\n workspaceId: string;\n};\n\ntype ReplacePolicy = {\n name: string;\n workspaceId: string;\n policy: ExecutionPolicyInstance;\n metaRequest: MetadataLabelWrite;\n};\n\nfunction toConcurrencyPolicyInit(\n policy: ExecutionPolicyInstance[\"concurrencyPolicy\"],\n): MessageInitShape<typeof ConcurrencyPolicySchema> | undefined {\n if (!policy) return undefined;\n return { maxConcurrentExecutions: policy.maxConcurrentExecutions };\n}\n\nfunction normalizeComparableConcurrency(\n policy: { maxConcurrentExecutions?: number } | undefined,\n): { maxConcurrentExecutions: number } | undefined {\n if (!policy || !policy.maxConcurrentExecutions) return undefined;\n return { maxConcurrentExecutions: policy.maxConcurrentExecutions };\n}\n\n/**\n * The declared key prefix, regardless of variant. `ExecutionPolicyWildcardInstance`\n * omits `key` from its public type to force callers through `keyFor()`, but\n * the underlying value always carries it when produced by\n * `defineWorkflowExecutionPolicy()` or `defineWorkflowExecutionPolicies()`.\n * @param policy - Declared policy from the config\n * @returns The declared key prefix\n */\nfunction declaredKey(policy: ExecutionPolicyInstance): string {\n if (policy.matchType === \"exact\") return policy.key;\n const key = (policy as unknown as { key?: string }).key;\n if (typeof key !== \"string\") {\n throw new Error(\n `Invalid workflow execution policy \"${policy.name}\": prefix policies must be created via defineWorkflowExecutionPolicy() or defineWorkflowExecutionPolicies(), not a hand-constructed object.`,\n );\n }\n return key;\n}\n\n/**\n * The literal key the platform registers for a declared policy: `key` with a\n * trailing `*` appended when `matchType` is `\"prefix\"`.\n * @param policy - Declared policy from the config\n * @returns The platform-facing execution policy key\n */\nexport function toPlatformExecutionPolicyKey(policy: ExecutionPolicyInstance): string {\n const key = declaredKey(policy);\n return policy.matchType === \"prefix\" ? `${key}*` : key;\n}\n\n/**\n * Validate a declared execution policy against the parser schema. Throws with\n * a descriptive error when `name` or the platform-facing key violates the\n * platform grammar.\n * @param policy - Declared policy from the config\n */\nfunction validatePolicy(policy: ExecutionPolicyInstance): void {\n if (declaredKey(policy).endsWith(\"*\")) {\n throw new Error(\n `Invalid workflow execution policy \"${policy.name}\": key must not end with '*'; omit the '*' and set matchType: \"prefix\" for wildcard policies (the SDK appends '*' automatically).`,\n );\n }\n const parsed = WorkflowJobFunctionExecutionPolicySchema.safeParse({\n name: policy.name,\n key: toPlatformExecutionPolicyKey(policy),\n concurrencyPolicy: policy.concurrencyPolicy,\n });\n if (!parsed.success) {\n throw new Error(\n `Invalid workflow execution policy \"${policy.name}\": ${parsed.error.issues.map((issue) => issue.message).join(\"; \")}`,\n );\n }\n}\n\n/**\n * Plan workflow job function execution policy changes based on desired\n * declarations and current remote state.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param appName - Application name\n * @param appId - Application ID for ownership metadata\n * @param declared - Policies declared in the config (property name → instance)\n * @returns Planned execution policy changes\n */\nexport async function planWorkflowJobFunctionExecutionPolicy(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n appId: string | undefined,\n declared: Record<string, ExecutionPolicyInstance>,\n) {\n const changeSet = createChangeSet<CreatePolicy, UpdatePolicy, DeletePolicy, ReplacePolicy>(\n \"Workflow execution policies\",\n );\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const declaredList = Object.values(declared);\n for (const policy of declaredList) {\n validatePolicy(policy);\n }\n\n const existing = await fetchExistingResourcesWithLabels({\n client,\n fetchPage: async (pageToken, pageSize) => {\n const response = await client.listWorkflowJobFunctionExecutionPolicies({\n workspaceId,\n pageToken,\n pageSize,\n });\n return [response.policies, response.nextPageToken];\n },\n getName: (resource) => resource.name,\n getTrn: (name) => resourceTrn(workspaceId, \"workflow_job_function_execution_policy\", name),\n });\n\n const seenNames = new Set<string>();\n for (const policy of declaredList) {\n if (seenNames.has(policy.name)) {\n throw new Error(\n `Duplicate workflow execution policy name \"${policy.name}\". Each policy must have a unique name within the workspace.`,\n );\n }\n seenNames.add(policy.name);\n\n const currentTrn = resourceTrn(\n workspaceId,\n \"workflow_job_function_execution_policy\",\n policy.name,\n );\n const metaRequest = await buildMetaRequest({ trn: currentTrn, appName, appId });\n const found = existing[policy.name];\n\n if (found) {\n const owned = trackDesiredResourceOwnership({\n labels: found.allLabels,\n ownerLabel: found.label,\n appName,\n appId,\n resourceType: \"Workflow execution policy\",\n resourceName: policy.name,\n conflicts,\n unmanaged,\n });\n\n const remoteKey = found.resource.executionPolicyKey;\n const desiredKey = toPlatformExecutionPolicyKey(policy);\n const remoteConcurrency = normalizeComparableConcurrency(found.resource.concurrencyPolicy);\n const desiredConcurrency = normalizeComparableConcurrency(policy.concurrencyPolicy);\n const unchanged =\n owned &&\n hasMatchingSdkVersion(found.allLabels, metaRequest.labels) &&\n remoteKey === desiredKey &&\n areNormalizedEqual(remoteConcurrency, desiredConcurrency);\n\n if (unchanged) {\n changeSet.unchanged.push({ name: policy.name });\n } else if (remoteKey !== desiredKey) {\n // execution_policy_key is immutable after create; the platform requires\n // a delete-then-create in the same apply pass. Handled as `replaces`\n // (not delete + create) so the create phase does not race the delete.\n changeSet.replaces.push({ name: policy.name, workspaceId, policy, metaRequest });\n } else {\n changeSet.updates.push({ name: policy.name, workspaceId, policy, metaRequest });\n }\n delete existing[policy.name];\n } else {\n changeSet.creates.push({ name: policy.name, workspaceId, policy, metaRequest });\n }\n }\n\n for (const [name, remaining] of Object.entries(existing)) {\n if (!remaining) continue;\n const owned = trackRemainingResourceOwner({\n labels: remaining.allLabels,\n ownerLabel: remaining.label,\n appName,\n appId,\n resourceOwners,\n });\n if (owned) {\n changeSet.deletes.push({ name, workspaceId });\n }\n }\n\n return { changeSet, conflicts, unmanaged, resourceOwners };\n}\n\n/**\n * Apply planned workflow execution policy changes for the given phase.\n * @param client - Operator client instance\n * @param plan - Result of `planWorkflowJobFunctionExecutionPolicy`\n * @param phase - Apply phase\n * @returns Promise that resolves when policies are applied\n */\nexport async function applyWorkflowJobFunctionExecutionPolicy(\n client: OperatorClient,\n plan: Awaited<ReturnType<typeof planWorkflowJobFunctionExecutionPolicy>>,\n phase: Extract<ApplyPhase, \"create-update\" | \"delete\"> = \"create-update\",\n): Promise<void> {\n const { changeSet } = plan;\n if (phase === \"create-update\") {\n await Promise.all([\n // Replacements delete-then-create the same name (execution_policy_key is\n // immutable); each replace runs sequentially so the create never races\n // its own delete and hits AlreadyExists.\n ...changeSet.replaces.map(async (replace) => {\n await client.deleteWorkflowJobFunctionExecutionPolicy({\n workspaceId: replace.workspaceId,\n executionPolicyName: replace.name,\n });\n await client.createWorkflowJobFunctionExecutionPolicy({\n workspaceId: replace.workspaceId,\n executionPolicyName: replace.policy.name,\n executionPolicyKey: toPlatformExecutionPolicyKey(replace.policy),\n concurrencyPolicy: toConcurrencyPolicyInit(replace.policy.concurrencyPolicy),\n });\n await writeMetadataLabels(client, replace.metaRequest);\n }),\n ...changeSet.creates.map(async (create) => {\n await client.createWorkflowJobFunctionExecutionPolicy({\n workspaceId: create.workspaceId,\n executionPolicyName: create.policy.name,\n executionPolicyKey: toPlatformExecutionPolicyKey(create.policy),\n concurrencyPolicy: toConcurrencyPolicyInit(create.policy.concurrencyPolicy),\n });\n await writeMetadataLabels(client, create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n await client.updateWorkflowJobFunctionExecutionPolicy({\n workspaceId: update.workspaceId,\n executionPolicyName: update.policy.name,\n concurrencyPolicy: toConcurrencyPolicyInit(update.policy.concurrencyPolicy),\n });\n await writeMetadataLabels(client, update.metaRequest);\n }),\n ]);\n } else {\n await Promise.all(\n changeSet.deletes.map((del) =>\n client.deleteWorkflowJobFunctionExecutionPolicy({\n workspaceId: del.workspaceId,\n executionPolicyName: del.name,\n }),\n ),\n );\n }\n}\n","import { withSpan } from \"#/cli/telemetry/index\";\nimport { applyAIGateway, type planAIGateway } from \"./aigateway\";\nimport { applyApplication, type planApplication } from \"./application\";\nimport { applyAuth, type planAuth } from \"./auth\";\nimport { applyExecutor, type planExecutor } from \"./executor\";\nimport { applyFunctionRegistry, type planFunctionRegistry } from \"./function-registry\";\nimport { applyIdP, type planIdP } from \"./idp\";\nimport { applyPipeline, type planPipeline } from \"./resolver\";\nimport { applySecretManager, type planSecretManager } from \"./secret-manager\";\nimport { applyStaticWebsite, type planStaticWebsite } from \"./staticwebsite\";\nimport { applyTailorDB, preflightTailorDB, type planTailorDB } from \"./tailordb\";\nimport { applyWorkflow, type planWorkflow } from \"./workflow\";\nimport {\n applyWorkflowJobFunctionExecutionPolicy,\n type planWorkflowJobFunctionExecutionPolicy,\n} from \"./workflow-execution-policy\";\nimport type { Application } from \"#/cli/services/application\";\nimport type { OperatorClient } from \"#/cli/shared/client\";\n\nexport type PlannedDeployment = {\n readonly application: Readonly<Application>;\n readonly functionRegistry: Awaited<ReturnType<typeof planFunctionRegistry>>;\n readonly tailorDB: Awaited<ReturnType<typeof planTailorDB>>;\n readonly staticWebsite: Awaited<ReturnType<typeof planStaticWebsite>>;\n readonly aiGateway: Awaited<ReturnType<typeof planAIGateway>>;\n readonly idp: Awaited<ReturnType<typeof planIdP>>;\n readonly auth: Awaited<ReturnType<typeof planAuth>>;\n readonly pipeline: Awaited<ReturnType<typeof planPipeline>>;\n readonly app: Awaited<ReturnType<typeof planApplication>>;\n readonly executor: Awaited<ReturnType<typeof planExecutor>>;\n readonly workflow: Awaited<ReturnType<typeof planWorkflow>>;\n readonly workflowExecutionPolicy: Awaited<\n ReturnType<typeof planWorkflowJobFunctionExecutionPolicy>\n >;\n readonly secretManager: Awaited<ReturnType<typeof planSecretManager>>;\n};\n\n/**\n * Apply planned deploy changes for one or more applications.\n * @param client - Operator client instance\n * @param workspaceId - Target workspace ID\n * @param deployments - Planned deployments to apply\n */\nexport async function applyDeploymentPlans(\n client: OperatorClient,\n workspaceId: string,\n deployments: ReadonlyArray<PlannedDeployment>,\n): Promise<void> {\n const forEachDeployment = async (\n apply: (deployment: PlannedDeployment) => Promise<unknown>,\n ): Promise<void> => {\n for (const deployment of deployments) {\n await apply(deployment);\n }\n };\n\n await withSpan(\"apply.preflight\", async () => {\n await forEachDeployment((d) => preflightTailorDB(client, d.tailorDB));\n });\n\n await withSpan(\"apply.createUpdateServices\", async () => {\n await forEachDeployment((d) =>\n applySecretManager(client, d.secretManager, \"create-update\", d.application),\n );\n await forEachDeployment((d) =>\n applyFunctionRegistry(client, workspaceId, d.functionRegistry, \"create-update\"),\n );\n await forEachDeployment((d) => applyStaticWebsite(client, d.staticWebsite, \"create-update\"));\n await forEachDeployment((d) => applyAIGateway(client, d.aiGateway, \"create-update\"));\n await forEachDeployment((d) => applyIdP(client, d.idp, \"create-update\"));\n await forEachDeployment((d) => applyAuth(client, d.auth, \"create-update-prerequisites\"));\n await forEachDeployment((d) => applyTailorDB(client, d.tailorDB, \"create-update\"));\n await forEachDeployment((d) => applyAuth(client, d.auth, \"create-update-dependents\"));\n await forEachDeployment((d) => applyPipeline(client, d.pipeline, \"create-update\"));\n });\n\n await withSpan(\"apply.deleteSubgraphResources\", async () => {\n await forEachDeployment((d) => applyPipeline(client, d.pipeline, \"delete-resources\"));\n await forEachDeployment((d) => applyAuth(client, d.auth, \"delete-resources\"));\n await forEachDeployment((d) => applyIdP(client, d.idp, \"delete-resources\"));\n });\n\n await withSpan(\"apply.createUpdateApplication\", async () => {\n await forEachDeployment((d) => applyApplication(client, d.app, \"create-update\"));\n });\n\n await withSpan(\"apply.createUpdateDependentServices\", async () => {\n await forEachDeployment((d) => applyExecutor(client, d.executor, \"create-update\"));\n // Execution policies must exist before workflow job functions that reference\n // them by key, otherwise the runtime rejects the dispatch as an unknown key.\n await forEachDeployment((d) =>\n applyWorkflowJobFunctionExecutionPolicy(client, d.workflowExecutionPolicy, \"create-update\"),\n );\n await forEachDeployment((d) => applyWorkflow(client, d.workflow, \"create-update\"));\n });\n\n await withSpan(\"apply.deleteDependentServices\", async () => {\n await forEachDeployment((d) => applyWorkflow(client, d.workflow, \"delete\"));\n await forEachDeployment((d) =>\n applyWorkflowJobFunctionExecutionPolicy(client, d.workflowExecutionPolicy, \"delete\"),\n );\n await forEachDeployment((d) => applyExecutor(client, d.executor, \"delete\"));\n await forEachDeployment((d) => applyStaticWebsite(client, d.staticWebsite, \"delete\"));\n await forEachDeployment((d) => applyAIGateway(client, d.aiGateway, \"delete\"));\n await forEachDeployment((d) =>\n applySecretManager(client, d.secretManager, \"delete\", d.application),\n );\n });\n\n await withSpan(\"apply.deleteApplication\", async () => {\n await forEachDeployment((d) => applyApplication(client, d.app, \"delete\"));\n });\n\n await withSpan(\"apply.deleteSubgraphServices\", async () => {\n await forEachDeployment((d) => applyPipeline(client, d.pipeline, \"delete-services\"));\n await forEachDeployment((d) => applyAuth(client, d.auth, \"delete-services\"));\n await forEachDeployment((d) => applyIdP(client, d.idp, \"delete-services\"));\n await forEachDeployment((d) => applyTailorDB(client, d.tailorDB, \"delete-services\"));\n });\n\n await withSpan(\"apply.cleanup\", async () => {\n await forEachDeployment((d) =>\n applyFunctionRegistry(client, workspaceId, d.functionRegistry, \"delete\"),\n );\n });\n}\n","import * as fs from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport { isCI } from \"std-env\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { parseBoolean } from \"#/cli/shared/parse-boolean\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type { CallExpression, ObjectExpression, ObjectProperty } from \"@oxc-project/types\";\n\nexport interface EnsureConfigIdResult {\n id: string;\n injected: boolean;\n}\n\n/**\n * Warn when a command that decides resource ownership resolved a config\n * without an app id.\n *\n * Injection only reaches an inline `defineConfig({...})` call, so a config\n * that re-exports one from another file resolves without an id and nothing\n * says so. Ownership then falls back to the application name, and resources\n * tagged with an id from an earlier deploy read as another application's.\n * @param appId - Application id from the resolved config, when it has one\n */\nexport function warnMissingAppId(appId: string | undefined): void {\n if (appId) return;\n logger.warn(\"The config resolved without an 'id'.\");\n logger.log(\n \" Resources tagged with an id from an earlier deploy read as another application's:\\n\" +\n \" deploy asks before taking them over, and remove leaves them in place. Only resources\\n\" +\n \" carrying no id are matched by application name.\\n\" +\n \" Add an 'id' to the object passed to defineConfig() — a config that re-exports it from\\n\" +\n \" another file cannot have one injected automatically. 'tailor setup' can add it for you.\",\n );\n}\n\ntype ASTNode = Record<string, unknown>;\n\n// The user-facing id is a plain UUID. A label-compatible prefix is added\n// at the metadata boundary in `cli/commands/deploy/label.ts`, so the\n// in-config value does not need to satisfy the platform label-value regex.\nconst uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\ninterface ConfigCallSite {\n callExpr: CallExpression;\n configObj: ObjectExpression | null;\n}\n\nfunction findDefineConfigCalls(node: unknown, results: ConfigCallSite[]): void {\n if (!node || typeof node !== \"object\") return;\n const n = node as ASTNode;\n\n if (n.type === \"CallExpression\") {\n const ce = n as unknown as CallExpression;\n if (ce.callee.type === \"Identifier\" && ce.callee.name === \"defineConfig\") {\n const arg = ce.arguments[0];\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n const configObj = arg && arg.type === \"ObjectExpression\" ? (arg as ObjectExpression) : null;\n results.push({ callExpr: ce, configObj });\n }\n }\n\n for (const key of Object.keys(n)) {\n const child = n[key];\n if (Array.isArray(child)) {\n for (const c of child) findDefineConfigCalls(c, results);\n } else if (child && typeof child === \"object\") {\n findDefineConfigCalls(child, results);\n }\n }\n}\n\nfunction findIdProperty(obj: ObjectExpression): ObjectProperty | null {\n for (const prop of obj.properties) {\n if (prop.type !== \"Property\") continue;\n const keyName =\n prop.key.type === \"Identifier\"\n ? prop.key.name\n : prop.key.type === \"Literal\"\n ? (prop.key as { value?: unknown }).value\n : null;\n if (keyName === \"id\") return prop;\n }\n return null;\n}\n\n/**\n * Ensure `tailor.config.ts` has an `id` property on the `defineConfig({...})`\n * argument. Generates a UUID when missing and writes it back to the file.\n * Returns null when the file does not contain a `defineConfig()` call (e.g.\n * a wrapper that re-exports another config).\n * @param configPath - Absolute path to the config file\n * @returns Resolved id and whether it was newly injected, or null if skipped\n */\nexport async function ensureConfigId(configPath: string): Promise<EnsureConfigIdResult | null> {\n const source = await fs.promises.readFile(configPath, \"utf-8\");\n const { program } = parseSync(configPath, source);\n\n const calls: ConfigCallSite[] = [];\n findDefineConfigCalls(program, calls);\n\n if (calls.length === 0) {\n // Wrapper/re-export file: defineConfig is in another file. Nothing to do here.\n return null;\n }\n if (calls.length > 1) {\n throw new Error(`Multiple defineConfig() calls found in ${configPath}. Only one is supported.`);\n }\n\n const { configObj } = assertDefined(calls[0], \"defineConfig call site missing\");\n if (!configObj) {\n throw new Error(\n `defineConfig() argument must be an inline object literal in ${configPath} so the SDK can manage the 'id' field.`,\n );\n }\n\n const idProp = findIdProperty(configObj);\n if (idProp) {\n const value = idProp.value;\n if (value.type !== \"Literal\") {\n throw new Error(\n `'id' field in ${configPath} must be a string literal. To use this config for a separate app, delete it.`,\n );\n }\n const literalValue = (value as { value?: unknown }).value;\n if (typeof literalValue !== \"string\" || literalValue === \"\") {\n throw new Error(\n `'id' field in ${configPath} must be a non-empty string literal. To use this config for a separate app, delete it.`,\n );\n }\n if (!uuidRegex.test(literalValue)) {\n throw new Error(\n `'id' field in ${configPath} must be a UUID. To use this config for a separate app, delete it.`,\n );\n }\n return { id: literalValue, injected: false };\n }\n\n const id = crypto.randomUUID();\n const newSource = insertIdProperty(source, configObj, id);\n await fs.promises.writeFile(configPath, newSource, \"utf-8\");\n\n logger.info(`Generated app id and wrote to ${configPath}: ${id}`);\n\n return { id, injected: true };\n}\n\n/**\n * Read the resolved `defineConfig({...})` `id` from a config file without\n * mutating it. Returns null when the file has no inline `defineConfig()` call\n * (wrapper/re-export config), and `{ id: null }` when the call exists but has\n * no usable `id` property.\n * @param configPath - Absolute path to the config file\n * @returns The existing id (or null when absent), or null for wrapper configs\n */\nasync function readConfigId(configPath: string): Promise<{ id: string | null } | null> {\n const source = await fs.promises.readFile(configPath, \"utf-8\");\n const { program } = parseSync(configPath, source);\n const calls: ConfigCallSite[] = [];\n findDefineConfigCalls(program, calls);\n if (calls.length === 0) return null;\n // Mirror ensureConfigId's shape validation so CI fails loudly on config\n // shapes whose id it cannot reliably read.\n if (calls.length > 1) {\n throw new Error(`Multiple defineConfig() calls found in ${configPath}. Only one is supported.`);\n }\n const { configObj } = assertDefined(calls[0], \"defineConfig call site missing\");\n if (!configObj) {\n throw new Error(\n `defineConfig() argument must be an inline object literal in ${configPath} so the SDK can manage the 'id' field.`,\n );\n }\n const idProp = findIdProperty(configObj);\n if (!idProp || idProp.value.type !== \"Literal\") return { id: null };\n const value = (idProp.value as { value?: unknown }).value;\n return { id: typeof value === \"string\" && value !== \"\" ? value : null };\n}\n\n/**\n * Read-only CI check: the config must already carry a valid app id.\n * Wrapper/re-export configs (no inline defineConfig call) are exempt,\n * mirroring the local behavior where {@link ensureConfigId} no-ops.\n * @param configPath - Absolute path to the config file\n */\nasync function assertConfigIdInCI(configPath: string): Promise<void> {\n const result = await readConfigId(configPath);\n if (result === null) {\n return;\n }\n if (!result.id) {\n throw new Error(\n `tailor.config.ts is missing an 'id'. CI does not auto-generate one ` +\n `(each run would be treated as a separate app and break resource ownership). ` +\n `Run 'tailor setup' or 'tailor deploy' locally and commit the injected id.`,\n );\n }\n // Keep CI and local behavior aligned: ensureConfigId() enforces the same\n // format when injecting locally.\n if (!uuidRegex.test(result.id)) {\n throw new Error(\n `'id' in ${configPath} must be a UUID. To use this config for a separate app, delete it.`,\n );\n }\n}\n\n/**\n * Ensure the config has an app id for a deploy run.\n *\n * Locally, the id is auto-injected when missing (via {@link ensureConfigId}).\n * In CI, the id is never auto-injected — a missing id is a hard error, because\n * generating one per run would create a fresh app each time and break resource\n * ownership. CI dry-runs (plan) perform the same check read-only, so a\n * forgotten id fails at PR time instead of at deploy. Ephemeral pipelines that\n * intentionally deploy a fresh app per run (such as e2e harnesses) can opt\n * back into injection with `TAILOR_CI_ALLOW_ID_INJECTION=true`.\n * Local dry-run and build-only flows skip both injection and the check (no\n * on-disk side effects are expected, and build-only never talks to the\n * platform).\n * @param obj - Inputs\n * @param obj.configPath - Absolute path to the config file\n * @param obj.dryRun - Whether this is a dry-run\n * @param obj.buildOnly - Whether this is a build-only run\n */\nexport async function ensureConfigIdForDeploy(obj: {\n configPath: string;\n dryRun: boolean;\n buildOnly: boolean;\n}): Promise<void> {\n const { configPath, dryRun, buildOnly } = obj;\n if (buildOnly) return;\n\n const allowCIInjection = parseBoolean(process.env.TAILOR_CI_ALLOW_ID_INJECTION) === true;\n const strictCI = isCI && !allowCIInjection;\n\n if (dryRun) {\n if (strictCI) {\n await assertConfigIdInCI(configPath);\n }\n return;\n }\n\n if (strictCI) {\n await assertConfigIdInCI(configPath);\n return;\n }\n\n await ensureConfigId(configPath);\n}\n\nconst idComment =\n \"// SDK-managed app id — do not edit, except when copying this config to a separate app.\";\n\nfunction insertIdProperty(source: string, configObj: ObjectExpression, id: string): string {\n const idLiteral = `id: ${JSON.stringify(id)}`;\n if (configObj.properties.length > 0) {\n const firstProp = assertDefined(configObj.properties[0], \"first property missing\");\n const lineStart = source.lastIndexOf(\"\\n\", firstProp.start - 1) + 1;\n const indent = source.slice(lineStart, firstProp.start);\n if (!/^[\\t ]*$/.test(indent)) {\n // The first property shares its line with other code (single-line\n // object literal): insert inline, where a `//` comment would swallow\n // the rest of the line and reusing the prefix as indent would\n // duplicate it.\n return source.slice(0, firstProp.start) + `${idLiteral}, ` + source.slice(firstProp.start);\n }\n const insertion = `${idComment}\\n${indent}${idLiteral},\\n${indent}`;\n return source.slice(0, firstProp.start) + insertion + source.slice(firstProp.start);\n }\n // Empty object: insert on its own lines so the `//` comment does not\n // bleed into the closing `}` / `)`. Derive indent from the line that\n // contains the opening brace.\n const openBracePos = configObj.start + 1;\n const braceLineStart = source.lastIndexOf(\"\\n\", configObj.start) + 1;\n const baseIndent = source.slice(braceLineStart).match(/^[\\t ]*/)?.[0] ?? \"\";\n const innerIndent = `${baseIndent} `;\n const insertion = `\\n${innerIndent}${idComment}\\n${innerIndent}${idLiteral},\\n${baseIndent}`;\n return source.slice(0, openBracePos) + insertion + source.slice(openBracePos);\n}\n","import { formatMigrationNumber } from \"#/cli/commands/tailordb/migrate/migration-number\";\nimport { styles, logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport ml from \"#/utils/multiline\";\nimport type { MigrationCheckpointRepair } from \"#/cli/commands/tailordb/migrate/types\";\n\nexport interface OwnerConflict {\n resourceType: string;\n resourceName: string;\n currentOwner: string;\n}\n\nexport interface UnmanagedResource {\n resourceType: string;\n resourceName: string;\n}\n\nexport async function confirmMigrationCheckpointRepairs(\n repairs: ReadonlyArray<MigrationCheckpointRepair>,\n yes: boolean,\n): Promise<void> {\n if (repairs.length === 0) return;\n\n logger.warn(\n \"TailorDB migration checkpoints and history IDs need to be updated before this deployment:\",\n );\n for (const repair of repairs.toSorted((a, b) => a.namespace.localeCompare(b.namespace))) {\n logger.log(` ${repair.namespace}:`);\n logger.log(\n ` Checkpoint: ${formatMigrationNumber(repair.from)} → ${formatMigrationNumber(repair.to)}`,\n );\n logger.log(\n ` Migration history ID: ${repair.fromHistoryId ?? \"<unset>\"} → ${repair.toHistoryId}`,\n );\n }\n logger.log(\" The checkpoint reset itself changes only metadata.\");\n logger.log(\" This deployment may still apply pending schema or data migrations afterward.\");\n\n if (yes) return;\n const confirmed = await prompt.confirm({\n message:\n \"Reset these migration checkpoints, align their history IDs, and continue with the deployment?\",\n default: false,\n });\n if (!confirmed) {\n throw new Error(\"Apply cancelled: migration checkpoint reset was not confirmed.\");\n }\n}\n\n/**\n * Confirm reassignment of resources when owner conflicts are detected.\n * Splits into three scenarios, each with its own prompt because the\n * user-facing meaning is different: the resource carries the same sdk-name and\n * an sdk-app-id the config does not match, either because the config now holds\n * a different id (regeneration) or because it holds none at all; or the\n * resource carries a different sdk-name (name mismatch).\n * @param conflicts - Detected owner conflicts\n * @param appName - Target application name\n * @param yes - Whether to auto-confirm without prompting\n * @param appId - Target application id, when the config resolves to one\n * @returns Promise that resolves when confirmation completes\n */\nexport async function confirmOwnerConflict(\n conflicts: OwnerConflict[],\n appName: string,\n yes: boolean,\n appId?: string,\n): Promise<void> {\n if (conflicts.length === 0) return;\n\n // Same sdk-name as the target app -> the resources carry an id this config\n // does not: either a new one replaced it, or the config has none at all.\n const idMismatches = conflicts.filter((c) => c.currentOwner === appName);\n const nameMismatches = conflicts.filter((c) => c.currentOwner !== appName);\n\n if (idMismatches.length > 0) {\n await (appId\n ? confirmIdRegeneration(idMismatches, appName, yes)\n : confirmMissingConfigId(idMismatches, appName, yes));\n }\n if (nameMismatches.length > 0) {\n await confirmNameMismatch(nameMismatches, appName, yes);\n }\n}\n\nasync function confirmIdRegeneration(\n conflicts: OwnerConflict[],\n appName: string,\n yes: boolean,\n): Promise<void> {\n logIdMismatch(`Application id was regenerated for \"${appName}\":`, conflicts);\n\n if (yes) {\n logger.success(\"Re-tagging resources with the new id (--yes flag specified)...\", {\n mode: \"plain\",\n });\n return;\n }\n\n const confirmed = await prompt.confirm({\n message: `Re-tag these resources with the new id for \"${appName}\"?\\n${styles.dim(\"(The id in tailor.config.ts was removed since the previous deploy, so a new one was generated)\")}`,\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Apply cancelled. Resources remain tagged with the previous id.\n To override, run again and confirm, or use --yes flag.\n `);\n }\n}\n\nfunction logIdMismatch(heading: string, conflicts: OwnerConflict[]): void {\n logger.warn(heading);\n logger.log(\" These resources are tagged with an id from an earlier deploy.\");\n logger.newline();\n logger.log(` ${styles.info(\"Resources\")}:`);\n for (const c of conflicts) {\n logger.log(` • ${styles.bold(c.resourceType)} ${styles.info(`\"${c.resourceName}\"`)}`);\n }\n}\n\nasync function confirmMissingConfigId(\n conflicts: OwnerConflict[],\n appName: string,\n yes: boolean,\n): Promise<void> {\n logIdMismatch(`No application id resolved for \"${appName}\":`, conflicts);\n\n if (yes) {\n logger.success(\"Managing these resources by name (--yes flag specified)...\", { mode: \"plain\" });\n return;\n }\n\n const confirmed = await prompt.confirm({\n message: `Drop that id and manage these resources by name for \"${appName}\"?\\n${styles.dim(\"(the config resolves without an 'id', so ownership falls back to the application name)\")}`,\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Apply cancelled. Resources remain tagged with their current id.\n Restore the 'id' in your config to keep owning them by id, or run again and confirm to own them by name.\n `);\n }\n}\n\nasync function confirmNameMismatch(\n conflicts: OwnerConflict[],\n appName: string,\n yes: boolean,\n): Promise<void> {\n const currentOwners = [...new Set(conflicts.map((c) => c.currentOwner))];\n\n logger.warn(\"Application name mismatch detected:\");\n\n logger.log(\n ` ${styles.warning(\"Current application(s)\")}: ${currentOwners.map((o) => styles.bold(`\"${o}\"`)).join(\", \")}`,\n );\n logger.log(` ${styles.success(\"New application\")}: ${styles.bold(`\"${appName}\"`)}`);\n logger.newline();\n logger.log(` ${styles.info(\"Resources\")}:`);\n for (const c of conflicts) {\n logger.log(` • ${styles.bold(c.resourceType)} ${styles.info(`\"${c.resourceName}\"`)}`);\n }\n\n if (yes) {\n logger.success(\"Updating resources (--yes flag specified)...\", {\n mode: \"plain\",\n });\n return;\n }\n\n const promptMessage =\n currentOwners.length === 1\n ? `Update these resources to be managed by \"${appName}\"?\\n${styles.dim(\"(Common when renaming your application)\")}`\n : `Update these resources to be managed by \"${appName}\"?`;\n const confirmed = await prompt.confirm({\n message: promptMessage,\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Apply cancelled. Resources remain managed by their current applications.\n To override, run again and confirm, or use --yes flag.\n `);\n }\n}\n\n/**\n * Confirm allowing tailor to manage previously unmanaged resources.\n * @param resources - Unmanaged resources\n * @param appName - Target application name\n * @param yes - Whether to auto-confirm without prompting\n * @returns Promise that resolves when confirmation completes\n */\nexport async function confirmUnmanagedResources(\n resources: UnmanagedResource[],\n appName: string,\n yes: boolean,\n): Promise<void> {\n if (resources.length === 0) return;\n\n logger.warn(\"Existing resources not tracked by tailor were found:\");\n\n logger.log(` ${styles.info(\"Resources\")}:`);\n for (const r of resources) {\n logger.log(` • ${styles.bold(r.resourceType)} ${styles.info(`\"${r.resourceName}\"`)}`);\n }\n logger.newline();\n logger.log(\" These resources may have been created by older SDK versions, Terraform, or CUE.\");\n logger.log(\" To continue, confirm that tailor should manage them.\");\n logger.log(\n \" If they are managed by another tool (e.g., Terraform), cancel and manage them there instead.\",\n );\n\n if (yes) {\n logger.success(`Adding to \"${appName}\" (--yes flag specified)...`, {\n mode: \"plain\",\n });\n return;\n }\n\n const confirmed = await prompt.confirm({\n message: `Allow tailor to manage these resources for \"${appName}\"?`,\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Apply cancelled. Resources remain unmanaged.\n To override, run again and confirm, or use --yes flag.\n `);\n }\n}\n\nexport interface ImportantResourceDeletion {\n resourceType: string;\n resourceName: string;\n}\n\n/**\n * Confirm deletion of important resources.\n * @param resources - Resources scheduled for deletion\n * @param yes - Whether to auto-confirm without prompting\n * @returns Promise that resolves when confirmation completes\n */\nexport async function confirmImportantResourceDeletion(\n resources: ImportantResourceDeletion[],\n yes: boolean,\n): Promise<void> {\n if (resources.length === 0) return;\n\n logger.warn(\"The following resources will be deleted:\");\n\n logger.log(` ${styles.info(\"Resources\")}:`);\n for (const r of resources) {\n logger.log(` • ${styles.bold(r.resourceType)} ${styles.error(`\"${r.resourceName}\"`)}`);\n }\n logger.newline();\n logger.log(\n styles.warning(\" Deleting these resources will permanently remove all associated data.\"),\n );\n\n if (yes) {\n logger.success(\"Deleting resources (--yes flag specified)...\", {\n mode: \"plain\",\n });\n return;\n }\n\n const confirmed = await prompt.confirm({\n message: \"Are you sure you want to delete these resources?\",\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Apply cancelled. Resources will not be deleted.\n To override, run again and confirm, or use --yes flag.\n `);\n }\n}\n\n/** An application recorded as needing to take part in this deploy, but absent. */\nexport interface MissingDependentApp {\n /**\n * The resource whose value is applied differently without the dependent, named\n * as messages name it, e.g. `TailorDB type \"Order\"`. Records live on the\n * resource, so this identifies one of those rather than an application.\n */\n resource: string;\n /** Stable id of the absent application. */\n appId: string;\n /** Why it has to take part in the same deploy. */\n reason: string;\n}\n\n/**\n * Confirm continuing without an application recorded as a dependency.\n *\n * A previous deploy recorded that another config's executors make this config's\n * resources publish events. Applying this config alone resolves those flags from\n * a smaller set of executors, which turns publishing off.\n * @param missing - Recorded dependencies absent from this deploy\n * @param yes - Whether `--yes` was passed\n * @returns Promise that resolves when the deploy may continue\n */\nexport async function confirmMissingDependentApps(\n missing: MissingDependentApp[],\n yes: boolean,\n): Promise<void> {\n if (missing.length === 0) return;\n\n logger.warn(\"Applications recorded as depending on this deploy are missing:\");\n for (const entry of missing) {\n logger.log(\n ` • application id ${styles.info(entry.appId)} depends on ${styles.bold(entry.resource)} (${entry.reason})`,\n );\n }\n logger.newline();\n logger.log(\" Applying without them turns off event publishing on the resources above:\");\n logger.log(\" nothing in this deploy subscribes to them, so the value resolves to false.\");\n logger.log(\" To keep it, add their configs to --config, or set publishEvents on\");\n logger.log(\" the resources above.\");\n\n if (yes) {\n logger.warn(\"Continuing without them (--yes flag specified); applying turns publishing off.\");\n return;\n }\n\n const confirmed = await prompt.confirm({\n message: \"Continue without them?\",\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Apply cancelled. Add the missing configs to --config, or set publishEvents\n explicitly on the resources that should keep publishing.\n `);\n }\n}\n","import { getOrNull } from \"#/cli/shared/client\";\nimport { eventSourceLabel } from \"#/cli/shared/publish-events\";\nimport {\n type DependencyScope,\n eventSourceKey,\n recordedDependencies,\n resolverTrn,\n resourceTrn,\n tailorDBTypeTrn,\n} from \"./label\";\nimport { subscribedWorkflowJobNames } from \"./workflow\";\nimport type { Application } from \"#/cli/services/application\";\nimport type { OperatorClient } from \"#/cli/shared/client\";\nimport type { MissingDependentApp } from \"./confirm\";\n\n/** One value this run would recompute, and where its records live. */\ntype RecomputedResource = {\n /** TRN carrying the dependency records. */\n trn: string;\n /** Key the run's own subscriptions are recorded under. */\n key: string;\n /** Which of the resource's values this entry concerns. */\n scope: DependencyScope;\n /** How it is named in the confirmation, e.g. `Workflow \"nightly\"`. */\n label: string;\n};\n\n/**\n * List the resources whose `publishEvents` this run recomputes.\n *\n * A resource that declares the value keeps it whatever the run covers, so no\n * absent config can change it and its records cannot matter. Skipping those is\n * what keeps a declared value from prompting forever.\n * @param workspaceId - Workspace being deployed to\n * @param application - Application whose resources are listed\n * @param jobsByWorkflow - Job names each workflow runs, keyed by its main job\n * @param subscribedKeys - Resources this run subscribes to, by resource key\n * @returns One entry per value that leaves `publishEvents` unset\n */\nfunction recomputedResources(\n workspaceId: string,\n application: Readonly<Application>,\n jobsByWorkflow: Record<string, string[]>,\n subscribedKeys: ReadonlySet<string>,\n): RecomputedResource[] {\n const resources: RecomputedResource[] = [];\n\n for (const service of application.tailorDBServices) {\n for (const [typeName, type] of Object.entries(service.types)) {\n if (type.settings.publishEvents === undefined) {\n resources.push({\n trn: tailorDBTypeTrn(workspaceId, service.namespace, typeName),\n key: eventSourceKey.tailorDBType(service.namespace, typeName),\n scope: \"resource\",\n label: eventSourceLabel.tailorDBType(typeName),\n });\n }\n }\n }\n\n for (const service of application.resolverServices) {\n for (const resolver of Object.values(service.resolvers)) {\n if (resolver.publishEvents === undefined) {\n resources.push({\n trn: resolverTrn(workspaceId, service.namespace, resolver.name),\n key: eventSourceKey.resolver(service.namespace, resolver.name),\n scope: \"resource\",\n label: eventSourceLabel.resolver(resolver.name),\n });\n }\n }\n }\n\n for (const idp of application.idpServices) {\n if (idp.publishEvents === undefined) {\n resources.push({\n trn: resourceTrn(workspaceId, \"idp\", idp.name),\n key: eventSourceKey.idp(idp.name),\n scope: \"resource\",\n label: eventSourceLabel.idpService(idp.name),\n });\n }\n }\n\n // A workflow carries two values: its own execution events and the ones its jobs\n // publish. Different triggers drive them, so each is asked about on its own —\n // a subscriber of one must not answer for the other.\n const explicitByJob = new Map(\n (application.workflowService?.jobs ?? []).map((job) => [job.name, job.publishEvents]),\n );\n const subscribedJobNames = subscribedWorkflowJobNames({\n workflows: Object.values(application.workflowService?.workflows ?? {}),\n mainJobDeps: jobsByWorkflow,\n isSubscribed: (workflowName) => subscribedKeys.has(eventSourceKey.workflowJobs(workflowName)),\n });\n for (const workflow of Object.values(application.workflowService?.workflows ?? {})) {\n const trn = resourceTrn(workspaceId, \"workflow\", workflow.name);\n if (workflow.publishEvents === undefined) {\n resources.push({\n trn,\n key: eventSourceKey.workflow(workflow.name),\n scope: \"resource\",\n label: eventSourceLabel.workflow(workflow.name),\n });\n }\n // Only the jobs this workflow runs decide whether its job records matter, and\n // only the ones no subscription in the run keeps on — `subscribedWorkflowJobNames`\n // applies the same union the values themselves are resolved by.\n const jobNames = jobsByWorkflow[workflow.mainJob.name] ?? [];\n if (\n jobNames.some(\n (jobName) => explicitByJob.get(jobName) === undefined && !subscribedJobNames.has(jobName),\n )\n ) {\n resources.push({\n trn,\n key: eventSourceKey.workflowJobs(workflow.name),\n scope: \"jobs\",\n label: eventSourceLabel.workflowJobs(workflow.name),\n });\n }\n }\n\n return resources;\n}\n\n/**\n * Read the applications recorded as depending on this config's resources but\n * absent from the current deploy.\n *\n * Records live on the resources rather than on the application, so this survives\n * the application being renamed and stops reporting a resource that is gone.\n *\n * A resource this run still subscribes to is skipped: its value resolves to `true`\n * from the run's own executors, so the absent config changes nothing about it and\n * asking would be asking about something that cannot happen. What is left over is\n * a resource that really does turn off.\n * @param params - Client, workspace, application, and the run's inputs\n * @param params.client - Operator client instance\n * @param params.workspaceId - Workspace being deployed to\n * @param params.application - Application being planned\n * @param params.runAppIds - Stable ids of every application in the run\n * @param params.subscribedKeys - Resources this run subscribes to, by resource key\n * @param params.jobsByWorkflow - Job names each workflow runs, keyed by its main job\n * @returns Recorded dependencies missing from the run\n */\nexport async function fetchMissingDependentApps(params: {\n client: OperatorClient;\n workspaceId: string;\n application: Readonly<Application>;\n runAppIds: ReadonlySet<string>;\n subscribedKeys: ReadonlySet<string>;\n jobsByWorkflow: Record<string, string[]>;\n}): Promise<MissingDependentApp[]> {\n const { client, workspaceId, application, runAppIds, subscribedKeys, jobsByWorkflow } = params;\n const found = await Promise.all(\n recomputedResources(workspaceId, application, jobsByWorkflow, subscribedKeys)\n .filter(({ key }) => !subscribedKeys.has(key))\n .map(async ({ trn, scope, label }) => {\n const metadata = await getOrNull(() => client.getMetadata({ trn }));\n return recordedDependencies(metadata?.metadata?.labels, scope)\n .filter((dependency) => !runAppIds.has(dependency.appId))\n .map((dependency) => ({\n resource: label,\n appId: dependency.appId,\n reason: dependency.reason,\n }));\n }),\n );\n return found.flat();\n}\n","import { create, type DescMessage } from \"@bufbuild/protobuf\";\nimport { pathToString } from \"@bufbuild/protobuf/reflect\";\nimport { createValidator, type Validator } from \"@bufbuild/protovalidate\";\nimport {\n CreateAIGatewayRequestSchema,\n UpdateAIGatewayRequestSchema,\n} from \"@tailor-platform/tailor-proto/aigateway_pb\";\nimport {\n CreateApplicationRequestSchema,\n UpdateApplicationRequestSchema,\n} from \"@tailor-platform/tailor-proto/application_pb\";\nimport {\n CreateAuthConnectionRequestSchema,\n UpdateAuthConnectionRequestSchema,\n CreateAuthHookRequestSchema,\n CreateAuthIDPConfigRequestSchema,\n CreateAuthMachineUserRequestSchema,\n CreateAuthOAuth2ClientRequestSchema,\n CreateAuthSCIMConfigRequestSchema,\n CreateAuthSCIMResourceRequestSchema,\n CreateAuthServiceRequestSchema,\n CreateTenantConfigRequestSchema,\n CreateUserProfileConfigRequestSchema,\n UpdateAuthHookRequestSchema,\n UpdateAuthIDPConfigRequestSchema,\n UpdateAuthMachineUserRequestSchema,\n UpdateAuthOAuth2ClientRequestSchema,\n UpdateAuthSCIMConfigRequestSchema,\n UpdateAuthSCIMResourceRequestSchema,\n UpdateAuthServiceRequestSchema,\n UpdateTenantConfigRequestSchema,\n UpdateUserProfileConfigRequestSchema,\n} from \"@tailor-platform/tailor-proto/auth_pb\";\nimport {\n CreateExecutorExecutorRequestSchema,\n UpdateExecutorExecutorRequestSchema,\n} from \"@tailor-platform/tailor-proto/executor_pb\";\nimport {\n CreateIdPServiceRequestSchema,\n UpdateIdPServiceRequestSchema,\n} from \"@tailor-platform/tailor-proto/idp_pb\";\nimport {\n CreatePipelineResolverRequestSchema,\n CreatePipelineServiceRequestSchema,\n UpdatePipelineResolverRequestSchema,\n UpdatePipelineServiceRequestSchema,\n} from \"@tailor-platform/tailor-proto/pipeline_pb\";\nimport {\n CreateSecretManagerSecretRequestSchema,\n CreateSecretManagerVaultRequestSchema,\n UpdateSecretManagerSecretRequestSchema,\n} from \"@tailor-platform/tailor-proto/secret_manager_pb\";\nimport {\n AddCustomDomainRequestSchema,\n CreateStaticWebsiteRequestSchema,\n UpdateStaticWebsiteRequestSchema,\n} from \"@tailor-platform/tailor-proto/staticwebsite_pb\";\nimport {\n CreateTailorDBServiceRequestSchema,\n CreateTailorDBTypeRequestSchema,\n UpdateTailorDBTypeRequestSchema,\n} from \"@tailor-platform/tailor-proto/tailordb_pb\";\nimport {\n CreateWorkflowJobFunctionExecutionPolicyRequestSchema,\n CreateWorkflowJobFunctionRequestSchema,\n CreateWorkflowRequestSchema,\n UpdateWorkflowJobFunctionExecutionPolicyRequestSchema,\n UpdateWorkflowRequestSchema,\n} from \"@tailor-platform/tailor-proto/workflow_pb\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { idpClientSecretName, idpClientVaultName } from \"./idp\";\nimport { secretCreateRequest, secretUpdateRequest, vaultCreateRequest } from \"./secret-manager\";\nimport { buildWorkflowValidationShape } from \"./workflow\";\nimport { toPlatformExecutionPolicyKey } from \"./workflow-execution-policy\";\nimport type { PlannedDeployment } from \"./apply-phases\";\n\n/** Plan results passed to validatePlan. */\nexport type ValidatePlanInput = Omit<PlannedDeployment, \"application\">;\n\ntype ViolationEntry = {\n kind: string;\n name: string;\n action: \"create\" | \"update\" | \"replace\";\n fieldPath: string;\n message: string;\n};\n\ntype HasRequest = { name: string; request: unknown };\ntype HasCreateRequest = { name: string; createRequest: unknown };\ntype HasUpdateRequest = { name: string; updateRequest: unknown };\n\ntype ValidateItemsParams<Desc extends DescMessage> = {\n validator: Validator;\n schema: Desc;\n kind: string;\n action: \"create\" | \"update\" | \"replace\";\n items: ReadonlyArray<HasRequest | HasCreateRequest | HasUpdateRequest>;\n requestKey: \"request\" | \"createRequest\" | \"updateRequest\";\n violations: ViolationEntry[];\n};\n\nfunction validateItems<Desc extends DescMessage>(params: ValidateItemsParams<Desc>): void {\n const { validator, schema, kind, action, items, requestKey, violations } = params;\n for (const item of items) {\n const init = (item as Record<string, unknown>)[requestKey];\n const msg = create(schema, init as never);\n const result = validator.validate(schema, msg);\n if (result.kind === \"invalid\") {\n for (const v of result.violations) {\n violations.push({\n kind,\n name: item.name,\n action,\n fieldPath: v.field.length > 0 ? pathToString(v.field) : \"(message)\",\n message: v.message,\n });\n }\n } else if (result.kind === \"error\") {\n // Evaluator failures must not block deploys; the platform stays the authoritative validator.\n logger.warn(`Could not validate ${kind} \"${item.name}\" (${action}): ${result.error.message}`);\n }\n }\n}\n\n/**\n * Validate all plan-time create/update requests against buf.validate constraints embedded in the\n * generated proto descriptors.\n *\n * Collections not validated: idp client, tailorDB gqlPermission, functionRegistry — no\n * buf.validate annotations.\n * Application cors, AIGateway cors, and IdP userAuthPolicy.allowedReturnOrigins receive\n * special handling: static-website URL placeholders are resolved at apply time, so the\n * relevant origin/URL constraints would false-positive on `<name>:url` entries\n * here. Application cors and AIGateway cors are dropped entirely, forgoing their\n * per-item URL/origin constraints for the whole list rather than substituting\n * placeholders; IdP `allowedReturnOrigins` instead substitutes placeholder entries\n * with a dummy origin so the per-item regex and the cross-field `enable_mfa requires\n * ≥1 origin` rule still get exercised on the rest of the payload.\n * Workflow jobFunctions map excluded: versions are registered at apply time (registerJobFunctions)\n * and the map field carries no min_items constraint. Job names are validated separately via\n * CreateWorkflowJobFunctionRequestSchema using usedJobNames from the workflow change set.\n * auth idpConfig.config (provider oneof) is absent at plan time for BuiltInIdP but carries no\n * required constraint — the request is validated as-is from the changeset.\n *\n * @param input - Plan results from the plan phase\n */\nexport async function validatePlan(input: ValidatePlanInput): Promise<void> {\n const {\n tailorDB,\n staticWebsite,\n aiGateway,\n idp,\n auth,\n pipeline,\n app,\n executor,\n workflow,\n workflowExecutionPolicy,\n secretManager,\n } = input;\n\n const validator = createValidator();\n const violations: ViolationEntry[] = [];\n\n function creates<Desc extends DescMessage>(\n schema: Desc,\n kind: string,\n items: ReadonlyArray<HasRequest>,\n ): void {\n validateItems({\n validator,\n schema,\n kind,\n action: \"create\",\n items,\n requestKey: \"request\",\n violations,\n });\n }\n\n function updates<Desc extends DescMessage>(\n schema: Desc,\n kind: string,\n items: ReadonlyArray<HasRequest>,\n ): void {\n validateItems({\n validator,\n schema,\n kind,\n action: \"update\",\n items,\n requestKey: \"request\",\n violations,\n });\n }\n\n function replaces<Desc extends DescMessage>(\n schema: Desc,\n kind: string,\n items: ReadonlyArray<HasCreateRequest>,\n ): void {\n validateItems({\n validator,\n schema,\n kind,\n action: \"replace\",\n items,\n requestKey: \"createRequest\",\n violations,\n });\n }\n\n function inPlaceReplaces<Desc extends DescMessage>(\n schema: Desc,\n kind: string,\n items: ReadonlyArray<HasUpdateRequest>,\n ): void {\n validateItems({\n validator,\n schema,\n kind,\n action: \"replace\",\n items,\n requestKey: \"updateRequest\",\n violations,\n });\n }\n\n // TailorDB service creates (UpdateService has no request field — only metaRequest)\n creates(\n CreateTailorDBServiceRequestSchema,\n \"TailorDB service\",\n tailorDB.changeSet.service.creates as HasRequest[],\n );\n\n creates(\n CreateTailorDBTypeRequestSchema,\n \"TailorDB type\",\n tailorDB.changeSet.type.creates as HasRequest[],\n );\n updates(\n UpdateTailorDBTypeRequestSchema,\n \"TailorDB type\",\n tailorDB.changeSet.type.updates as HasRequest[],\n );\n\n creates(\n CreateStaticWebsiteRequestSchema,\n \"StaticWebsite\",\n staticWebsite.changeSet.creates as HasRequest[],\n );\n updates(\n UpdateStaticWebsiteRequestSchema,\n \"StaticWebsite\",\n staticWebsite.changeSet.updates as HasRequest[],\n );\n creates(\n AddCustomDomainRequestSchema,\n \"StaticWebsite custom domain\",\n staticWebsite.customDomainChangeSet.creates as HasRequest[],\n );\n\n // cors is excluded: static-website URL placeholders are resolved at apply time.\n creates(\n CreateAIGatewayRequestSchema,\n \"AIGateway\",\n (aiGateway.changeSet.creates as HasRequest[]).map((item) => ({\n name: item.name,\n request: { ...(item.request as Record<string, unknown>), cors: undefined },\n })),\n );\n updates(\n UpdateAIGatewayRequestSchema,\n \"AIGateway\",\n (aiGateway.changeSet.updates as HasRequest[]).map((item) => ({\n name: item.name,\n request: { ...(item.request as Record<string, unknown>), cors: undefined },\n })),\n );\n\n // userAuthPolicy.allowedReturnOrigins: static-website URL placeholders\n // (`<name>:url`) are resolved at apply time. Substitute them with a dummy\n // origin so the per-item origin regex passes and the cross-field\n // `enable_mfa requires ≥1 origin` rule still sees a non-empty list; real\n // (non-placeholder) entries pass through unchanged.\n const placeholderOriginReplacement = \"https://placeholder.invalid\";\n const substituteIdpReturnOrigins = (item: HasRequest): HasRequest => {\n const request = item.request as { userAuthPolicy?: Record<string, unknown> };\n const origins = request.userAuthPolicy?.allowedReturnOrigins;\n if (!Array.isArray(origins) || origins.length === 0) {\n return item;\n }\n // Match the parser schema's placeholder shape exactly (a static-website\n // slug followed by `:url`, no path/query/fragment). A broader regex would\n // mask schema-rejected inputs that should still surface here as\n // validation errors.\n const substituted = origins.map((origin) =>\n typeof origin === \"string\" && /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]:url$/.test(origin)\n ? placeholderOriginReplacement\n : origin,\n );\n return {\n ...item,\n request: {\n ...request,\n userAuthPolicy: { ...request.userAuthPolicy, allowedReturnOrigins: substituted },\n },\n };\n };\n creates(\n CreateIdPServiceRequestSchema,\n \"IdP service\",\n (idp.changeSet.service.creates as HasRequest[]).map(substituteIdpReturnOrigins),\n );\n updates(\n UpdateIdPServiceRequestSchema,\n \"IdP service\",\n (idp.changeSet.service.updates as HasRequest[]).map(substituteIdpReturnOrigins),\n );\n\n // Validate Secret Manager vault/secret names derived from IdP client creates and updates.\n // The client name itself may be valid while the derived vault/secret name exceeds 63 chars.\n const idpClientVaultItems = [\n ...idp.changeSet.client.creates.map((c) => ({\n clientName: c.request.client?.name ?? \"\",\n namespaceName: c.request.namespaceName ?? \"\",\n workspaceId: c.request.workspaceId ?? \"\",\n })),\n ...idp.changeSet.client.updates.map((u) => ({\n clientName: u.name,\n namespaceName: u.namespaceName,\n workspaceId: u.workspaceId,\n })),\n ];\n creates(\n CreateSecretManagerVaultRequestSchema,\n \"IdP client secret\",\n idpClientVaultItems.map((item) => ({\n name: item.clientName,\n request: {\n workspaceId: item.workspaceId,\n secretmanagerVaultName: idpClientVaultName(item.namespaceName, item.clientName),\n },\n })),\n );\n creates(\n CreateSecretManagerSecretRequestSchema,\n \"IdP client secret\",\n idpClientVaultItems.map((item) => ({\n name: item.clientName,\n request: {\n workspaceId: item.workspaceId,\n secretmanagerVaultName: idpClientVaultName(item.namespaceName, item.clientName),\n secretmanagerSecretName: idpClientSecretName(item.namespaceName, item.clientName),\n },\n })),\n );\n\n creates(\n CreateAuthServiceRequestSchema,\n \"Auth service\",\n auth.changeSet.service.creates as HasRequest[],\n );\n updates(\n UpdateAuthServiceRequestSchema,\n \"Auth service\",\n auth.changeSet.service.updates as HasRequest[],\n );\n\n creates(\n CreateAuthIDPConfigRequestSchema,\n \"Auth IDP config\",\n auth.changeSet.idpConfig.creates as HasRequest[],\n );\n updates(\n UpdateAuthIDPConfigRequestSchema,\n \"Auth IDP config\",\n auth.changeSet.idpConfig.updates as HasRequest[],\n );\n\n creates(\n CreateUserProfileConfigRequestSchema,\n \"Auth user profile config\",\n auth.changeSet.userProfileConfig.creates as HasRequest[],\n );\n updates(\n UpdateUserProfileConfigRequestSchema,\n \"Auth user profile config\",\n auth.changeSet.userProfileConfig.updates as HasRequest[],\n );\n\n creates(\n CreateTenantConfigRequestSchema,\n \"Auth tenant config\",\n auth.changeSet.tenantConfig.creates as HasRequest[],\n );\n updates(\n UpdateTenantConfigRequestSchema,\n \"Auth tenant config\",\n auth.changeSet.tenantConfig.updates as HasRequest[],\n );\n\n creates(\n CreateAuthMachineUserRequestSchema,\n \"Auth machine user\",\n auth.changeSet.machineUser.creates as HasRequest[],\n );\n updates(\n UpdateAuthMachineUserRequestSchema,\n \"Auth machine user\",\n auth.changeSet.machineUser.updates as HasRequest[],\n );\n\n creates(\n CreateAuthHookRequestSchema,\n \"Auth hook\",\n auth.changeSet.authHook.creates as HasRequest[],\n );\n updates(\n UpdateAuthHookRequestSchema,\n \"Auth hook\",\n auth.changeSet.authHook.updates as HasRequest[],\n );\n\n creates(\n CreateAuthSCIMConfigRequestSchema,\n \"Auth SCIM config\",\n auth.changeSet.scim.creates as HasRequest[],\n );\n updates(\n UpdateAuthSCIMConfigRequestSchema,\n \"Auth SCIM config\",\n auth.changeSet.scim.updates as HasRequest[],\n );\n\n creates(\n CreateAuthSCIMResourceRequestSchema,\n \"Auth SCIM resource\",\n auth.changeSet.scimResource.creates as HasRequest[],\n );\n updates(\n UpdateAuthSCIMResourceRequestSchema,\n \"Auth SCIM resource\",\n auth.changeSet.scimResource.updates as HasRequest[],\n );\n\n creates(\n CreateAuthOAuth2ClientRequestSchema,\n \"OAuth2 client\",\n auth.changeSet.oauth2Client.creates as HasRequest[],\n );\n updates(\n UpdateAuthOAuth2ClientRequestSchema,\n \"OAuth2 client\",\n auth.changeSet.oauth2Client.updates as HasRequest[],\n );\n replaces(\n CreateAuthOAuth2ClientRequestSchema,\n \"OAuth2 client\",\n auth.changeSet.oauth2Client.replaces as HasCreateRequest[],\n );\n\n creates(\n CreatePipelineServiceRequestSchema,\n \"Pipeline service\",\n pipeline.changeSet.service.creates as HasRequest[],\n );\n updates(\n UpdatePipelineServiceRequestSchema,\n \"Pipeline service\",\n pipeline.changeSet.service.updates as HasRequest[],\n );\n creates(\n CreatePipelineResolverRequestSchema,\n \"Resolver\",\n pipeline.changeSet.resolver.creates as HasRequest[],\n );\n updates(\n UpdatePipelineResolverRequestSchema,\n \"Resolver\",\n pipeline.changeSet.resolver.updates as HasRequest[],\n );\n\n creates(\n CreateExecutorExecutorRequestSchema,\n \"Executor\",\n executor.changeSet.creates as HasRequest[],\n );\n updates(\n UpdateExecutorExecutorRequestSchema,\n \"Executor\",\n executor.changeSet.updates as HasRequest[],\n );\n\n creates(\n CreateWorkflowRequestSchema,\n \"Workflow\",\n workflow.changeSet.creates.map((item) => ({\n name: item.name,\n request: buildWorkflowValidationShape(item.workspaceId, item.workflow),\n })),\n );\n updates(\n UpdateWorkflowRequestSchema,\n \"Workflow\",\n workflow.changeSet.updates.map((item) => ({\n name: item.name,\n request: buildWorkflowValidationShape(item.workspaceId, item.workflow),\n })),\n );\n\n // Validate job function names using the first workspace that defines them.\n const workflowJobNameWorkspaceId =\n workflow.changeSet.creates[0]?.workspaceId ?? workflow.changeSet.updates[0]?.workspaceId ?? \"\";\n if (workflowJobNameWorkspaceId) {\n const allJobNames = new Set<string>();\n for (const item of [...workflow.changeSet.creates, ...workflow.changeSet.updates]) {\n for (const jobName of item.usedJobNames) {\n allJobNames.add(jobName);\n }\n }\n for (const jobName of workflow.unchangedWorkflowJobNames) {\n allJobNames.add(jobName);\n }\n creates(\n CreateWorkflowJobFunctionRequestSchema,\n \"Workflow job function\",\n [...allJobNames].map((jobName) => ({\n name: jobName,\n request: {\n workspaceId: workflowJobNameWorkspaceId,\n jobFunctionName: jobName,\n scriptRef: jobName,\n },\n })),\n );\n }\n\n creates(\n CreateWorkflowJobFunctionExecutionPolicyRequestSchema,\n \"Workflow execution policy\",\n // Replaces re-create the resource after deleting it (execution_policy_key is\n // immutable), so their Create-shaped request must clear validation too.\n [\n ...workflowExecutionPolicy.changeSet.creates,\n ...workflowExecutionPolicy.changeSet.replaces,\n ].map((item) => ({\n name: item.name,\n request: {\n workspaceId: item.workspaceId,\n executionPolicyName: item.policy.name,\n executionPolicyKey: toPlatformExecutionPolicyKey(item.policy),\n ...(item.policy.concurrencyPolicy && {\n concurrencyPolicy: {\n maxConcurrentExecutions: item.policy.concurrencyPolicy.maxConcurrentExecutions,\n },\n }),\n },\n })),\n );\n updates(\n UpdateWorkflowJobFunctionExecutionPolicyRequestSchema,\n \"Workflow execution policy\",\n workflowExecutionPolicy.changeSet.updates.map((item) => ({\n name: item.name,\n request: {\n workspaceId: item.workspaceId,\n executionPolicyName: item.policy.name,\n ...(item.policy.concurrencyPolicy && {\n concurrencyPolicy: {\n maxConcurrentExecutions: item.policy.concurrencyPolicy.maxConcurrentExecutions,\n },\n }),\n },\n })),\n );\n\n creates(\n CreateSecretManagerVaultRequestSchema,\n \"Secret Manager vault\",\n secretManager.vaultChangeSet.creates.map((item) => ({\n name: item.name,\n request: vaultCreateRequest(item),\n })),\n );\n creates(\n CreateSecretManagerSecretRequestSchema,\n \"Secret Manager secret\",\n secretManager.secretChangeSet.creates.map((item) => ({\n name: item.name,\n request: secretCreateRequest(item),\n })),\n );\n updates(\n UpdateSecretManagerSecretRequestSchema,\n \"Secret Manager secret\",\n secretManager.secretChangeSet.updates.map((item) => ({\n name: item.name,\n request: secretUpdateRequest(item),\n })),\n );\n\n // cors is excluded: static-website URL placeholders are resolved at apply time.\n creates(\n CreateApplicationRequestSchema,\n \"Application\",\n app.creates.map((item) => ({\n name: item.name,\n request: { ...item.request, cors: undefined },\n })),\n );\n updates(\n UpdateApplicationRequestSchema,\n \"Application\",\n [...app.updates, ...app.unchanged].map((item) => ({\n name: item.name,\n request: { ...item.request, cors: undefined },\n })),\n );\n\n creates(\n CreateAuthConnectionRequestSchema,\n \"Auth connection\",\n auth.changeSet.connection.creates as HasRequest[],\n );\n inPlaceReplaces(\n UpdateAuthConnectionRequestSchema,\n \"Auth connection\",\n auth.changeSet.connection.replaces as HasUpdateRequest[],\n );\n\n if (violations.length === 0) {\n return;\n }\n\n const resourceNames = new Set(violations.map((v) => `${v.kind}:${v.name}`));\n logger.error(\n `Pre-flight validation found ${violations.length} violation(s) across ${resourceNames.size} resource(s):`,\n );\n for (const v of violations) {\n logger.log(\n ` ${styles.resourceType(v.kind)} ${styles.resourceName(v.name)} ` +\n `(${v.action}) — ${styles.bold(v.fieldPath)}: ${v.message}`,\n );\n }\n\n throw new Error(\n `${violations.length} validation error(s) found in ${resourceNames.size} resource(s)`,\n );\n}\n","import { z } from \"zod\";\n\nexport const profileNameSchema = z.string().min(1, \"Profile must not be empty\");\n","import { z } from \"zod\";\nimport { assertDefined } from \"#/utils/assert\";\n\nexport const workspaceNameSchema = z\n .string()\n .min(3, \"Name must be at least 3 characters\")\n .max(63, \"Name must be at most 63 characters\")\n .regex(/^[a-z0-9-]+$/, \"Name can only contain lowercase letters, numbers, and hyphens\")\n .refine(\n (name) => !name.startsWith(\"-\") && !name.endsWith(\"-\"),\n \"Name cannot start or end with a hyphen\",\n );\n\n/**\n * Validate a workspace name for use in an interactive prompt.\n * @param name - Candidate workspace name\n * @returns True when valid, otherwise a validation message\n */\nexport function validateWorkspaceName(name: string): true | string {\n const result = workspaceNameSchema.safeParse(name);\n return result.success\n ? true\n : assertDefined(result.error.issues[0], \"Zod returned no issues\").message;\n}\n","import { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { renderTable } from \"./ascii-table\";\nimport type { AsciiTableConfig } from \"./ascii-table\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\n\n/**\n * Format a protobuf Timestamp to ISO string.\n * @param timestamp - Protobuf timestamp\n * @returns Date object or null if invalid\n */\nexport function formatTimestamp(timestamp: Timestamp | undefined): Date | null {\n if (!timestamp) {\n return null;\n }\n const date = timestampDate(timestamp);\n if (Number.isNaN(date.getTime())) {\n return null;\n }\n return date;\n}\n\n/**\n * Formats a table with consistent single-line border style.\n * Use this instead of importing a table-rendering package directly.\n * @param data - Table data\n * @param config - Table configuration\n * @returns Formatted table string\n */\nexport function formatTable(data: unknown[][], config?: AsciiTableConfig): string {\n return renderTable(data, config);\n}\n\n/**\n * Formats a key-value table with single-line border style.\n * @param data - Key-value pairs\n * @returns Formatted key-value table string\n */\nexport function formatKeyValueTable(data: [string, string][]): string {\n return formatTable(data, { singleLine: true });\n}\n\n/**\n * Formats a table with headers, using single-line border style.\n * Draws horizontal lines only at top, after header, and bottom.\n * @param headers - Table header labels\n * @param rows - Table rows\n * @returns Formatted table string with headers\n */\nexport function formatTableWithHeaders(headers: string[], rows: string[][]): string {\n return formatTable([headers, ...rows], {\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n}\n\n/**\n * Format a 2D array of values into a table string.\n * @param value - Value to format\n * @returns Human-readable string representation\n */\nexport function formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (Array.isArray(value)) {\n return value.map(String).join(\"\\n\");\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value, null, 2);\n }\n return String(value);\n}\n\n/**\n * Format a Date or ISO timestamp string as a human-readable relative time.\n * @param value - Date object, ISO date string, or null\n * @returns Relative time (e.g., \"5 minutes ago\") or \"N/A\" for null/invalid\n */\nexport function humanizeRelativeTime(value: Date | string | null): string {\n if (value === null) {\n return \"N/A\";\n }\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) {\n return typeof value === \"string\" ? value : \"N/A\";\n }\n return formatDistanceToNowStrict(date, { addSuffix: true });\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport pLimit from \"p-limit\";\nimport { formatTimestamp } from \"#/cli/shared/format\";\nimport { logger, type FieldTransformer } from \"#/cli/shared/logger\";\nimport type { OperatorClient } from \"#/cli/shared/client\";\nimport type { Workspace } from \"@tailor-platform/tailor-proto/workspace_resource_pb\";\n\nexport interface WorkspaceInfo {\n id: string;\n name: string;\n folderName?: string;\n organizationId?: string;\n folderId?: string;\n region: string;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\nexport interface WorkspaceDetails extends WorkspaceInfo {\n deleteProtection: boolean;\n organizationId: string;\n folderId: string;\n}\n\nexport const workspaceInfo = (workspace: Workspace, folderName?: string): WorkspaceInfo => {\n const info = {\n id: workspace.id,\n name: workspace.name,\n region: workspace.region,\n ...(workspace.organizationId ? { organizationId: workspace.organizationId } : {}),\n ...(workspace.folderId ? { folderId: workspace.folderId } : {}),\n createdAt: formatTimestamp(workspace.createTime),\n updatedAt: formatTimestamp(workspace.updateTime),\n };\n return folderName ? { ...info, folderName } : info;\n};\n\nexport const workspaceDetails = (workspace: Workspace, folderName?: string): WorkspaceDetails => {\n return {\n ...workspaceInfo(workspace, folderName),\n deleteProtection: workspace.deleteProtection,\n organizationId: workspace.organizationId,\n folderId: workspace.folderId,\n };\n};\n\nexport async function resolveWorkspaceFolderName(\n client: OperatorClient,\n workspace: Workspace,\n): Promise<string | undefined> {\n if (!workspace.organizationId || !workspace.folderId) return undefined;\n\n try {\n const response = await client.getOrganizationFolder({\n organizationId: workspace.organizationId,\n folderId: workspace.folderId,\n });\n\n return response.folder?.name || undefined;\n } catch (error) {\n if (\n error instanceof ConnectError &&\n (error.code === Code.NotFound || error.code === Code.PermissionDenied)\n ) {\n return undefined;\n }\n logger.warn(`Failed to resolve workspace folder name: ${error}`);\n return undefined;\n }\n}\n\nexport function createWorkspaceFolderNameResolver(client: OperatorClient) {\n const cache = new Map<string, Promise<string | undefined>>();\n\n return (workspace: Workspace): Promise<string | undefined> => {\n if (!workspace.organizationId || !workspace.folderId) return Promise.resolve(undefined);\n\n const cacheKey = `${workspace.organizationId}/${workspace.folderId}`;\n const cached = cache.get(cacheKey);\n if (cached) return cached;\n\n const promise = resolveWorkspaceFolderName(client, workspace);\n cache.set(cacheKey, promise);\n return promise;\n };\n}\n\nexport async function workspaceInfoWithFolderName(\n client: OperatorClient,\n workspace: Workspace,\n): Promise<WorkspaceInfo> {\n const folderName = await resolveWorkspaceFolderName(client, workspace);\n return workspaceInfo(workspace, folderName);\n}\n\nexport async function workspaceDetailsWithFolderName(\n client: OperatorClient,\n workspace: Workspace,\n): Promise<WorkspaceDetails> {\n const folderName = await resolveWorkspaceFolderName(client, workspace);\n return workspaceDetails(workspace, folderName);\n}\n\nexport async function workspaceInfosWithFolderNames(\n client: OperatorClient,\n workspaces: Workspace[],\n): Promise<WorkspaceInfo[]> {\n const resolveFolderName = createWorkspaceFolderNameResolver(client);\n const limit = pLimit(5);\n return Promise.all(\n workspaces.map((workspace) =>\n limit(async () => workspaceInfo(workspace, await resolveFolderName(workspace))),\n ),\n );\n}\n\nexport function workspaceDisplayName(workspace: Pick<WorkspaceInfo, \"name\" | \"folderName\">) {\n return workspace.folderName ? `${workspace.folderName}/${workspace.name}` : workspace.name;\n}\n\nexport function createWorkspaceNameTransformer(\n nameKey: string,\n folderNameKey: string,\n): NonNullable<FieldTransformer> {\n return (value: unknown, item: object): string => {\n const workspace = item as Record<string, unknown>;\n const name = workspace[nameKey];\n const folderName = workspace[folderNameKey];\n if (typeof name === \"string\" && typeof folderName === \"string\") {\n return workspaceDisplayName({ name, folderName });\n }\n return String(value ?? \"\");\n };\n}\n\nexport const workspaceNameTransformer = createWorkspaceNameTransformer(\"name\", \"folderName\");\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport {\n getConsoleBaseUrl,\n getOAuth2ClientId,\n getPlatformBaseUrl,\n initOperatorClient,\n isDefaultPlatform,\n type OperatorClient,\n type PlatformClientConfig,\n} from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport {\n loadAccessToken,\n loadPlatformClientConfig,\n platformConfigFromProfile,\n readPlatformConfig,\n resolveConfigUser,\n writePlatformConfig,\n} from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { profileNameSchema } from \"#/cli/shared/profile-name\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { workspaceNameSchema } from \"#/cli/shared/workspace-name\";\nimport { assertDefined } from \"#/utils/assert\";\nimport {\n workspaceDisplayName,\n workspaceInfoWithFolderName,\n workspaceNameTransformer,\n type WorkspaceInfo,\n} from \"./transform\";\nimport type { ProfileInfo } from \"../profile\";\n\n/**\n * Schema for workspace creation options\n * - name: 3-63 chars, lowercase alphanumeric and hyphens, cannot start/end with hyphen\n * - organizationId, folderId: optional UUIDs\n */\n// strip unknown keys\nconst createWorkspaceOptionsSchema = z.object({\n name: workspaceNameSchema,\n region: z.string(),\n deleteProtection: z.boolean().optional(),\n organizationId: z.uuid().optional(),\n folderId: z.uuid().optional(),\n profile: profileNameSchema.optional(),\n});\n\nexport type CreateWorkspaceOptions = z.input<typeof createWorkspaceOptionsSchema>;\nexport type ValidatedCreateWorkspaceOptions = z.output<typeof createWorkspaceOptionsSchema>;\n\nconst validateRegion = async (region: string, client: OperatorClient) => {\n const availableRegions = await client.listAvailableWorkspaceRegions({});\n if (!availableRegions.regions.includes(region)) {\n throw new Error(`Region must be one of: ${availableRegions.regions.join(\", \")}.`);\n }\n};\n\nfunction profilePlatformSettings(platformConfig?: PlatformClientConfig) {\n const hasOAuth2ClientId =\n platformConfig?.oauth2ClientId || process.env.TAILOR_PLATFORM_OAUTH2_CLIENT_ID;\n const hasConsoleUrl = platformConfig?.consoleUrl || process.env.TAILOR_PLATFORM_CONSOLE_URL;\n\n return {\n ...(isDefaultPlatform(platformConfig)\n ? {}\n : { platform_url: getPlatformBaseUrl(platformConfig) }),\n ...(hasOAuth2ClientId ? { oauth2_client_id: getOAuth2ClientId(platformConfig) } : {}),\n ...(hasConsoleUrl ? { console_url: getConsoleBaseUrl(platformConfig) } : {}),\n };\n}\n\n/**\n * Create a new workspace with the given options.\n * @param options - Workspace creation options\n * @returns Created workspace info\n */\nexport async function createWorkspace(options: CreateWorkspaceOptions): Promise<WorkspaceInfo> {\n const validated = validateCreateWorkspaceOptions(options);\n const accessToken = await loadAccessToken({ profile: validated.profile });\n const platformConfig = await loadPlatformClientConfig({ profile: validated.profile });\n const client = await initOperatorClient(accessToken, platformConfig);\n await validateRegion(validated.region, client);\n return createValidatedWorkspaceWithClient(client, validated);\n}\n\n/**\n * Create a workspace after its local options and region have been validated.\n * @param client - Authenticated Operator client\n * @param options - Validated workspace creation options\n * @returns Created workspace info\n */\nexport async function createValidatedWorkspaceWithClient(\n client: OperatorClient,\n options: ValidatedCreateWorkspaceOptions,\n): Promise<WorkspaceInfo> {\n // Create workspace\n const resp = await client.createWorkspace({\n workspaceName: options.name,\n workspaceRegion: options.region,\n deleteProtection: options.deleteProtection ?? false,\n organizationId: options.organizationId,\n folderId: options.folderId,\n });\n\n return workspaceInfoWithFolderName(\n client,\n assertDefined(resp.workspace, \"createWorkspace response missing workspace\"),\n );\n}\n\n/**\n * Validate workspace creation options without making API calls.\n * @param options - Workspace creation options\n * @returns Validated workspace creation options\n */\nexport function validateCreateWorkspaceOptions(\n options: CreateWorkspaceOptions,\n): ValidatedCreateWorkspaceOptions {\n const result = createWorkspaceOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n return result.data;\n}\n\nexport { validateWorkspaceName } from \"#/cli/shared/workspace-name\";\n\nexport const createCommand = defineAppCommand({\n name: \"create\",\n description: \"Create a new Tailor Platform workspace.\",\n args: z.strictObject({\n name: arg(z.string(), {\n alias: \"n\",\n description: \"Workspace name\",\n }),\n region: arg(z.string(), {\n alias: \"r\",\n description: \"Workspace region (us-west, asia-northeast)\",\n }),\n \"delete-protection\": arg(z.boolean().default(false), {\n alias: \"d\",\n description: \"Enable delete protection\",\n }),\n \"organization-id\": arg(z.string().optional(), {\n alias: \"o\",\n description: \"Organization ID to workspace associate with\",\n env: \"TAILOR_PLATFORM_ORGANIZATION_ID\",\n }),\n \"folder-id\": arg(z.string().optional(), {\n alias: \"f\",\n description: \"Folder ID to workspace associate with\",\n env: \"TAILOR_PLATFORM_FOLDER_ID\",\n }),\n \"profile-name\": arg(z.string().optional(), {\n alias: \"p\",\n description: \"Profile name to create\",\n }),\n profile: arg(profileNameSchema.optional(), {\n description: \"Workspace profile used for authentication and Platform selection\",\n env: \"TAILOR_PLATFORM_PROFILE\",\n }),\n \"profile-user\": arg(z.string().optional(), {\n description:\n \"User email address or machine user client ID for the profile (defaults to current user)\",\n }),\n permission: arg(z.enum([\"write\", \"read\"]).default(\"write\"), {\n description:\n \"Profile permission (requires --profile-name). 'read' blocks all write commands while the profile is active.\",\n }),\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n const profileName = args[\"profile-name\"];\n let profileSetup:\n | {\n name: string;\n user: string;\n platformSettings: ReturnType<typeof profilePlatformSettings>;\n }\n | undefined;\n if (profileName) {\n const config = await readPlatformConfig();\n if (config.profiles[profileName]) {\n throw new Error(`Profile \"${profileName}\" already exists.`);\n }\n\n const activeProfileName = args.profile;\n const activeProfileEntry = activeProfileName ? config.profiles[activeProfileName] : undefined;\n const platformConfig = activeProfileEntry\n ? platformConfigFromProfile(activeProfileEntry)\n : undefined;\n const profileUser = args[\"profile-user\"] || activeProfileEntry?.user || config.current_user;\n if (!profileUser) {\n throw new Error(\n \"Current user not found. Please login or specify --profile-user to create a profile.\",\n );\n }\n\n const resolvedProfileUser = resolveConfigUser(config, profileUser, platformConfig);\n if (!resolvedProfileUser) {\n throw new Error(\n `User \"${profileUser}\" not found.\\nPlease verify your user name and login using 'tailor login' command.`,\n );\n }\n profileSetup = {\n name: profileName,\n user: resolvedProfileUser,\n platformSettings: profilePlatformSettings(platformConfig),\n };\n }\n\n // Execute workspace create logic\n const workspace = await createWorkspace({\n name: args.name,\n region: args.region,\n deleteProtection: args[\"delete-protection\"],\n organizationId: args[\"organization-id\"],\n folderId: args[\"folder-id\"],\n profile: args.profile,\n });\n\n let profileInfo: ProfileInfo | undefined;\n if (profileSetup) {\n const config = await readPlatformConfig();\n const platformSettings = profileSetup.platformSettings;\n config.profiles[profileSetup.name] = {\n user: profileSetup.user,\n workspace_id: workspace.id,\n ...(args.permission === \"read\" ? { readonly: true } : {}),\n ...platformSettings,\n };\n writePlatformConfig(config);\n profileInfo = {\n name: profileSetup.name,\n user: profileSetup.user,\n workspaceId: workspace.id,\n permission: args.permission,\n ...(platformSettings.platform_url ? { platformUrl: platformSettings.platform_url } : {}),\n ...(platformSettings.oauth2_client_id\n ? { oauth2ClientId: platformSettings.oauth2_client_id }\n : {}),\n ...(platformSettings.console_url ? { consoleUrl: platformSettings.console_url } : {}),\n };\n\n if (!args.json) {\n logger.success(`Profile \"${profileSetup.name}\" created successfully.`);\n }\n }\n\n if (!args.json) {\n logger.success(`Workspace \"${workspaceDisplayName(workspace)}\" created successfully.`);\n }\n\n if (args.json && profileInfo) {\n logger.out({ ...workspace, profile: profileInfo });\n return;\n }\n\n logger.out(workspace, { display: { name: workspaceNameTransformer, folderName: null } });\n if (profileInfo) {\n logger.out(\"Profile:\");\n logger.out(profileInfo);\n }\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { type Order, paginationArgs, toPageDirection } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadPlatformClientConfig } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { profileNameSchema } from \"#/cli/shared/profile-name\";\nimport {\n workspaceInfosWithFolderNames,\n workspaceNameTransformer,\n type WorkspaceInfo,\n} from \"./transform\";\n\nexport interface ListWorkspacesOptions {\n order?: Order;\n limit?: number;\n profile?: string;\n}\n\n/**\n * List workspaces with an optional order and limit.\n * @param options - Workspace listing options\n * @returns List of workspaces\n */\nexport async function listWorkspaces(options?: ListWorkspacesOptions): Promise<WorkspaceInfo[]> {\n const profile = profileNameSchema.optional().parse(options?.profile);\n const accessToken = await loadAccessToken({ profile });\n const platformConfig = await loadPlatformClientConfig({ profile });\n const client = await initOperatorClient(accessToken, platformConfig);\n return listWorkspacesWithClient(client, options);\n}\n\n/**\n * List workspaces using an existing Operator client.\n * @param client - Authenticated Operator client\n * @param options - Workspace listing options\n * @returns List of workspaces\n */\nexport async function listWorkspacesWithClient(\n client: Parameters<typeof workspaceInfosWithFolderNames>[0],\n options?: ListWorkspacesOptions,\n): Promise<WorkspaceInfo[]> {\n const pageDirection = toPageDirection(options?.order);\n const workspaces = await fetchPaged(\n async (pageToken, pageSize) => {\n const { workspaces, nextPageToken } = await client.listWorkspaces({\n pageToken,\n pageSize,\n pageDirection,\n });\n return [workspaces, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return workspaceInfosWithFolderNames(client, workspaces);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all Tailor Platform workspaces.\",\n args: z.strictObject({\n ...paginationArgs(),\n profile: arg(profileNameSchema.optional(), {\n description: \"Workspace profile used for authentication and Platform selection\",\n env: \"TAILOR_PLATFORM_PROFILE\",\n }),\n }),\n run: async (args) => {\n const workspaces = await listWorkspaces({\n order: args.order,\n limit: args.limit,\n profile: args.profile,\n });\n logger.out(workspaces, {\n display: {\n name: workspaceNameTransformer,\n folderName: null,\n organizationId: null,\n folderId: null,\n updatedAt: null,\n },\n });\n },\n});\n","import { randomUUID } from \"node:crypto\";\nimport { readFile, mkdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"pathe\";\nimport { z } from \"zod\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\n\n// strip unknown keys\nconst workspaceContextSchema = z.object({\n version: z.literal(1),\n platformUrl: z.url(),\n applicationId: z.string().min(1).optional(),\n workspaceId: z.uuid(),\n});\n\nexport type WorkspaceContext = z.output<typeof workspaceContextSchema>;\n\nfunction defaultConfigPath(): string {\n return resolve(process.cwd(), \"tailor.config.ts\");\n}\n\nfunction contextPath(configPath: string): string {\n return join(dirname(configPath), getDistDir(), `${basename(configPath)}.context.json`);\n}\n\n/**\n * Load the project workspace context when it belongs to the current platform.\n * Missing, malformed, and cross-platform state is ignored.\n * @param platformUrl - Current Platform API base URL\n * @param configPath - Configuration file whose workspace selection is loaded\n * @param applicationId - Application identity that must match the saved context\n * @returns Valid context for the current platform, or undefined\n */\nexport async function loadWorkspaceContext(\n platformUrl: string,\n configPath = defaultConfigPath(),\n applicationId?: string,\n): Promise<WorkspaceContext | undefined> {\n let contents: string;\n try {\n contents = await readFile(contextPath(configPath), \"utf8\");\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return undefined;\n throw error;\n }\n\n let value: unknown;\n try {\n value = JSON.parse(contents);\n } catch {\n return undefined;\n }\n\n const result = workspaceContextSchema.safeParse(value);\n if (\n !result.success ||\n result.data.platformUrl !== platformUrl ||\n (applicationId !== undefined && result.data.applicationId !== applicationId)\n ) {\n return undefined;\n }\n return result.data;\n}\n\n/**\n * Persist the selected workspace as project-local SDK state.\n * @param context - Workspace context to persist\n * @param configPath - Configuration file whose workspace selection is persisted\n * @param applicationId - Application identity stored with the workspace selection\n */\nexport async function saveWorkspaceContext(\n context: WorkspaceContext,\n configPath = defaultConfigPath(),\n applicationId?: string,\n): Promise<void> {\n const validated = workspaceContextSchema.parse({\n ...context,\n ...(applicationId === undefined ? {} : { applicationId }),\n });\n const stateDirectory = join(dirname(configPath), getDistDir());\n const targetPath = contextPath(configPath);\n const serialized = `${JSON.stringify(validated, null, 2)}\\n`;\n try {\n if ((await readFile(targetPath, \"utf8\")) === serialized) return;\n } catch {\n // Missing or unreadable state should still fall through to the atomic replacement attempt.\n }\n const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n await mkdir(stateDirectory, { recursive: true });\n try {\n await writeFile(temporaryPath, serialized, { mode: 0o600 });\n await rename(temporaryPath, targetPath);\n } catch (error) {\n await rm(temporaryPath, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { basename } from \"pathe\";\nimport { getPlatformBaseUrl, initOperatorClient, type OperatorClient } from \"#/cli/shared/client\";\nimport {\n loadAccessToken,\n loadPlatformClientConfig,\n tryLoadWorkspaceId,\n} from \"#/cli/shared/context\";\nimport { CLIError, type CLIErrorNextAction } from \"#/cli/shared/errors\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { canPrompt, prompt } from \"#/cli/shared/prompt\";\nimport {\n createValidatedWorkspaceWithClient,\n type ValidatedCreateWorkspaceOptions,\n validateCreateWorkspaceOptions,\n validateWorkspaceName,\n} from \"../workspace/create\";\nimport { listWorkspacesWithClient } from \"../workspace/list\";\nimport { workspaceDisplayName, workspaceInfo, type WorkspaceInfo } from \"../workspace/transform\";\nimport {\n loadWorkspaceContext,\n saveWorkspaceContext,\n type WorkspaceContext,\n} from \"./workspace-context\";\n\nexport interface ResolveDeployWorkspaceOptions {\n workspaceId?: string;\n profile?: string;\n createWorkspace?: boolean;\n workspaceName?: string;\n workspaceRegion?: string;\n organizationId?: string;\n folderId?: string;\n dryRun?: boolean;\n contextTargets?: readonly WorkspaceContextTarget[];\n deployArgs?: readonly string[];\n workspaceCommandArgs?: readonly string[];\n workspaceCommandJson?: boolean;\n}\n\nexport interface WorkspaceContextTarget {\n configPath: string;\n applicationId: string;\n}\n\nexport interface ResolvedDeployWorkspace {\n client: OperatorClient;\n workspaceId: string;\n}\n\nfunction suggestedWorkspaceName(): string {\n const name = basename(process.cwd())\n .toLowerCase()\n .replaceAll(/[^a-z0-9-]+/g, \"-\")\n .replaceAll(/^-+|-+$/g, \"\")\n .slice(0, 63)\n .replace(/-+$/, \"\");\n return validateWorkspaceName(name) === true ? name : \"my-workspace\";\n}\n\nfunction executableAction(args: readonly string[]): CLIErrorNextAction {\n return { command: \"tailor\", args };\n}\n\nfunction deployArgs(options: ResolveDeployWorkspaceOptions): readonly string[] {\n return options.deployArgs ?? [\"deploy\"];\n}\n\nfunction workspaceCommandArgs(options: ResolveDeployWorkspaceOptions): readonly string[] {\n return options.workspaceCommandArgs ?? [];\n}\n\nfunction createDeployArgs(\n options: ResolveDeployWorkspaceOptions,\n name: string,\n region: string,\n): readonly string[] {\n return [\n ...deployArgs(options),\n \"--create-workspace\",\n \"--workspace-name\",\n name,\n \"--workspace-region\",\n region,\n ...(options.organizationId ? [\"--organization-id\", options.organizationId] : []),\n ...(options.folderId ? [\"--folder-id\", options.folderId] : []),\n ];\n}\n\nfunction selectDeployArgs(options: ResolveDeployWorkspaceOptions): readonly string[] {\n return [...deployArgs(options), \"--workspace-id\", \"<workspace-id>\"];\n}\n\nfunction workspaceLabel(workspace: WorkspaceInfo): string {\n const organization = workspace.organizationId ?? \"personal\";\n return `${workspaceDisplayName(workspace)} (${workspace.region}, org: ${organization}, id: ${workspace.id})`;\n}\n\nfunction workspaceMatchesRequestedIdentity(\n workspace: WorkspaceInfo,\n options: ResolveDeployWorkspaceOptions,\n): boolean {\n return (\n options.workspaceName === workspace.name &&\n options.workspaceRegion === workspace.region &&\n options.organizationId === workspace.organizationId &&\n options.folderId === workspace.folderId\n );\n}\n\nfunction workspaceIdentity(workspace: WorkspaceInfo) {\n const { id, name, region, organizationId, folderId } = workspace;\n return { id, name, region, organizationId, folderId };\n}\n\nfunction projectContextTargets(\n contextTargets?: readonly WorkspaceContextTarget[],\n): WorkspaceContextTarget[] | undefined {\n if (!contextTargets) return undefined;\n return [...new Map(contextTargets.map((target) => [target.configPath, target])).values()];\n}\n\nasync function loadProjectContexts(\n platformUrl: string,\n contextTargets?: readonly WorkspaceContextTarget[],\n): Promise<WorkspaceContext[]> {\n const targets = projectContextTargets(contextTargets);\n if (!targets || targets.length === 0) {\n const context = await loadWorkspaceContext(platformUrl);\n return context ? [context] : [];\n }\n const contexts = await Promise.all(\n targets.map(({ configPath, applicationId }) =>\n loadWorkspaceContext(platformUrl, configPath, applicationId),\n ),\n );\n return contexts.filter((context): context is WorkspaceContext => context !== undefined);\n}\n\nasync function persistWorkspaceContext(\n context: WorkspaceContext,\n contextTargets?: readonly WorkspaceContextTarget[],\n): Promise<void> {\n const targets = projectContextTargets(contextTargets);\n if (!targets || targets.length === 0) {\n await saveWorkspaceContext(context);\n return;\n }\n const results = await Promise.allSettled(\n targets.map(({ configPath, applicationId }) =>\n saveWorkspaceContext(context, configPath, applicationId),\n ),\n );\n const failures = results.filter((result) => result.status === \"rejected\");\n if (failures.length > 0) {\n throw new Error(\n failures\n .map(({ reason }) => (reason instanceof Error ? reason.message : String(reason)))\n .join(\"; \"),\n );\n }\n}\n\nasync function rememberWorkspaceContext(\n context: WorkspaceContext,\n options: ResolveDeployWorkspaceOptions,\n failurePolicy: \"error-on-partial\" | \"warn\" = \"error-on-partial\",\n): Promise<void> {\n if (options.dryRun) return;\n try {\n await persistWorkspaceContext(context, options.contextTargets);\n } catch (error) {\n const contextPathCount = projectContextTargets(options.contextTargets)?.length;\n if ((contextPathCount ?? 0) > 1 && failurePolicy === \"error-on-partial\") {\n throw CLIError({\n code: \"WORKSPACE_CONTEXT_SAVE_FAILED\",\n message: \"The workspace selection could not be saved for every configuration file.\",\n details: error instanceof Error ? error.message : String(error),\n suggestion: \"Fix project state permissions, then rerun deploy with the workspace ID.\",\n next: executableAction([...deployArgs(options), \"--workspace-id\", context.workspaceId]),\n context: {\n workspaceId: context.workspaceId,\n configPaths: options.contextTargets?.map(({ configPath }) => configPath),\n },\n });\n }\n logger.warn(\n `Could not save the project workspace selection (${error instanceof Error ? error.message : String(error)}). Continue with --workspace-id ${context.workspaceId} on later runs.`,\n );\n }\n}\n\nasync function useWorkspace(\n client: OperatorClient,\n platformUrl: string,\n workspace: WorkspaceInfo,\n options: ResolveDeployWorkspaceOptions,\n failurePolicy: \"error-on-partial\" | \"warn\" = \"error-on-partial\",\n): Promise<ResolvedDeployWorkspace> {\n await rememberWorkspaceContext(\n {\n version: 1,\n platformUrl,\n workspaceId: workspace.id,\n },\n options,\n failurePolicy,\n );\n logger.info(`Using workspace: ${workspaceLabel(workspace)}`);\n return { client, workspaceId: workspace.id };\n}\n\nfunction useRememberedWorkspace(\n client: OperatorClient,\n workspace: WorkspaceInfo,\n): ResolvedDeployWorkspace {\n logger.warn(`Using saved workspace selection: ${workspaceLabel(workspace)}`);\n return { client, workspaceId: workspace.id };\n}\n\nconst createNewWorkspaceSelection = \"create-new-workspace\";\n\nasync function chooseWorkspace(\n client: OperatorClient,\n platformUrl: string,\n workspaces: readonly WorkspaceInfo[],\n options: ResolveDeployWorkspaceOptions,\n): Promise<ResolvedDeployWorkspace> {\n const workspaceId = await prompt.select({\n message: \"Select a workspace\",\n choices: [\n ...workspaces.map((workspace) => ({\n name: workspaceLabel(workspace),\n value: workspace.id,\n })),\n { name: \"Create new workspace\", value: createNewWorkspaceSelection },\n ],\n });\n if (workspaceId === createNewWorkspaceSelection) {\n return createWorkspaceForDeploy(client, platformUrl, options);\n }\n const workspace = workspaces.find(({ id }) => id === workspaceId);\n if (!workspace) throw new Error(\"Selected workspace was not found\");\n return useWorkspace(client, platformUrl, workspace, options);\n}\n\nfunction invalidCreateOptionsError(\n options: ResolveDeployWorkspaceOptions,\n name: string,\n region: string,\n details: string,\n): Error {\n return CLIError({\n code: \"WORKSPACE_CREATE_OPTIONS_INVALID\",\n message: \"Workspace creation options are invalid.\",\n details,\n suggestion: \"Correct the workspace creation options and rerun deploy.\",\n next: executableAction(createDeployArgs(options, name, region)),\n });\n}\n\nasync function createWorkspace(\n client: OperatorClient,\n platformUrl: string,\n options: ResolveDeployWorkspaceOptions,\n availableRegions: readonly string[],\n validatedOptions?: ValidatedCreateWorkspaceOptions,\n): Promise<ResolvedDeployWorkspace> {\n let name = options.workspaceName;\n let region = options.workspaceRegion;\n const interactive = canPrompt();\n\n if (interactive) {\n name ??= await prompt.text({\n message: \"Workspace name\",\n default: suggestedWorkspaceName(),\n validate: validateWorkspaceName,\n });\n region ??= await prompt.select({\n message: \"Workspace region\",\n choices: availableRegions.map((value) => ({ name: value, value })),\n });\n } else {\n const missingOptions = [\n ...(name === undefined ? [\"--workspace-name\"] : []),\n ...(region === undefined ? [\"--workspace-region\"] : []),\n ];\n if (missingOptions.length > 0) {\n throw CLIError({\n code: \"WORKSPACE_CREATE_OPTIONS_REQUIRED\",\n message: \"Workspace creation requires a name and region in non-interactive mode.\",\n suggestion: \"Provide every workspace creation option and rerun deploy.\",\n next: executableAction(createDeployArgs(options, name ?? \"<name>\", region ?? \"<region>\")),\n context: { missingOptions },\n });\n }\n }\n\n if (!name || !region) throw new Error(\"Workspace creation options were not resolved\");\n\n let validated = validatedOptions;\n if (!validated) {\n try {\n validated = validateCreateWorkspaceOptions({\n name,\n region,\n organizationId: options.organizationId,\n folderId: options.folderId,\n });\n } catch (error) {\n throw invalidCreateOptionsError(\n options,\n name,\n region,\n error instanceof Error ? error.message : String(error),\n );\n }\n if (!availableRegions.includes(region)) {\n throw invalidCreateOptionsError(\n options,\n name,\n region,\n `Region must be one of: ${availableRegions.join(\", \")}.`,\n );\n }\n }\n\n if (interactive) {\n const scope = [\n options.organizationId ? `organization: ${options.organizationId}` : undefined,\n options.folderId ? `folder: ${options.folderId}` : undefined,\n ].filter((value): value is string => value !== undefined);\n const confirmed = await prompt.confirm({\n message: `Create workspace \"${name}\" in ${region}${scope.length > 0 ? ` (${scope.join(\", \")})` : \"\"}?`,\n default: true,\n });\n if (!confirmed) {\n throw CLIError({\n code: \"WORKSPACE_CREATION_CANCELLED\",\n message: \"Workspace creation was cancelled.\",\n });\n }\n }\n\n let workspace: WorkspaceInfo;\n try {\n workspace = await createValidatedWorkspaceWithClient(client, validated);\n } catch (error) {\n if (\n error instanceof ConnectError &&\n ![\n Code.Canceled,\n Code.Unknown,\n Code.DeadlineExceeded,\n Code.Aborted,\n Code.Internal,\n Code.Unavailable,\n Code.DataLoss,\n ].includes(error.code)\n ) {\n throw error;\n }\n throw CLIError({\n code: \"WORKSPACE_CREATION_FAILED\",\n message: \"Workspace creation did not complete successfully.\",\n details: error instanceof Error ? error.message : String(error),\n suggestion:\n \"The outcome may be uncertain. List workspaces before retrying creation to avoid duplicates.\",\n next: executableAction([\"workspace\", \"list\", ...workspaceCommandArgs(options), \"--json\"]),\n });\n }\n\n await rememberWorkspaceContext(\n {\n version: 1,\n platformUrl,\n workspaceId: workspace.id,\n },\n options,\n );\n logger.success(`Created workspace: ${workspaceLabel(workspace)}`);\n logger.info(`Reuse this workspace with: tailor deploy --workspace-id ${workspace.id}`);\n logger.info(`Or set TAILOR_PLATFORM_WORKSPACE_ID=${workspace.id}.`);\n return { client, workspaceId: workspace.id };\n}\n\nasync function createWorkspaceForDeploy(\n client: OperatorClient,\n platformUrl: string,\n options: ResolveDeployWorkspaceOptions,\n requestedRegions?: readonly string[],\n validatedOptions?: ValidatedCreateWorkspaceOptions,\n): Promise<ResolvedDeployWorkspace> {\n const regions = requestedRegions ?? (await client.listAvailableWorkspaceRegions({})).regions;\n if (options.dryRun) {\n throw CLIError({\n code: \"WORKSPACE_CREATION_DISABLED_IN_DRY_RUN\",\n message: \"Dry-run cannot create the workspace required to build a deployment plan.\",\n suggestion:\n \"Create a workspace explicitly, then rerun the same dry-run with its workspace ID.\",\n context: { availableRegions: regions },\n });\n }\n return createWorkspace(client, platformUrl, options, regions, validatedOptions);\n}\n\n/**\n * Resolve or provision the workspace used by deploy.\n * Explicit configuration wins over project context and account discovery.\n * @param options - Deploy workspace selection and creation options\n * @returns Authenticated client and resolved workspace ID\n */\nexport async function resolveDeployWorkspace(\n options: ResolveDeployWorkspaceOptions = {},\n): Promise<ResolvedDeployWorkspace> {\n const createOptionNames = [\n options.workspaceName !== undefined ? \"--workspace-name\" : undefined,\n options.workspaceRegion !== undefined ? \"--workspace-region\" : undefined,\n ].filter((name): name is string => name !== undefined);\n if (!options.createWorkspace && createOptionNames.length > 0) {\n throw CLIError({\n code: \"WORKSPACE_CREATE_FLAG_REQUIRED\",\n message: \"Workspace creation options require --create-workspace.\",\n suggestion: \"Add --create-workspace or remove the workspace creation options.\",\n next: executableAction(\n createDeployArgs(\n options,\n options.workspaceName ?? \"<name>\",\n options.workspaceRegion ?? \"<region>\",\n ),\n ),\n context: { options: createOptionNames },\n });\n }\n if (options.createWorkspace && options.workspaceName !== undefined) {\n const nameValidation = validateWorkspaceName(options.workspaceName);\n if (nameValidation !== true) {\n throw invalidCreateOptionsError(\n options,\n options.workspaceName,\n options.workspaceRegion ?? \"<region>\",\n nameValidation,\n );\n }\n }\n if (options.createWorkspace && options.workspaceRegion === \"\") {\n throw invalidCreateOptionsError(\n options,\n options.workspaceName ?? \"<name>\",\n options.workspaceRegion,\n \"Region must not be empty.\",\n );\n }\n\n const explicitWorkspaceId = await tryLoadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n const accessToken = await loadAccessToken({ profile: options.profile });\n const platformConfig = await loadPlatformClientConfig({\n profile: options.profile,\n allowMissingProfile: explicitWorkspaceId !== undefined,\n });\n const platformUrl = getPlatformBaseUrl(platformConfig);\n const client = await initOperatorClient(accessToken, platformConfig);\n\n if (explicitWorkspaceId) {\n let response;\n try {\n response = await client.getWorkspace({ workspaceId: explicitWorkspaceId });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw CLIError({\n code: \"WORKSPACE_NOT_FOUND\",\n message: `Workspace \"${explicitWorkspaceId}\" was not found.`,\n });\n }\n throw error;\n }\n if (!response.workspace) {\n throw CLIError({\n code: \"WORKSPACE_NOT_FOUND\",\n message: `Workspace \"${explicitWorkspaceId}\" was not found.`,\n });\n }\n return useWorkspace(client, platformUrl, workspaceInfo(response.workspace), options, \"warn\");\n }\n\n let requestedCreateOptions;\n if (\n options.createWorkspace &&\n options.workspaceName !== undefined &&\n options.workspaceRegion !== undefined\n ) {\n try {\n requestedCreateOptions = validateCreateWorkspaceOptions({\n name: options.workspaceName,\n region: options.workspaceRegion,\n organizationId: options.organizationId,\n folderId: options.folderId,\n });\n } catch (error) {\n throw invalidCreateOptionsError(\n options,\n options.workspaceName,\n options.workspaceRegion,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n const [contexts, workspaces] = await Promise.all([\n loadProjectContexts(platformUrl, options.contextTargets),\n listWorkspacesWithClient(client),\n ]);\n const interactive = canPrompt();\n\n const contextWorkspaceIds = new Set(contexts.map(({ workspaceId }) => workspaceId));\n const linkedWorkspace =\n contextWorkspaceIds.size === 1\n ? workspaces.find(({ id }) => contextWorkspaceIds.has(id))\n : undefined;\n if (\n linkedWorkspace &&\n (!options.createWorkspace || workspaceMatchesRequestedIdentity(linkedWorkspace, options))\n ) {\n const contextTargetCount = projectContextTargets(options.contextTargets)?.length ?? 1;\n return contexts.length === contextTargetCount\n ? useRememberedWorkspace(client, linkedWorkspace)\n : useWorkspace(client, platformUrl, linkedWorkspace, options);\n }\n\n const onlyWorkspace = workspaces.length === 1 ? workspaces[0] : undefined;\n const canReuseOnlyWorkspace =\n onlyWorkspace !== undefined &&\n requestedCreateOptions !== undefined &&\n workspaceMatchesRequestedIdentity(onlyWorkspace, options);\n let requestedRegions: { regions: readonly string[] } | undefined;\n if (requestedCreateOptions && !canReuseOnlyWorkspace) {\n requestedRegions = await client.listAvailableWorkspaceRegions({});\n if (!requestedRegions.regions.includes(requestedCreateOptions.region)) {\n throw invalidCreateOptionsError(\n options,\n requestedCreateOptions.name,\n requestedCreateOptions.region,\n `Region must be one of: ${requestedRegions.regions.join(\", \")}.`,\n );\n }\n }\n\n if (\n workspaces.length === 0 &&\n (interactive || options.createWorkspace || contexts.length === 0)\n ) {\n const regions =\n requestedRegions?.regions ?? (await client.listAvailableWorkspaceRegions({})).regions;\n if (options.dryRun || interactive || options.createWorkspace) {\n return createWorkspaceForDeploy(\n client,\n platformUrl,\n options,\n regions,\n requestedCreateOptions,\n );\n }\n\n throw CLIError({\n code: \"WORKSPACE_NOT_FOUND\",\n message: \"No workspaces are available for this account.\",\n suggestion:\n \"Create one during deploy by providing the workspace name and one of the available regions.\",\n next: executableAction(createDeployArgs(options, \"<name>\", \"<region>\")),\n context: { availableRegions: regions },\n });\n }\n\n if (contextWorkspaceIds.size > 1) {\n const canReplaceStaleContexts =\n options.createWorkspace === true &&\n options.workspaceName !== undefined &&\n options.workspaceRegion !== undefined &&\n workspaces.length === 0;\n if (!interactive && !canReplaceStaleContexts) {\n throw CLIError({\n code: \"WORKSPACE_CONTEXT_CONFLICT\",\n message: \"The deployed configuration files are linked to different workspaces.\",\n suggestion: \"Choose one workspace explicitly for the combined deployment.\",\n next: executableAction(selectDeployArgs(options)),\n context: { savedWorkspaceIds: [...contextWorkspaceIds] },\n });\n }\n if (workspaces.length > 0 && !options.createWorkspace) {\n return chooseWorkspace(client, platformUrl, workspaces, options);\n }\n }\n\n if (!linkedWorkspace && contexts.length > 0) {\n const explicitlyEnsuringSingleTarget =\n options.createWorkspace === true &&\n options.workspaceName !== undefined &&\n options.workspaceRegion !== undefined &&\n workspaces.length <= 1;\n if (!interactive && !explicitlyEnsuringSingleTarget) {\n throw CLIError({\n code: \"WORKSPACE_CONTEXT_STALE\",\n message: \"The saved project workspace is no longer available.\",\n suggestion: \"Choose an available workspace explicitly before deploying.\",\n next: executableAction(selectDeployArgs(options)),\n context: {\n savedWorkspaceIds: [...contextWorkspaceIds],\n workspaces: workspaces.map(workspaceIdentity),\n },\n });\n }\n if (workspaces.length > 0 && interactive && !options.createWorkspace) {\n return chooseWorkspace(client, platformUrl, workspaces, options);\n }\n }\n\n if (workspaces.length === 1) {\n const [workspace] = workspaces;\n if (!workspace) throw new Error(\"Workspace discovery returned an invalid result\");\n\n if (options.createWorkspace && !workspaceMatchesRequestedIdentity(workspace, options)) {\n throw CLIError({\n code: \"WORKSPACE_CREATE_CONFLICT\",\n message: \"The existing workspace does not match the requested workspace.\",\n suggestion:\n \"Use the existing workspace, or run the explicit workspace create command to create another one.\",\n next: executableAction([\n \"workspace\",\n \"create\",\n ...workspaceCommandArgs(options),\n ...(options.workspaceCommandJson ? [\"--json\"] : []),\n \"--name\",\n options.workspaceName ?? \"<name>\",\n \"--region\",\n options.workspaceRegion ?? \"<region>\",\n ...(options.organizationId ? [\"--organization-id\", options.organizationId] : []),\n ...(options.folderId ? [\"--folder-id\", options.folderId] : []),\n ]),\n context: {\n existingWorkspace: workspaceIdentity(workspace),\n },\n });\n }\n\n if (interactive && !options.createWorkspace) {\n return chooseWorkspace(client, platformUrl, workspaces, options);\n }\n\n return useWorkspace(client, platformUrl, workspace, options);\n }\n\n if (workspaces.length > 1) {\n if (!interactive) {\n throw CLIError({\n code: \"WORKSPACE_SELECTION_REQUIRED\",\n message: \"Multiple workspaces are available.\",\n suggestion: \"Choose one explicitly for non-interactive deployment.\",\n next: executableAction(selectDeployArgs(options)),\n context: {\n workspaces: workspaces.map(workspaceIdentity),\n },\n });\n }\n\n return chooseWorkspace(client, platformUrl, workspaces, options);\n }\n\n throw new Error(\"Workspace discovery returned an invalid result\");\n}\n","import * as fs from \"node:fs\";\nimport { findUpSync } from \"find-up-simple\";\nimport * as path from \"pathe\";\nimport { hashFile } from \"#/cli/cache/hasher\";\nimport { createCacheManager } from \"#/cli/cache/manager\";\nimport { formatMigrationNumber } from \"#/cli/commands/tailordb/migrate/migration-number\";\nimport { loadApplication, type Application } from \"#/cli/services/application\";\nimport { assertUniqueTailorDBTypeNamesWithExternal } from \"#/cli/services/tailordb/type-name-validation\";\nimport { getOrNull, type OperatorClient } from \"#/cli/shared/client\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadConfigPath } from \"#/cli/shared/context\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { readPackageJson } from \"#/cli/shared/package-json\";\nimport { parseBoolean } from \"#/cli/shared/parse-boolean\";\nimport { eventSourceLabel, publishEventsConflict } from \"#/cli/shared/publish-events\";\nimport { generateUserTypes } from \"#/cli/shared/type-generator\";\nimport { withSpan } from \"#/cli/telemetry/index\";\nimport { PluginManager } from \"#/plugin/manager\";\nimport { planAIGateway } from \"./aigateway\";\nimport { planApplication } from \"./application\";\nimport { applyDeploymentPlans, type PlannedDeployment } from \"./apply-phases\";\nimport { formatAuthHookChangeEntries, planAuth } from \"./auth\";\nimport {\n formatPlanSummary,\n summarizeChangeSets,\n type HasName,\n type PlanSummary,\n} from \"./change-set\";\nimport { ensureConfigIdForDeploy, warnMissingAppId } from \"./config-id-injector\";\nimport {\n confirmImportantResourceDeletion,\n confirmMigrationCheckpointRepairs,\n confirmMissingDependentApps,\n confirmOwnerConflict,\n confirmUnmanagedResources,\n type ImportantResourceDeletion,\n type MissingDependentApp,\n type OwnerConflict,\n type UnmanagedResource,\n} from \"./confirm\";\nimport { fetchMissingDependentApps } from \"./dependency-records\";\nimport {\n buildPlannedExecutorsByName,\n collectApplicationIdpNames,\n findResolverNamespace,\n formatExecutorChangeEntries,\n planExecutor,\n} from \"./executor\";\nimport {\n collectFunctionEntries,\n filterBundledWorkflowJobs,\n planFunctionRegistry,\n resolverFunctionName,\n splitFunctionRegistryChanges,\n WORKFLOW_PREFIX,\n} from \"./function-registry\";\nimport {\n ACTION_SYMBOLS,\n buildGroupedDisplayLines,\n extractServiceActions,\n formatChangeSetEntries,\n type GroupedDisplayEntry,\n type NamespaceAction,\n} from \"./grouped-display\";\nimport { planIdP } from \"./idp\";\nimport {\n buildMetaRequest,\n dependedByAppLabelKey,\n type DependentAppsByResource,\n type DeployDependencyReason,\n eventSourceKey,\n hasMatchingSdkVersion,\n resourceTrn,\n sdkNameLabelKey,\n} from \"./label\";\nimport { formatResolverChangeEntries, planPipeline } from \"./resolver\";\nimport { planSecretManager } from \"./secret-manager\";\nimport { planStaticWebsite } from \"./staticwebsite\";\nimport { formatTailorDBResourceChangeEntries, planTailorDB } from \"./tailordb\";\nimport { validatePlan } from \"./validate-plan\";\nimport {\n formatWorkflowChangeEntries,\n planWorkflow,\n type WorkflowEventSubscribers,\n} from \"./workflow\";\nimport { planWorkflowJobFunctionExecutionPolicy } from \"./workflow-execution-policy\";\nimport { resolveDeployWorkspace } from \"./workspace\";\nimport type { Executor } from \"#/types/executor.generated\";\nimport type {\n PlanContext,\n TailorDBMigrationTestBaseline,\n TailorDBMigrationTestSnapshots,\n} from \"./types\";\n\nexport interface DeployOptions {\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n dryRun?: boolean;\n yes?: boolean;\n noSchemaCheck?: boolean;\n noValidate?: boolean;\n noCache?: boolean;\n cleanCache?: boolean;\n createWorkspace?: boolean;\n workspaceName?: string;\n workspaceRegion?: string;\n organizationId?: string;\n folderId?: string;\n // NOTE(remiposo): Provide an option to run build-only for testing purposes.\n // This could potentially be exposed as a CLI option.\n buildOnly?: boolean;\n}\n\ninterface DeployCLIContext {\n envFile?: string;\n envFileIfExists?: string;\n verbose?: boolean;\n json?: boolean;\n}\n\ninterface DeployInternalContext {\n migrationTestBaselines?: ReadonlyMap<string, TailorDBMigrationTestBaseline>;\n migrationTestSnapshots?: TailorDBMigrationTestSnapshots;\n suppressResultOutput?: boolean;\n}\n\n/**\n * Resolve which IdP an `idpUser` trigger subscribes to. A trigger that omits the\n * `idp` option means the only configured IdP; when several exist the target is\n * ambiguous and the apply pipeline throws a clearer error for it later.\n * @param application - Application declaring the executor\n * @param trigger - The executor's `idpUser` trigger\n * @returns The subscribed IdP name, or undefined when ambiguous\n */\nfunction subscribedIdpName(\n application: Readonly<Application>,\n trigger: { idp?: string | undefined },\n): string | undefined {\n if (trigger.idp != null) {\n return trigger.idp;\n }\n const idps = collectApplicationIdpNames(application);\n if (idps.size !== 1) {\n return undefined;\n }\n const [only] = idps;\n return only;\n}\n\n/** What one executor's event trigger subscribes to, and who declares it. */\ntype EventSubscription = {\n /** Target declaring the executor. */\n subscriber: BuiltDeploymentTarget;\n /** Name of the subscribing executor, for error messages. */\n executorName: string;\n /** Target declaring the subscribed resource. */\n owner: BuiltDeploymentTarget;\n /** The subscribed resource, named as error messages name it. */\n resource: string;\n /** Stable identity of the subscribed resource, keying its dependency records. */\n key: string | undefined;\n /**\n * Whether the owner declares `publishEvents` on the subscribed resource, which\n * pins the value and leaves nothing for a dependency record to protect.\n */\n pinned: boolean;\n /** The executor's trigger, narrowed to a kind that names a publishing resource. */\n trigger: PublishingTrigger;\n};\n\n/**\n * Build the error for a subscription whose resource no config in the run declares.\n *\n * The advice differs by cause: a config that declares the resource as owned\n * elsewhere is missing its peer from `--config`, while one that declares nothing\n * external is naming a resource that does not exist.\n * @param executorName - Name of the subscribing executor\n * @param lookup - How the subscribed resource is found\n * @param subscriber - Deployment target declaring the executor\n * @returns Error message\n */\nfunction missingOwnerMessage(\n executorName: string,\n lookup: EventSourceLookup,\n subscriber: BuiltDeploymentTarget,\n): string {\n const subject = `Executor \"${executorName}\" subscribes to ${lookup.resource}, which no config in this deploy declares.`;\n const external = lookup.externalHint(subscriber);\n if (external) {\n return `${subject} This config declares ${external}, so add the config that owns it to --config.`;\n }\n if (\n lookup.trigger.kind === \"workflowExecution\" ||\n lookup.trigger.kind === \"workflowJobExecution\"\n ) {\n return (\n `${subject} A workflow has no \"external\" declaration, unlike a TailorDB namespace or resolver, so ` +\n `nothing in this config points at the one that owns it. Check the name, or add the config that ` +\n `declares the workflow to --config.`\n );\n }\n return `${subject} This config declares nothing external that could hold it, so check the name.`;\n}\n\n/**\n * Resolve every event subscription in the run to the config that declares the\n * subscribed resource.\n *\n * Doing this once keeps the flags the planners resolve and the cross-config\n * dependencies recorded on the application in agreement — both are read off the\n * same list.\n * @param targets - Built deployment targets in the run\n * @returns One entry per executor whose trigger names a publishing resource\n */\nexport function collectEventSubscriptions(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n): EventSubscription[] {\n const subscriptions: EventSubscription[] = [];\n const applications = targets.map((target) => target.application);\n for (const subscriber of targets) {\n const executors = subscriber.application.executorService?.executors ?? {};\n const visibility = collectSubscriberVisibility(subscriber, applications);\n for (const executor of Object.values(executors)) {\n const lookup = eventSourceLookup(executor, subscriber, visibility);\n if (!lookup) {\n continue;\n }\n const entry = {\n subscriber,\n executorName: executor.name,\n resource: lookup.resource,\n trigger: lookup.trigger,\n };\n if (lookup.declaredBy(subscriber)) {\n subscriptions.push({\n ...entry,\n owner: subscriber,\n pinned: lookup.pinned(subscriber),\n key: lookup.keyIn(subscriber),\n });\n continue;\n }\n const peers = targets.filter(\n (target) => target.config.path !== subscriber.config.path && lookup.declaredBy(target),\n );\n const owners = lookup.narrowOwners(peers);\n // The subscriber sees the name in more than one namespace. Which one the\n // trigger means is reported when the executor's namespace is resolved.\n if (owners === \"ambiguous\") {\n continue;\n }\n const [owner] = owners;\n if (!owner) {\n throw new Error(missingOwnerMessage(executor.name, lookup, subscriber));\n }\n subscriptions.push({\n ...entry,\n owner,\n pinned: lookup.pinned(owner),\n key: lookup.keyIn(owner),\n });\n }\n }\n return subscriptions;\n}\n\n/**\n * Key the resources this run subscribes to among the target's own.\n *\n * A resource with a subscriber in the run resolves to `true` from that subscriber\n * alone, so no absent config can change it.\n * @param subscriptions - Subscriptions resolved across the run\n * @param owner - Deployment target being planned\n * @returns Resource keys the run subscribes to\n */\nfunction subscribedResourceKeys(\n subscriptions: ReadonlyArray<EventSubscription>,\n owner: BuiltDeploymentTarget,\n): ReadonlySet<string> {\n return new Set(\n ownedSubscriptions(subscriptions, owner).flatMap((subscription) => subscription.key ?? []),\n );\n}\n\n/**\n * Select the subscriptions pointing at resources the given target declares.\n * @param subscriptions - Subscriptions resolved across the run\n * @param owner - Deployment target being planned\n * @returns Subscriptions whose subscribed resource belongs to `owner`\n */\nfunction ownedSubscriptions(\n subscriptions: ReadonlyArray<EventSubscription>,\n owner: BuiltDeploymentTarget,\n): EventSubscription[] {\n return subscriptions.filter(\n (subscription) => subscription.owner.config.path === owner.config.path,\n );\n}\n\n/**\n * Collect the TailorDB types subscribed to among the given subscriptions.\n * @param subscriptions - Subscriptions owned by the target being planned\n * @returns Subscribed type names\n */\nfunction subscribedTailorDBTypes(\n subscriptions: ReadonlyArray<EventSubscription>,\n): ReadonlySet<string> {\n return new Set(\n subscriptions.flatMap((subscription) =>\n subscription.trigger.kind === \"tailordb\" ? [subscription.trigger.typeName] : [],\n ),\n );\n}\n\n/**\n * Collect the resolvers subscribed to among the given subscriptions.\n * @param subscriptions - Subscriptions owned by the target being planned\n * @returns Subscribed resolver names\n */\nfunction subscribedResolvers(subscriptions: ReadonlyArray<EventSubscription>): ReadonlySet<string> {\n return new Set(\n subscriptions.flatMap((subscription) =>\n subscription.trigger.kind === \"resolverExecuted\" ? [subscription.trigger.resolverName] : [],\n ),\n );\n}\n\n/**\n * Collect the IdPs subscribed to among the given subscriptions.\n * @param subscriptions - Subscriptions owned by the target being planned\n * @returns Subscribed IdP names\n */\nfunction subscribedIdps(subscriptions: ReadonlyArray<EventSubscription>): ReadonlySet<string> {\n return new Set(\n subscriptions.flatMap((subscription) =>\n subscription.trigger.kind === \"idpUser\"\n ? [\n subscribedIdpName(subscription.subscriber.application, subscription.trigger) ?? [],\n ].flat()\n : [],\n ),\n );\n}\n\n/**\n * Collect the workflows subscribed to, per event granularity level.\n * @param subscriptions - Subscriptions owned by the target being planned\n * @returns Subscribers keyed by event granularity level\n */\nfunction subscribedWorkflows(subscriptions: ReadonlyArray<EventSubscription>): {\n execution: WorkflowEventSubscribers;\n jobExecution: WorkflowEventSubscribers;\n} {\n const execution = { workflowNames: new Set<string>() };\n const jobExecution = { workflowNames: new Set<string>() };\n for (const { trigger } of subscriptions) {\n if (trigger.kind === \"workflowExecution\") {\n execution.workflowNames.add(trigger.workflowName);\n } else if (trigger.kind === \"workflowJobExecution\") {\n jobExecution.workflowNames.add(trigger.workflowName);\n }\n }\n return { execution, jobExecution };\n}\n\n/**\n * Collect the applications that have to take part in the same deploy for this\n * target's resources to be applied the same way.\n *\n * An executor in another config makes the resource it subscribes to publish\n * events, so deploying this config without that one would resolve the flag from\n * a smaller set of executors and turn publishing off.\n *\n * A resource that declares `publishEvents` keeps its value either way, so\n * recording a dependency for it would ask about a partial deploy that changes\n * nothing — and `prompt.confirm` rejects outright where it cannot ask, failing a\n * deploy that was never at risk.\n *\n * Records are keyed by resource rather than by application: the resource is what\n * carries them, so a record survives the owner being renamed and disappears with\n * the resource itself.\n * @param subscriptions - Subscriptions owned by the target being planned\n * @returns Dependent application ids and reasons, keyed by resource\n */\nexport function collectDependentApps(\n subscriptions: ReadonlyArray<EventSubscription>,\n): DependentAppsByResource {\n const byResource = new Map<string, Map<string, DeployDependencyReason>>();\n for (const { subscriber, owner, pinned, key } of subscriptions) {\n if (subscriber.config.path === owner.config.path || pinned || key === undefined) {\n continue;\n }\n const appId = subscriber.application.id;\n if (appId === undefined) {\n continue;\n }\n const dependents = byResource.get(key) ?? new Map<string, DeployDependencyReason>();\n dependents.set(appId, \"publish-events\");\n byResource.set(key, dependents);\n }\n return byResource;\n}\n\n/**\n * Collect explicit `publishEvents` values declared on this target's workflow jobs.\n * @param target - Deployment target being planned\n * @returns Explicit flags keyed by job name\n */\nfunction collectWorkflowJobPublishEvents(\n target: BuiltDeploymentTarget,\n): ReadonlyMap<string, boolean> {\n const jobPublishEvents = new Map<string, boolean>();\n for (const job of target.application.workflowService?.jobs ?? []) {\n if (job.publishEvents !== undefined) {\n jobPublishEvents.set(job.name, job.publishEvents);\n }\n }\n return jobPublishEvents;\n}\n\nfunction collectExpectedLocalStaticWebsiteNames(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n): ReadonlySet<string> {\n const websiteNames = new Set<string>();\n for (const target of targets) {\n for (const website of target.application.staticWebsiteServices) {\n websiteNames.add(website.name);\n }\n }\n return websiteNames;\n}\n\nfunction addPossiblyAmbiguousNamespace(\n namespaces: Map<string, string | undefined>,\n key: string,\n namespace: string,\n): void {\n if (namespaces.has(key)) {\n if (namespaces.get(key) !== namespace) {\n namespaces.set(key, undefined);\n }\n return;\n }\n namespaces.set(key, namespace);\n}\n\ntype VisibleResource = {\n visibilityKey: string;\n resourceKey: string;\n};\n\ntype CollectVisibleResourcesParams<TResult> = {\n application: Readonly<Application>;\n applications: ReadonlyArray<Readonly<Application>>;\n visibleKeysOf: (application: Readonly<Application>) => ReadonlySet<string>;\n resourcesOf: (application: Readonly<Application>) => Iterable<VisibleResource>;\n createResult: () => TResult;\n addResource: (result: TResult, resourceKey: string, visibilityKey: string) => void;\n};\n\nfunction collectVisibleResources<TResult>(params: CollectVisibleResourcesParams<TResult>): TResult {\n const { application, applications, visibleKeysOf, resourcesOf, createResult, addResource } =\n params;\n const visibleKeys = visibleKeysOf(application);\n const result = createResult();\n for (const candidate of applications) {\n for (const resource of resourcesOf(candidate)) {\n if (!visibleKeys.has(resource.visibilityKey)) {\n continue;\n }\n addResource(result, resource.resourceKey, resource.visibilityKey);\n }\n }\n return result;\n}\n\nfunction collectApplicationTailorDBNamespaces(\n application: Readonly<Application>,\n): ReadonlySet<string> {\n return new Set([\n ...application.tailorDBServices.map((service) => service.namespace),\n ...application.externalTailorDBNamespaces,\n ]);\n}\n\nfunction* tailorDBTypeResources(application: Readonly<Application>): Iterable<VisibleResource> {\n for (const service of application.tailorDBServices) {\n for (const typeName of Object.keys(service.types)) {\n yield { visibilityKey: service.namespace, resourceKey: typeName };\n }\n }\n}\n\nexport function collectVisibleTailorDBTypeNamespaces(\n application: Readonly<Application>,\n applications: ReadonlyArray<Readonly<Application>>,\n): ReadonlyMap<string, string | undefined> {\n return collectVisibleResources({\n application,\n applications,\n visibleKeysOf: collectApplicationTailorDBNamespaces,\n resourcesOf: tailorDBTypeResources,\n createResult: () => new Map<string, string | undefined>(),\n addResource: addPossiblyAmbiguousNamespace,\n });\n}\n\nfunction collectApplicationResolverNamespaces(\n application: Readonly<Application>,\n): ReadonlySet<string> {\n return new Set(\n application.subgraphs\n .filter((subgraph) => subgraph.Type === \"pipeline\")\n .map((subgraph) => subgraph.Name),\n );\n}\n\nfunction* idpNameResources(application: Readonly<Application>): Iterable<VisibleResource> {\n for (const name of collectApplicationIdpNames(application)) {\n yield { visibilityKey: name, resourceKey: name };\n }\n}\n\nexport function collectVisibleIdpNames(\n application: Readonly<Application>,\n applications: ReadonlyArray<Readonly<Application>>,\n): ReadonlySet<string> {\n return collectVisibleResources({\n application,\n applications,\n visibleKeysOf: collectApplicationIdpNames,\n resourcesOf: idpNameResources,\n createResult: () => new Set<string>(),\n addResource: (names, name) => {\n names.add(name);\n },\n });\n}\n\nfunction* resolverResources(application: Readonly<Application>): Iterable<VisibleResource> {\n for (const service of application.resolverServices) {\n for (const resolver of Object.values(service.resolvers)) {\n yield { visibilityKey: service.namespace, resourceKey: resolver.name };\n }\n }\n}\n\nexport function collectVisibleResolverNamespaces(\n application: Readonly<Application>,\n applications: ReadonlyArray<Readonly<Application>>,\n): ReadonlyMap<string, string | undefined> {\n return collectVisibleResources({\n application,\n applications,\n visibleKeysOf: collectApplicationResolverNamespaces,\n resourcesOf: resolverResources,\n createResult: () => new Map<string, string | undefined>(),\n addResource: addPossiblyAmbiguousNamespace,\n });\n}\n\n/**\n * Detect whether any resource owned by this application was last applied by a\n * different SDK version, in which case every resource is re-applied.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param application - Application being deployed\n * @param functionEntries - Function registry entries of the application\n * @returns True when an owned resource carries a different sdk-version label\n */\nexport async function shouldForceApplyAll(\n client: OperatorClient,\n workspaceId: string,\n application: Readonly<Application>,\n functionEntries: ReadonlyArray<{ name: string }>,\n) {\n const desiredLabels = (\n await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"application\", application.name),\n appName: application.name,\n appId: application.id,\n })\n ).labels;\n const candidateTrns = new Set<string>();\n\n if (application.subgraphs.length > 0) {\n candidateTrns.add(resourceTrn(workspaceId, \"application\", application.name));\n }\n application.staticWebsiteServices.forEach((website) => {\n candidateTrns.add(resourceTrn(workspaceId, \"staticwebsite\", website.name));\n });\n application.aiGatewayServices.forEach((gateway) => {\n candidateTrns.add(resourceTrn(workspaceId, \"aigateway\", gateway.name));\n });\n application.resolverServices.forEach((pipeline) => {\n candidateTrns.add(resourceTrn(workspaceId, \"pipeline\", pipeline.namespace));\n });\n application.idpServices.forEach((idp) => {\n candidateTrns.add(resourceTrn(workspaceId, \"idp\", idp.name));\n });\n if (application.authService) {\n candidateTrns.add(resourceTrn(workspaceId, \"auth\", application.authService.config.name));\n }\n Object.values(application.executorService?.executors ?? {}).forEach((executor) => {\n candidateTrns.add(resourceTrn(workspaceId, \"executor\", executor.name));\n });\n Object.values(application.workflowService?.workflows ?? {}).forEach((workflow) => {\n candidateTrns.add(resourceTrn(workspaceId, \"workflow\", workflow.name));\n });\n application.tailorDBServices.forEach((service) => {\n candidateTrns.add(resourceTrn(workspaceId, \"tailordb\", service.namespace));\n });\n application.secrets.forEach((vault) => {\n candidateTrns.add(resourceTrn(workspaceId, \"vault\", vault.vaultName));\n });\n functionEntries.forEach((entry) => {\n candidateTrns.add(resourceTrn(workspaceId, \"function_registry\", entry.name));\n });\n\n const results = await Promise.allSettled(\n [...candidateTrns].map((trn) =>\n getOrNull(async () => {\n const { metadata } = await client.getMetadata({ trn });\n return metadata;\n }),\n ),\n );\n\n const hasMismatch = results.some(\n (result) =>\n result.status === \"fulfilled\" &&\n result.value?.labels[sdkNameLabelKey] === application.name &&\n !hasMatchingSdkVersion(result.value.labels, desiredLabels),\n );\n if (hasMismatch) {\n return true;\n }\n const failure = results.find((result) => result.status === \"rejected\");\n if (failure) {\n throw failure.reason;\n }\n return false;\n}\n\n/**\n * Decide which renamed-away applications should be deleted. Excludes the\n * deploy targets themselves: id regeneration alone keeps the name unchanged,\n * so deleting by name would destroy a live app.\n * @param params - Inputs for the computation\n * @param params.conflicts - Detected owner conflicts across all services\n * @param params.resourceOwners - App names that still own resources we don't manage\n * @param params.protectedAppNames - App names that must not be deleted\n * @returns Names of empty old applications that should be deleted\n */\nexport function computeRenamedAppDeletions(params: {\n conflicts: ReadonlyArray<Pick<OwnerConflict, \"currentOwner\">>;\n resourceOwners: ReadonlySet<string>;\n protectedAppNames: ReadonlySet<string>;\n}): string[] {\n const { conflicts, resourceOwners, protectedAppNames } = params;\n const conflictOwners = new Set(conflicts.map((c) => c.currentOwner));\n return [...conflictOwners].filter(\n (owner) => !resourceOwners.has(owner) && !protectedAppNames.has(owner),\n );\n}\n\ntype PlanResults = Omit<PlannedDeployment, \"application\">;\n\ntype LoadedDeployConfig = Awaited<ReturnType<typeof loadConfig>>;\n\ntype BuildDeploymentTargetParams = {\n configPath: string | undefined;\n loadedConfig?: LoadedDeployConfig;\n dryRun: boolean;\n buildOnly: boolean;\n noCache: boolean;\n packageVersion: string;\n cacheDir: string;\n};\n\ntype BuiltDeploymentTarget = {\n config: Awaited<ReturnType<typeof loadConfig>>[\"config\"];\n application: Application;\n workflowBuildResult: Awaited<ReturnType<typeof loadApplication>>[\"workflowBuildResult\"];\n httpAdapterBuildResult: Awaited<ReturnType<typeof loadApplication>>[\"httpAdapterBuildResult\"];\n bundledScripts: Awaited<ReturnType<typeof loadApplication>>[\"bundledScripts\"];\n};\n\ntype BuildDeploymentTargetsParams = Omit<\n BuildDeploymentTargetParams,\n \"configPath\" | \"loadedConfig\"\n> & {\n configPaths: ReadonlyArray<string | undefined>;\n loadedConfigs?: ReadonlyArray<LoadedDeployConfig>;\n buildTarget?: (params: BuildDeploymentTargetParams) => Promise<BuiltDeploymentTarget>;\n};\n\ntype DeployRunPlanInputs = Pick<\n PlanContext,\n \"expectedLocalStaticWebsiteNames\" | \"externalAuthIdpConfigNames\" | \"runAppIds\"\n> & {\n /** Every event subscription in the run, resolved to its declaring config. */\n eventSubscriptions: ReadonlyArray<EventSubscription>;\n};\n\ntype PlanDeploymentTargetParams = {\n target: BuiltDeploymentTarget;\n targets: ReadonlyArray<BuiltDeploymentTarget>;\n runInputs: DeployRunPlanInputs;\n client: OperatorClient;\n workspaceId: string;\n noSchemaCheck: boolean | undefined;\n migrationTestBaselines?: ReadonlyMap<string, TailorDBMigrationTestBaseline>;\n migrationTestSnapshots?: TailorDBMigrationTestSnapshots;\n};\n\ntype ConfirmDeploymentPlansParams = {\n deployments: PlannedDeployment[];\n yes: boolean;\n dryRun?: boolean;\n /** Applications recorded as dependencies but absent from this deploy. */\n missingDependentApps?: MissingDependentApp[];\n};\n\ntype PlanDeploymentTargetsParams = {\n targets: ReadonlyArray<BuiltDeploymentTarget>;\n runInputs: DeployRunPlanInputs;\n client: OperatorClient;\n workspaceId: string;\n noSchemaCheck: boolean | undefined;\n migrationTestBaselines?: ReadonlyMap<string, TailorDBMigrationTestBaseline>;\n migrationTestSnapshots?: TailorDBMigrationTestSnapshots;\n planTarget?: (params: PlanDeploymentTargetParams) => Promise<PlannedDeployment>;\n};\n\ntype PrintPlanOptions = {\n dryRun?: boolean;\n};\n\ntype JsonPlanPayload = {\n summary: PlanSummary;\n changes: Array<Pick<GroupedDisplayEntry, \"action\" | \"name\" | \"labels\" | \"namespace\">>;\n warnings: Array<{\n type: \"unmanaged\" | \"skippedSecret\";\n resourceType: string;\n name: string;\n }>;\n conflicts: Array<{\n resourceType: string;\n name: string;\n currentOwner: string;\n }>;\n};\n\ntype PlanReport = {\n summary: PlanSummary;\n json: JsonPlanPayload;\n lines: string[];\n};\n\nfunction buildPlanReport(results: PlanResults): PlanReport {\n const executorEntries = formatExecutorChangeEntries(\n results.executor.changeSet,\n buildPlannedExecutorsByName(results.executor.changeSet),\n results.functionRegistry.executorFunctionChanges,\n );\n const resolverEntries = formatResolverChangeEntries(\n results.pipeline.changeSet.resolver,\n results.functionRegistry.resolverFunctionChanges,\n );\n const workflowEntries = formatWorkflowChangeEntries(\n results.workflow.changeSet,\n results.functionRegistry.workflowJobChanges,\n );\n const workflowExecutionPolicyEntries = formatChangeSetEntries(\n results.workflowExecutionPolicy.changeSet,\n [\"executionPolicy\"],\n );\n const authHookEntries = formatAuthHookChangeEntries(\n results.auth.changeSet.authHook,\n results.functionRegistry.authHookFunctionChanges,\n );\n const tailorDBResourceEntries = formatTailorDBResourceChangeEntries(\n results.tailorDB.changeSet.type,\n results.tailorDB.changeSet.gqlPermission,\n );\n const checkpointRepairEntries: GroupedDisplayEntry[] =\n results.tailorDB.context.checkpointRepairs.map((repair) => ({\n action: \"update\",\n symbol: ACTION_SYMBOLS.update,\n name: `migration checkpoint ${formatMigrationNumber(repair.from)} → ${formatMigrationNumber(repair.to)}`,\n labels: [\"migrationCheckpoint\"],\n namespace: repair.namespace,\n }));\n const tailorDBEntries: GroupedDisplayEntry[] = [\n ...tailorDBResourceEntries,\n ...checkpointRepairEntries,\n ];\n const pipelineEntries: GroupedDisplayEntry[] = [...resolverEntries];\n const namespaceOf = (item: HasName) => {\n if (\n \"request\" in item &&\n item.request &&\n typeof item.request === \"object\" &&\n \"namespaceName\" in item.request\n ) {\n return item.request.namespaceName as string;\n }\n if (\"namespaceName\" in item) {\n return item.namespaceName as string;\n }\n return undefined;\n };\n const authNamespaceOf = (item: HasName) =>\n \"request\" in item &&\n item.request &&\n typeof item.request === \"object\" &&\n \"authNamespace\" in item.request\n ? (item.request.authNamespace as string)\n : undefined;\n const idpEntries: GroupedDisplayEntry[] = [\n ...formatChangeSetEntries(results.idp.changeSet.client, [\"client\"], namespaceOf),\n ];\n const authEntries: GroupedDisplayEntry[] = [\n ...formatChangeSetEntries(results.auth.changeSet.idpConfig, [\"idpConfig\"], namespaceOf),\n ...formatChangeSetEntries(\n results.auth.changeSet.userProfileConfig,\n [\"userProfileConfig\"],\n namespaceOf,\n ),\n ...formatChangeSetEntries(results.auth.changeSet.tenantConfig, [\"tenantConfig\"], namespaceOf),\n ...formatChangeSetEntries(results.auth.changeSet.machineUser, [\"machineUser\"], authNamespaceOf),\n ...authHookEntries,\n ...formatChangeSetEntries(results.auth.changeSet.oauth2Client, [\"oauth2Client\"], namespaceOf),\n ...formatChangeSetEntries(results.auth.changeSet.scim, [\"scimConfig\"], namespaceOf),\n ...formatChangeSetEntries(results.auth.changeSet.scimResource, [\"scimResource\"], namespaceOf),\n ...formatChangeSetEntries(results.auth.changeSet.connection, [\"connection\"], namespaceOf),\n ];\n\n const { otherChanges: otherFunctionRegistryChanges } = splitFunctionRegistryChanges(\n results.functionRegistry.changeSet,\n );\n const tailorDBServiceActions = extractServiceActions(results.tailorDB.changeSet.service);\n const pipelineServiceActions = extractServiceActions(results.pipeline.changeSet.service);\n const idpServiceActions = extractServiceActions(results.idp.changeSet.service);\n const authServiceActions = extractServiceActions(results.auth.changeSet.service);\n\n const allDisplayEntries = [\n ...tailorDBEntries,\n ...pipelineEntries,\n ...executorEntries,\n ...workflowEntries,\n ...workflowExecutionPolicyEntries,\n ...idpEntries,\n ...authEntries,\n ];\n const allServiceActions = [\n ...tailorDBServiceActions,\n ...pipelineServiceActions,\n ...idpServiceActions,\n ...authServiceActions,\n ];\n const summary = summarizePlanResults(results, allDisplayEntries, allServiceActions);\n\n const allUnmanaged = [\n ...results.functionRegistry.unmanaged,\n ...results.tailorDB.unmanaged,\n ...results.staticWebsite.unmanaged,\n ...results.aiGateway.unmanaged,\n ...results.idp.unmanaged,\n ...results.auth.unmanaged,\n ...results.pipeline.unmanaged,\n ...results.executor.unmanaged,\n ...results.workflow.unmanaged,\n ...results.secretManager.unmanaged,\n ];\n const allConflicts = [\n ...results.functionRegistry.conflicts,\n ...results.tailorDB.conflicts,\n ...results.staticWebsite.conflicts,\n ...results.aiGateway.conflicts,\n ...results.idp.conflicts,\n ...results.auth.conflicts,\n ...results.pipeline.conflicts,\n ...results.executor.conflicts,\n ...results.workflow.conflicts,\n ...results.secretManager.conflicts,\n ];\n\n const allEntries = [\n ...allDisplayEntries,\n ...tailorDBServiceActions.map(({ action, name }) => ({\n action,\n name,\n labels: [\"tailorDB\"],\n namespace: undefined,\n })),\n ...pipelineServiceActions.map(({ action, name }) => ({\n action,\n name,\n labels: [\"pipeline\"],\n namespace: undefined,\n })),\n ...idpServiceActions.map(({ action, name }) => ({\n action,\n name,\n labels: [\"idp\"],\n namespace: undefined,\n })),\n ...authServiceActions.map(({ action, name }) => ({\n action,\n name,\n labels: [\"auth\"],\n namespace: undefined,\n })),\n ...formatChangeSetEntries(otherFunctionRegistryChanges),\n ...formatChangeSetEntries(results.staticWebsite.changeSet, [\"staticWebsite\"]),\n ...formatChangeSetEntries(results.staticWebsite.customDomainChangeSet, [\"customDomain\"]),\n ...formatChangeSetEntries(results.aiGateway.changeSet, [\"aiGateway\"]),\n ...formatChangeSetEntries(results.app, [\"application\"]),\n ...formatChangeSetEntries(results.secretManager.vaultChangeSet, [\"vault\"]),\n ...formatChangeSetEntries(results.secretManager.secretChangeSet, [\"secret\"]),\n ];\n const changes = allEntries.map(({ action, name, labels, namespace }) => ({\n action,\n name,\n labels,\n namespace,\n }));\n const warnings = [\n ...allUnmanaged.map(({ resourceType, resourceName }) => ({\n type: \"unmanaged\" as const,\n resourceType,\n name: resourceName,\n })),\n ...results.secretManager.skippedSecrets.map((name) => ({\n type: \"skippedSecret\" as const,\n resourceType: \"secret\",\n name,\n })),\n ];\n const conflicts = allConflicts.map(({ resourceType, resourceName, currentOwner }) => ({\n resourceType,\n name: resourceName,\n currentOwner,\n }));\n\n const allLines: string[] = [\n ...buildGroupedDisplayLines(\n results.functionRegistry.changeSet.title,\n formatChangeSetEntries(otherFunctionRegistryChanges),\n ),\n ...results.staticWebsite.changeSet.lines(),\n ...results.staticWebsite.customDomainChangeSet.lines(),\n ...results.aiGateway.changeSet.lines(),\n ...results.app.lines(),\n ...buildGroupedDisplayLines(\"TailorDB\", tailorDBEntries, tailorDBServiceActions),\n ...buildGroupedDisplayLines(\"Resolver\", pipelineEntries, pipelineServiceActions),\n ...buildGroupedDisplayLines(\"Executor\", executorEntries),\n ...buildGroupedDisplayLines(\"Workflow\", workflowEntries),\n ...buildGroupedDisplayLines(\"IdP\", idpEntries, idpServiceActions),\n ...buildGroupedDisplayLines(\"Auth\", authEntries, authServiceActions),\n ...results.secretManager.vaultChangeSet.lines(),\n ...results.secretManager.secretChangeSet.lines(),\n ];\n\n if (allUnmanaged.length > 0) {\n allLines.push(styles.bold(\"Unmanaged resources (not in config):\"));\n for (const { resourceType, resourceName } of allUnmanaged) {\n allLines.push(` ${styles.warning(\"⚠\")} ${styles.bold(resourceType)} \"${resourceName}\"`);\n }\n }\n\n if (results.secretManager.skippedSecrets.length > 0) {\n allLines.push(styles.bold(\"Secret Manager secrets (skipped - no value provided):\"));\n for (const name of results.secretManager.skippedSecrets) {\n allLines.push(` ${styles.dim(\"○\")} ${name}`);\n }\n }\n\n if (allConflicts.length > 0) {\n allLines.push(styles.bold(\"Owner conflicts (will require confirmation on apply):\"));\n for (const { resourceType, resourceName, currentOwner } of allConflicts) {\n allLines.push(\n ` ${styles.warning(\"!\")} ${styles.bold(resourceType)} \"${resourceName}\" — owned by \"${currentOwner}\"`,\n );\n }\n }\n\n allLines.push(formatPlanSummary(summary));\n\n return {\n summary,\n json: { summary, changes, warnings, conflicts },\n lines: allLines,\n };\n}\n\n/**\n * Format and output the plan results, then return a summary of change counts.\n * In JSON dry-run mode a JSON payload is written to stdout. In all other modes\n * the human-readable diff goes to stdout (dry-run) or stderr (apply).\n * @param results - Planned results across all services\n * @param opts - Output options (dry-run mode flag)\n * @returns Aggregated plan summary counts\n */\nexport function printPlanResults(results: PlanResults, opts?: PrintPlanOptions): PlanSummary {\n const report = buildPlanReport(results);\n\n if (logger.jsonMode && opts?.dryRun) {\n logger.out(report.json);\n return report.summary;\n }\n\n const output = report.lines.join(\"\\n\");\n if (opts?.dryRun) {\n logger.out(output);\n } else {\n logger.log(output);\n }\n\n return report.summary;\n}\n\n/**\n * Summarize plan counts from display entries, service actions, and non-grouped changesets.\n * @param results - Planned apply results\n * @param displayEntries - All grouped display entries across sections\n * @param serviceActions - All service-level namespace actions\n * @returns Aggregated plan summary\n */\nexport function summarizePlanResults(\n results: PlanResults,\n displayEntries: ReadonlyArray<GroupedDisplayEntry>,\n serviceActions: ReadonlyArray<NamespaceAction>,\n): PlanSummary {\n const summary: PlanSummary = { create: 0, update: 0, delete: 0, replace: 0 };\n\n // Count grouped display entries\n for (const entry of displayEntries) {\n summary[entry.action] += 1;\n }\n\n // Count service-level actions (shown as namespace headers)\n for (const sa of serviceActions) {\n summary[sa.action] += 1;\n }\n\n // Count non-grouped changesets (staticWebsite, app, secretManager, functionRegistry other)\n const { otherChanges } = splitFunctionRegistryChanges(results.functionRegistry.changeSet);\n const nonGrouped = summarizeChangeSets([\n otherChanges,\n results.staticWebsite.changeSet,\n results.staticWebsite.customDomainChangeSet,\n results.aiGateway.changeSet,\n results.app,\n results.secretManager.vaultChangeSet,\n results.secretManager.secretChangeSet,\n ]);\n summary.create += nonGrouped.create;\n summary.update += nonGrouped.update;\n summary.delete += nonGrouped.delete;\n summary.replace += nonGrouped.replace;\n\n return summary;\n}\n\n/**\n * Parse the deploy config option into one or more config paths.\n * @param configPath - Raw `--config` option value\n * @returns Config paths, or one undefined entry to preserve default config lookup\n */\nexport function parseDeployConfigPaths(configPath?: string): Array<string | undefined> {\n const rawConfigPath = configPath ?? process.env.TAILOR_PLATFORM_SDK_CONFIG_PATH;\n if (rawConfigPath === undefined) {\n return [undefined];\n }\n\n const configPaths = rawConfigPath.split(\",\").map((entry) => entry.trim());\n if (configPaths.some((entry) => entry.length === 0)) {\n throw new Error(\"--config must contain one or more non-empty config paths.\");\n }\n return configPaths;\n}\n\nfunction recoveryEnvironmentArgs(\n options: DeployOptions | undefined,\n cliContext?: DeployCLIContext,\n): readonly string[] {\n return [\n ...(cliContext?.envFile ? [\"--env-file\", path.resolve(process.cwd(), cliContext.envFile)] : []),\n ...(cliContext?.envFileIfExists\n ? [\"--env-file-if-exists\", path.resolve(process.cwd(), cliContext.envFileIfExists)]\n : []),\n ...(options?.profile ? [\"--profile\", options.profile] : []),\n ];\n}\n\nfunction recoveryOutputArgs(cliContext?: DeployCLIContext): readonly string[] {\n return [\n ...(cliContext?.verbose ? [\"--verbose\"] : []),\n ...(cliContext?.json || logger.jsonMode ? [\"--json\"] : []),\n ];\n}\n\nfunction retryDeployArgs(\n options: DeployOptions | undefined,\n configPaths: readonly string[],\n cliContext?: DeployCLIContext,\n): readonly string[] {\n return [\n \"deploy\",\n \"--config\",\n configPaths.join(\",\"),\n ...recoveryEnvironmentArgs(options, cliContext),\n ...(options?.dryRun ? [\"--dry-run\"] : []),\n ...(options?.yes ? [\"--yes\"] : []),\n ...(options?.noSchemaCheck ? [\"--no-schema-check\"] : []),\n ...(options?.noValidate ? [\"--no-validate\"] : []),\n ...(options?.noCache ? [\"--no-cache\"] : []),\n ...(options?.cleanCache ? [\"--clean-cache\"] : []),\n ...recoveryOutputArgs(cliContext),\n ];\n}\n\nfunction workspaceRecoveryArgs(\n options: DeployOptions | undefined,\n cliContext?: DeployCLIContext,\n): readonly string[] {\n return [\n ...recoveryEnvironmentArgs(options, cliContext),\n ...(cliContext?.verbose ? [\"--verbose\"] : []),\n ];\n}\n\nasync function buildDeploymentTarget(\n params: BuildDeploymentTargetParams,\n): Promise<BuiltDeploymentTarget> {\n const { configPath, loadedConfig, dryRun, buildOnly, noCache, packageVersion, cacheDir } = params;\n const { config, plugins } =\n loadedConfig ?? (await loadDeployConfig({ configPath, dryRun, buildOnly }));\n\n const configDir = path.dirname(config.path);\n const lockfilePath =\n findUpSync(\"pnpm-lock.yaml\", { cwd: configDir }) ??\n findUpSync(\"package-lock.json\", { cwd: configDir }) ??\n findUpSync(\"yarn.lock\", { cwd: configDir }) ??\n findUpSync(\"bun.lock\", { cwd: configDir });\n const cacheManager = createCacheManager({\n enabled: !noCache,\n cacheDir,\n sdkVersion: packageVersion,\n lockfileHash: lockfilePath ? hashFile(lockfilePath) : undefined,\n });\n\n let pluginManager: PluginManager | undefined;\n if (plugins.length > 0) {\n pluginManager = new PluginManager(plugins);\n }\n\n await withSpan(\"build.generateUserTypes\", () =>\n generateUserTypes({ config, configPath: config.path }),\n );\n\n let application: Application;\n let workflowBuildResult: Awaited<ReturnType<typeof loadApplication>>[\"workflowBuildResult\"];\n let httpAdapterBuildResult: Awaited<ReturnType<typeof loadApplication>>[\"httpAdapterBuildResult\"];\n let bundledScripts: Awaited<ReturnType<typeof loadApplication>>[\"bundledScripts\"];\n try {\n const result = await withSpan(\"build.loadApplication\", () =>\n loadApplication({\n config,\n pluginManager,\n bundleCache: cacheManager.bundleCache,\n }),\n );\n application = result.application;\n workflowBuildResult = result.workflowBuildResult;\n httpAdapterBuildResult = result.httpAdapterBuildResult;\n bundledScripts = result.bundledScripts;\n } finally {\n cacheManager.finalize();\n }\n\n return {\n config,\n application,\n workflowBuildResult,\n httpAdapterBuildResult,\n bundledScripts,\n };\n}\n\nasync function loadDeployConfig(params: {\n configPath: string | undefined;\n dryRun: boolean;\n buildOnly: boolean;\n}): Promise<LoadedDeployConfig> {\n const { configPath, dryRun, buildOnly } = params;\n return withSpan(\"build.loadConfig\", async () => {\n const foundPath = loadConfigPath(configPath);\n if (foundPath) {\n const resolvedPath = path.resolve(process.cwd(), foundPath);\n if (fs.existsSync(resolvedPath)) {\n await ensureConfigIdForDeploy({ configPath: resolvedPath, dryRun, buildOnly });\n }\n }\n const loaded = await loadConfig(configPath);\n // build-only never reaches the platform, so ownership does not apply.\n if (!buildOnly) warnMissingAppId(loaded.config.id);\n return loaded;\n });\n}\n\nexport async function buildDeploymentTargets(\n params: BuildDeploymentTargetsParams,\n): Promise<BuiltDeploymentTarget[]> {\n const {\n configPaths,\n loadedConfigs,\n buildTarget = buildDeploymentTarget,\n ...targetParams\n } = params;\n\n return Promise.all(\n configPaths.map((configPath, index) =>\n buildTarget({\n ...targetParams,\n configPath,\n loadedConfig: loadedConfigs?.[index],\n }),\n ),\n );\n}\n\nfunction setBundledScript(\n target: Map<string, string>,\n name: string,\n code: string,\n kind: string,\n): void {\n if (target.has(name)) {\n throw new Error(`Duplicate ${kind} bundle name \"${name}\" across config files.`);\n }\n target.set(name, code);\n}\n\nfunction addBundledScripts(\n target: Map<string, string>,\n source: ReadonlyMap<string, string>,\n kind: string,\n): void {\n for (const [name, code] of source) {\n setBundledScript(target, name, code, kind);\n }\n}\n\nfunction collectDuplicateBundleNames(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n select: (target: BuiltDeploymentTarget) => ReadonlyMap<string, string>,\n): ReadonlySet<string> {\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const target of targets) {\n for (const name of select(target).keys()) {\n if (seen.has(name)) {\n duplicates.add(name);\n }\n seen.add(name);\n }\n }\n return duplicates;\n}\n\nfunction addResolverBundledScripts(\n target: Map<string, string>,\n source: BuiltDeploymentTarget,\n duplicateNames: ReadonlySet<string>,\n): void {\n const consumedNames = new Set<string>();\n for (const service of source.application.resolverServices) {\n for (const resolver of Object.values(service.resolvers)) {\n const code = source.bundledScripts.resolvers.get(resolver.name);\n if (code === undefined) {\n continue;\n }\n const name = duplicateNames.has(resolver.name)\n ? resolverFunctionName(service.namespace, resolver.name)\n : resolver.name;\n setBundledScript(target, name, code, \"resolver\");\n consumedNames.add(resolver.name);\n }\n }\n for (const [name, code] of source.bundledScripts.resolvers) {\n if (!consumedNames.has(name)) {\n setBundledScript(target, name, code, \"resolver\");\n }\n }\n}\n\n/**\n * Merge per-config bundled scripts into one build-only result.\n * @param targets - Built deployment targets to merge\n * @returns Combined bundled scripts across all targets\n */\nexport function mergeBundledScripts(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n): BuiltDeploymentTarget[\"bundledScripts\"] {\n const bundledScripts: BuiltDeploymentTarget[\"bundledScripts\"] = {\n resolvers: new Map(),\n executors: new Map(),\n workflowJobs: new Map(),\n authHooks: new Map(),\n };\n const duplicateResolverNames = collectDuplicateBundleNames(\n targets,\n (target) => target.bundledScripts.resolvers,\n );\n\n for (const target of targets) {\n addResolverBundledScripts(bundledScripts.resolvers, target, duplicateResolverNames);\n addBundledScripts(bundledScripts.executors, target.bundledScripts.executors, \"executor\");\n addBundledScripts(\n bundledScripts.workflowJobs,\n target.bundledScripts.workflowJobs,\n \"workflow job\",\n );\n addBundledScripts(bundledScripts.authHooks, target.bundledScripts.authHooks, \"auth hook\");\n }\n\n return bundledScripts;\n}\n\n/**\n * Reject resource names that collide across configs. Each checked resource\n * type is workspace-global (its TRN is not qualified by namespace or app), so\n * a duplicate name would make two configs target the same platform resource:\n * one config's apply could overwrite the other's, or a fresh create could be\n * attempted twice. Resolver and auth-hook function names are namespace- or\n * app-qualified and are intentionally excluded.\n * @param targets - Built deployment targets to check\n */\nexport function assertUniqueGlobalResourceNames(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n): void {\n for (const check of DEPLOY_MANAGED_RESOURCE_DEFINITIONS) {\n const seen = new Set<string>();\n for (const target of targets) {\n for (const name of check.namesOf(target)) {\n if (seen.has(name)) {\n throw new Error(\n `Duplicate ${check.resourceLabel} name \"${name}\" across config files. ${check.resourceLabel} names must be unique across all configs in a single deploy.`,\n );\n }\n seen.add(name);\n }\n }\n }\n}\n\n/** Executor trigger kinds that name a resource which publishes events. */\ntype PublishingTrigger = Extract<\n Executor[\"trigger\"],\n {\n kind:\n | \"tailordb\"\n | \"resolverExecuted\"\n | \"idpUser\"\n | \"workflowExecution\"\n | \"workflowJobExecution\";\n }\n>;\n\n/**\n * What one subscribing config can see, in the same terms the executor's own\n * namespace resolution uses. A namespace maps to `undefined` when the subscriber\n * sees the name in more than one place.\n */\ntype SubscriberVisibility = {\n tailorDBTypes: ReadonlyMap<string, string | undefined>;\n resolvers: ReadonlyMap<string, string | undefined>;\n idps: ReadonlySet<string>;\n};\n\nfunction collectSubscriberVisibility(\n subscriber: BuiltDeploymentTarget,\n applications: ReadonlyArray<Readonly<Application>>,\n): SubscriberVisibility {\n return {\n tailorDBTypes: collectVisibleTailorDBTypeNamespaces(subscriber.application, applications),\n resolvers: collectVisibleResolverNamespaces(subscriber.application, applications),\n idps: collectVisibleIdpNames(subscriber.application, applications),\n };\n}\n\n/** Candidate owners the subscriber's view leaves, or that it cannot tell apart. */\ntype OwnerCandidates = BuiltDeploymentTarget[] | \"ambiguous\";\n\n/** How to find one event-publishing resource in a deployment target. */\ntype EventSourceLookup = {\n /** Resource named in error messages, e.g. `TailorDB type \"Order\"`. */\n resource: string;\n /** The trigger, narrowed to a kind that names a publishing resource. */\n trigger: PublishingTrigger;\n /** Whether `target` declares the resource. */\n declaredBy: (target: BuiltDeploymentTarget) => boolean | undefined;\n /**\n * Whether `target` declares `publishEvents` on the resource, so the value does\n * not depend on which configs the run covers.\n */\n pinned: (target: BuiltDeploymentTarget) => boolean;\n /**\n * Stable identity of the subscribed resource inside its owner, used to key the\n * dependency records. Undefined when the owner does not declare it after all.\n */\n keyIn: (owner: BuiltDeploymentTarget) => string | undefined;\n /**\n * Narrow peer configs to the ones the subscriber's own view resolves to.\n *\n * Matching on the name alone would count a same-named resource in a namespace\n * the subscriber cannot see, and drop the subscription as ambiguous even though\n * the executor resolves it to exactly one owner.\n */\n narrowOwners: (candidates: ReadonlyArray<BuiltDeploymentTarget>) => OwnerCandidates;\n /**\n * What `target` declares as owned elsewhere that could hold this resource,\n * described for an error message. Undefined for a resource kind that cannot be\n * referenced from another config at all.\n */\n externalHint: (target: BuiltDeploymentTarget) => string | undefined;\n};\n\n/**\n * TailorDB namespaces the config declares as owned elsewhere.\n * @param target - Deployment target declaring the executor\n * @returns Namespace names declared with `external: true`\n */\nfunction externalTailorDBNamespaces(target: BuiltDeploymentTarget): ReadonlyArray<string> {\n return target.application.externalTailorDBNamespaces;\n}\n\nfunction externalSubgraphNames(\n target: BuiltDeploymentTarget,\n subgraphType: string,\n localNames: ReadonlySet<string>,\n): string[] {\n return target.application.subgraphs\n .filter((subgraph) => subgraph.Type === subgraphType && !localNames.has(subgraph.Name))\n .map((subgraph) => subgraph.Name);\n}\n\nfunction externalResolverNamespaces(target: BuiltDeploymentTarget): string[] {\n const local = new Set(target.application.resolverServices.map((service) => service.namespace));\n return externalSubgraphNames(target, \"pipeline\", local);\n}\n\nfunction externalIdpNames(target: BuiltDeploymentTarget): string[] {\n const local = new Set(target.application.idpServices.map((idp) => idp.name));\n return externalSubgraphNames(target, \"idp\", local);\n}\n\n/**\n * Describe the external declarations that could hold a missing resource.\n * @param kind - Resource kind named in the message, e.g. `TailorDB namespace`\n * @param names - External names the subscribing config declares\n * @returns A phrase for the error message, or undefined when it declares none\n */\nfunction describeExternal(kind: string, names: ReadonlyArray<string>): string | undefined {\n if (names.length === 0) {\n return undefined;\n }\n const plural = names.length === 1 ? kind : `${kind}s`;\n return `external ${plural} ${names.map((name) => `\"${name}\"`).join(\", \")}`;\n}\n\nfunction declaresTailorDBType(\n target: BuiltDeploymentTarget,\n typeName: string,\n): boolean | undefined {\n return (\n target.application.tailorDBServices.some((service) => service.types[typeName]) || undefined\n );\n}\n\nfunction declaresResolver(\n target: BuiltDeploymentTarget,\n resolverName: string,\n): boolean | undefined {\n return (\n target.application.resolverServices.some((service) =>\n Object.values(service.resolvers).some((resolver) => resolver.name === resolverName),\n ) || undefined\n );\n}\n\nfunction declaresIdp(target: BuiltDeploymentTarget, idpName: string): boolean | undefined {\n return target.application.idpServices.some((entry) => entry.name === idpName) || undefined;\n}\n\nfunction declaresWorkflow(\n target: BuiltDeploymentTarget,\n workflowName: string,\n): boolean | undefined {\n const workflows = Object.values(target.application.workflowService?.workflows ?? {});\n return workflows.some((entry) => entry.name === workflowName) || undefined;\n}\n\n// A resource that declares publishEvents keeps that value whatever the run covers,\n// so nothing about it needs recording. An explicit `false` with a subscriber is\n// rejected by assertNoPublishEventsConflict, which explains that case on its own.\nfunction pinsTailorDBType(target: BuiltDeploymentTarget, typeName: string): boolean {\n for (const service of target.application.tailorDBServices) {\n const type = service.types[typeName];\n if (type) return type.settings.publishEvents !== undefined;\n }\n return false;\n}\n\n// Resolver names are only namespace-unique, so the namespace the subscriber sees\n// the name through is what decides which resolver's declared value applies.\n// Searching every namespace would let one namespace's declaration pin another's.\nfunction pinsResolverIn(\n target: BuiltDeploymentTarget,\n namespace: string,\n resolverName: string,\n): boolean {\n return target.application.resolverServices.some(\n (service) =>\n service.namespace === namespace &&\n Object.values(service.resolvers).some(\n (resolver) => resolver.name === resolverName && resolver.publishEvents !== undefined,\n ),\n );\n}\n\nfunction pinsIdp(target: BuiltDeploymentTarget, idpName: string): boolean {\n return target.application.idpServices.some(\n (entry) => entry.name === idpName && entry.publishEvents !== undefined,\n );\n}\n\nfunction pinsWorkflow(target: BuiltDeploymentTarget, workflowName: string): boolean {\n return Object.values(target.application.workflowService?.workflows ?? {}).some(\n (entry) => entry.name === workflowName && entry.publishEvents !== undefined,\n );\n}\n\n// A workflowJobExecution trigger enables publishing on the jobs the subscribed\n// workflow runs, so only those decide whether the value is declared. Reading the\n// whole config's jobs instead would call the value unset because some other\n// workflow leaves one unset, and `planWorkflow` writes the records per workflow.\nfunction pinsEveryJobOfWorkflow(target: BuiltDeploymentTarget, workflowName: string): boolean {\n const workflow = Object.values(target.application.workflowService?.workflows ?? {}).find(\n (entry) => entry.name === workflowName,\n );\n if (workflow === undefined) return false;\n const jobNames = target.workflowBuildResult?.mainJobDeps[workflow.mainJob.name] ?? [];\n const declared = collectWorkflowJobPublishEvents(target);\n return jobNames.length > 0 && jobNames.every((jobName) => declared.has(jobName));\n}\n\nfunction tailorDBTypeNamespaceIn(\n target: BuiltDeploymentTarget,\n typeName: string,\n): string | undefined {\n return target.application.tailorDBServices.find((service) => service.types[typeName])?.namespace;\n}\n\n// A namespaced resource is owned by whichever config declares it in the one\n// namespace the subscriber sees it through. An absent key means the subscriber\n// cannot see the name at all, which the missing-owner error explains.\nfunction narrowByVisibleNamespace(params: {\n candidates: ReadonlyArray<BuiltDeploymentTarget>;\n visible: ReadonlyMap<string, string | undefined>;\n resourceKey: string;\n declaresIn: (target: BuiltDeploymentTarget, namespace: string) => boolean;\n}): OwnerCandidates {\n const { candidates, visible, resourceKey, declaresIn } = params;\n if (!visible.has(resourceKey)) return [];\n const namespace = visible.get(resourceKey);\n if (namespace === undefined) return \"ambiguous\";\n return candidates.filter((target) => declaresIn(target, namespace));\n}\n\nfunction declaresTailorDBTypeIn(\n target: BuiltDeploymentTarget,\n namespace: string,\n typeName: string,\n): boolean {\n return target.application.tailorDBServices.some(\n (service) => service.namespace === namespace && Boolean(service.types[typeName]),\n );\n}\n\nfunction declaresResolverIn(\n target: BuiltDeploymentTarget,\n namespace: string,\n resolverName: string,\n): boolean {\n return target.application.resolverServices.some(\n (service) =>\n service.namespace === namespace &&\n Object.values(service.resolvers).some((resolver) => resolver.name === resolverName),\n );\n}\n\n/**\n * Resolve how to find the resource an executor's event trigger subscribes to.\n * @param executor - Executor declared by the subscribing config\n * @param subscriber - Deployment target declaring the executor\n * @param visibility - What the subscribing config can see, by resource kind\n * @returns The lookup, or undefined for triggers with no publishing resource\n */\nfunction eventSourceLookup(\n executor: Executor,\n subscriber: BuiltDeploymentTarget,\n visibility: SubscriberVisibility,\n): EventSourceLookup | undefined {\n const { trigger } = executor;\n switch (trigger.kind) {\n case \"tailordb\":\n return {\n resource: publishEventsConflict.tailorDBType(trigger.typeName).resource,\n trigger,\n declaredBy: (target) => declaresTailorDBType(target, trigger.typeName),\n pinned: (target) => pinsTailorDBType(target, trigger.typeName),\n keyIn: (owner) => {\n const namespace = tailorDBTypeNamespaceIn(owner, trigger.typeName);\n return namespace && eventSourceKey.tailorDBType(namespace, trigger.typeName);\n },\n narrowOwners: (candidates) =>\n narrowByVisibleNamespace({\n candidates,\n visible: visibility.tailorDBTypes,\n resourceKey: trigger.typeName,\n declaresIn: (target, namespace) =>\n declaresTailorDBTypeIn(target, namespace, trigger.typeName),\n }),\n externalHint: (target) =>\n describeExternal(\"TailorDB namespace\", externalTailorDBNamespaces(target)),\n };\n case \"resolverExecuted\": {\n // The namespace the subscriber resolves the name through, in the same order\n // the trigger itself resolves it: a locally declared resolver wins, and only\n // then the namespaces the config sees. Reading it back off the owner by bare\n // name would pick whichever namespace comes first instead, and reading only\n // the visible map would call a local name ambiguous because an external\n // namespace happens to hold it too.\n const namespace =\n findResolverNamespace(subscriber.application, trigger.resolverName) ??\n visibility.resolvers.get(trigger.resolverName);\n return {\n resource: publishEventsConflict.resolver(trigger.resolverName).resource,\n trigger,\n declaredBy: (target) => declaresResolver(target, trigger.resolverName),\n pinned: (target) =>\n namespace !== undefined && pinsResolverIn(target, namespace, trigger.resolverName),\n keyIn: () => namespace && eventSourceKey.resolver(namespace, trigger.resolverName),\n narrowOwners: (candidates) =>\n narrowByVisibleNamespace({\n candidates,\n visible: visibility.resolvers,\n resourceKey: trigger.resolverName,\n declaresIn: (target, namespace) =>\n declaresResolverIn(target, namespace, trigger.resolverName),\n }),\n externalHint: (target) =>\n describeExternal(\"resolver namespace\", externalResolverNamespaces(target)),\n };\n }\n case \"idpUser\": {\n const idpName = subscribedIdpName(subscriber.application, trigger);\n if (idpName === undefined) {\n return undefined;\n }\n return {\n resource: publishEventsConflict.idpService(idpName).resource,\n trigger,\n declaredBy: (target) => declaresIdp(target, idpName),\n pinned: (target) => pinsIdp(target, idpName),\n keyIn: () => eventSourceKey.idp(idpName),\n // IdP namespace names are unique across a run, so there is nothing to\n // tell apart once the subscriber can see the name.\n narrowOwners: (candidates) =>\n visibility.idps.has(idpName)\n ? candidates.filter((target) => declaresIdp(target, idpName))\n : [],\n // The trigger names the IdP, so the hint can be exact rather than a list.\n externalHint: (target) =>\n describeExternal(\n \"IdP\",\n externalIdpNames(target).filter((name) => name === idpName),\n ),\n };\n }\n case \"workflowExecution\":\n case \"workflowJobExecution\":\n return {\n // A job trigger subscribes to the jobs' events, not the workflow's own, so\n // naming the workflow would read as if its publishEvents were at stake.\n resource:\n trigger.kind === \"workflowExecution\"\n ? eventSourceLabel.workflow(trigger.workflowName)\n : eventSourceLabel.workflowJobs(trigger.workflowName),\n trigger,\n declaredBy: (target) => declaresWorkflow(target, trigger.workflowName),\n pinned: (target) =>\n trigger.kind === \"workflowExecution\"\n ? pinsWorkflow(target, trigger.workflowName)\n : pinsEveryJobOfWorkflow(target, trigger.workflowName),\n keyIn: () =>\n trigger.kind === \"workflowExecution\"\n ? eventSourceKey.workflow(trigger.workflowName)\n : eventSourceKey.workflowJobs(trigger.workflowName),\n narrowOwners: (candidates) =>\n candidates.filter((target) => declaresWorkflow(target, trigger.workflowName)),\n // A workflow has no `external` declaration to check.\n externalHint: () => undefined,\n };\n default:\n return undefined;\n }\n}\n\nfunction collectPlannedExternalTailorDBServices(\n target: BuiltDeploymentTarget,\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n): Application[\"tailorDBServices\"] {\n const externalNamespaces = new Set(target.application.externalTailorDBNamespaces);\n if (externalNamespaces.size === 0) {\n return [];\n }\n\n return targets.flatMap((candidate) =>\n candidate.application.tailorDBServices.filter((service) =>\n externalNamespaces.has(service.namespace),\n ),\n );\n}\n\nexport function collectExternalAuthIdpConfigNames(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n): ReadonlyMap<string, string | undefined> {\n const idpConfigNames = new Map<string, string | undefined>();\n for (const target of targets) {\n const authService = target.application.authService;\n if (!authService) {\n continue;\n }\n const { name } = authService.config;\n const idpConfigName = authService.config.idProvider?.name;\n if (idpConfigNames.has(name) && idpConfigNames.get(name) !== idpConfigName) {\n throw new Error(\n `Auth namespace \"${name}\" is defined by multiple config files with different IdP configs. ` +\n `Auth namespace names must be unique across all configs in a single deploy.`,\n );\n }\n idpConfigNames.set(name, idpConfigName);\n }\n return idpConfigNames;\n}\n\n/**\n * Reject a cross-config subscription whose dependency cannot be recorded.\n *\n * Records live on the subscribed resource, so there is always somewhere to put\n * one. What can be missing is the dependent's name: the record identifies it by\n * application id, and a subscriber that resolves without one cannot be recorded,\n * leaving the next deploy of the owner alone to turn publishing off unannounced.\n *\n * The check applies only to a run that writes: `--dry-run` leaves every id\n * uninjected, so demanding one there would reject configs a real deploy gives one.\n * @param subscriptions - Every event subscription resolved for the run\n * @param writes - Whether this run applies changes rather than only reporting them\n */\nexport function assertRecordableDependencies(\n subscriptions: ReadonlyArray<EventSubscription>,\n writes: boolean,\n): void {\n for (const { subscriber, owner, executorName, resource, pinned } of subscriptions) {\n if (subscriber.config.path === owner.config.path) continue;\n if (pinned) continue;\n if (!writes) continue;\n const appId = subscriber.application.id;\n // An id that cannot form a label key fails the same way as a missing one, and\n // it has to fail here: the write happens partway through apply, once sibling\n // resources have already been mutated.\n if (appId !== undefined && dependedByAppLabelKey(appId) !== undefined) continue;\n const cause =\n appId === undefined\n ? `${subscriber.config.path} resolves without an \"id\" — a config that re-exports ` +\n `defineConfig() from another file never gets one`\n : `${subscriber.config.path} resolves to the id \"${appId}\", which is not the lowercase ` +\n `UUID deploy writes`;\n const fix =\n appId === undefined\n ? `Call defineConfig() inline in ${subscriber.config.path} so deploy can manage its \"id\".`\n : `Restore the generated value in ${subscriber.config.path}'s \"id\".`;\n throw new Error(\n `Executor \"${executorName}\" in ${subscriber.config.path} subscribes to ${resource} in ` +\n `${owner.config.path}, which would enable event publishing on it for this deploy only. ` +\n `${cause} — so deploy cannot record which config the dependency belongs to, and ` +\n `deploying ${owner.config.path} alone later would turn publishing back off without ` +\n `asking.\\n\\n${fix}`,\n );\n }\n}\n\nfunction collectDeployRunPlanInputs(\n targets: ReadonlyArray<BuiltDeploymentTarget>,\n writes: boolean,\n): DeployRunPlanInputs {\n const eventSubscriptions = collectEventSubscriptions(targets);\n assertRecordableDependencies(eventSubscriptions, writes);\n return {\n eventSubscriptions,\n runAppIds: new Set(\n targets.map((target) => target.application.id).filter((id) => id !== undefined),\n ),\n expectedLocalStaticWebsiteNames: collectExpectedLocalStaticWebsiteNames(targets),\n externalAuthIdpConfigNames: collectExternalAuthIdpConfigNames(targets),\n };\n}\n\nasync function planDeploymentTarget(\n params: PlanDeploymentTargetParams,\n): Promise<PlannedDeployment> {\n const {\n target,\n targets,\n runInputs,\n client,\n workspaceId,\n noSchemaCheck,\n migrationTestBaselines,\n migrationTestSnapshots,\n } = params;\n const { config, application, workflowBuildResult, httpAdapterBuildResult, bundledScripts } =\n target;\n const owned = ownedSubscriptions(runInputs.eventSubscriptions, target);\n\n const migrationTestServices = application.tailorDBServices.map((service) => {\n const snapshot = migrationTestSnapshots?.get(service.namespace);\n return snapshot ? { ...service, types: snapshot.types, typeSourceInfo: {} } : service;\n });\n await withSpan(\"plan.validateTailorDBTypeNames\", () =>\n assertUniqueTailorDBTypeNamesWithExternal({\n client,\n workspaceId,\n tailorDBServices: migrationTestServices,\n externalTailorDBNamespaces: application.externalTailorDBNamespaces,\n plannedExternalTailorDBServices: collectPlannedExternalTailorDBServices(target, targets),\n }),\n );\n\n const workflowService = application.workflowService;\n const bundledWorkflowJobs = filterBundledWorkflowJobs(\n workflowService?.jobs ?? [],\n workflowBuildResult?.usedJobNames ?? [],\n );\n const functionEntries = collectFunctionEntries(application, bundledWorkflowJobs, bundledScripts);\n const forceApplyAll = await withSpan(\"plan.detectSdkVersionChange\", () =>\n shouldForceApplyAll(client, workspaceId, application, functionEntries),\n );\n\n return withSpan(\"plan\", async () => {\n const applications = targets.map((target) => target.application);\n const tailorDBTypeNamespaces = collectVisibleTailorDBTypeNamespaces(application, applications);\n const resolverNamespaces = collectVisibleResolverNamespaces(application, applications);\n const idpNames = collectVisibleIdpNames(application, applications);\n const ctx: PlanContext = {\n client,\n workspaceId,\n application,\n forRemoval: false,\n config,\n noSchemaCheck,\n migrationTestBaselines,\n migrationTestSnapshots,\n forceApplyAll,\n ...runInputs,\n idpUserTriggerTargets: subscribedIdps(owned),\n executorUsedTailorDBTypes: subscribedTailorDBTypes(owned),\n executorUsedResolvers: subscribedResolvers(owned),\n dependentApps: collectDependentApps(owned),\n tailorDBTypeNamespaces,\n resolverNamespaces,\n idpNames,\n };\n const functionRegistry = await withSpan(\"plan.functionRegistry\", () =>\n planFunctionRegistry(client, workspaceId, application.name, application.id, functionEntries),\n );\n const unchangedWorkflowJobs = new Set(\n functionRegistry.changeSet.unchanged\n .filter((entry) => entry.name.startsWith(WORKFLOW_PREFIX))\n .map((entry) => entry.name.slice(WORKFLOW_PREFIX.length)),\n );\n const [\n tailorDB,\n staticWebsite,\n aiGateway,\n idp,\n auth,\n pipeline,\n app,\n executor,\n workflow,\n workflowExecutionPolicy,\n secretManager,\n ] = await Promise.all([\n withSpan(\"plan.tailorDB\", () => planTailorDB(ctx)),\n withSpan(\"plan.staticWebsite\", () => planStaticWebsite(ctx)),\n withSpan(\"plan.aiGateway\", () => planAIGateway(ctx)),\n withSpan(\"plan.idp\", () => planIdP(ctx)),\n withSpan(\"plan.auth\", () => planAuth(ctx)),\n withSpan(\"plan.pipeline\", () => planPipeline(ctx)),\n withSpan(\"plan.application\", () => planApplication(ctx, httpAdapterBuildResult)),\n withSpan(\"plan.executor\", () => planExecutor(ctx)),\n withSpan(\"plan.workflow\", () =>\n planWorkflow(\n client,\n workspaceId,\n application.name,\n application.id,\n workflowService?.workflows ?? {},\n workflowBuildResult?.mainJobDeps ?? {},\n unchangedWorkflowJobs,\n {\n ...subscribedWorkflows(owned),\n jobPublishEvents: collectWorkflowJobPublishEvents(target),\n dependentApps: ctx.dependentApps,\n runAppIds: ctx.runAppIds,\n },\n ),\n ),\n withSpan(\"plan.workflowExecutionPolicy\", () =>\n planWorkflowJobFunctionExecutionPolicy(\n client,\n workspaceId,\n application.name,\n application.id,\n config.workflow?.executionPolicies ?? {},\n ),\n ),\n withSpan(\"plan.secretManager\", () => planSecretManager(ctx)),\n ]);\n\n return {\n application,\n functionRegistry,\n tailorDB,\n staticWebsite,\n aiGateway,\n idp,\n auth,\n pipeline,\n app,\n executor,\n workflow,\n workflowExecutionPolicy,\n secretManager,\n };\n });\n}\n\nexport async function planDeploymentTargets(\n params: PlanDeploymentTargetsParams,\n): Promise<PlannedDeployment[]> {\n const { targets, planTarget = planDeploymentTarget, ...planParams } = params;\n return Promise.all(\n targets.map((target) =>\n planTarget({\n ...planParams,\n target,\n targets,\n }),\n ),\n );\n}\n\nfunction deploymentPlanResults(deployment: PlannedDeployment): PlanResults {\n const { application: _application, ...results } = deployment;\n return results;\n}\n\ntype OwnershipTrackedPlan = {\n conflicts: OwnerConflict[];\n unmanaged: UnmanagedResource[];\n resourceOwners: Set<string>;\n};\n\n/**\n * Every `PlanResults` entry carries ownership-tracking fields; deriving the\n * list from `results` itself (instead of naming each key) keeps these\n * collectors in sync with `PlannedDeployment` as resource types are added.\n * @param results - Plan results for a single deployment\n * @returns The ownership-tracking plan entries\n */\nfunction ownershipTrackedPlans(results: PlanResults): ReadonlyArray<OwnershipTrackedPlan> {\n return Object.values(results);\n}\n\nfunction collectOwnerConflicts(results: PlanResults): OwnerConflict[] {\n return ownershipTrackedPlans(results).flatMap((plan) => plan.conflicts);\n}\n\nfunction collectUnmanagedResources(results: PlanResults): UnmanagedResource[] {\n return ownershipTrackedPlans(results).flatMap((plan) => plan.unmanaged);\n}\n\nfunction collectResourceOwners(results: PlanResults): Set<string> {\n return new Set(ownershipTrackedPlans(results).flatMap((plan) => [...plan.resourceOwners]));\n}\n\nfunction collectImportantResourceDeletions(results: PlanResults): ImportantResourceDeletion[] {\n const importantDeletions: ImportantResourceDeletion[] = [];\n for (const del of results.tailorDB.changeSet.type.deletes) {\n importantDeletions.push({\n resourceType: \"TailorDB type\",\n resourceName: del.name,\n });\n }\n for (const del of results.staticWebsite.changeSet.deletes) {\n importantDeletions.push({\n resourceType: \"StaticWebsite\",\n resourceName: del.name,\n });\n }\n for (const del of results.aiGateway.changeSet.deletes) {\n importantDeletions.push({\n resourceType: \"AIGateway\",\n resourceName: del.name,\n });\n }\n for (const del of results.auth.changeSet.oauth2Client.deletes) {\n importantDeletions.push({\n resourceType: \"OAuth2 client\",\n resourceName: del.name,\n });\n }\n for (const replace of results.auth.changeSet.oauth2Client.replaces) {\n importantDeletions.push({\n resourceType: \"OAuth2 client (client type change)\",\n resourceName: replace.name,\n });\n }\n for (const del of results.auth.changeSet.connection.deletes) {\n importantDeletions.push({\n resourceType: \"Auth connection\",\n resourceName: del.name,\n });\n }\n for (const del of results.secretManager.vaultChangeSet.deletes) {\n importantDeletions.push({\n resourceType: \"Secret Manager vault\",\n resourceName: del.name,\n });\n }\n for (const del of results.secretManager.secretChangeSet.deletes) {\n importantDeletions.push({\n resourceType: \"Secret Manager secret\",\n resourceName: del.name,\n });\n }\n return importantDeletions;\n}\n\ntype WorkflowJobFunctionItem = { jobFunctionName: string };\ntype ManagedResourceItem = HasName | WorkflowJobFunctionItem;\n\ntype ManagedResourceChangeSet = {\n creates: ManagedResourceItem[];\n updates: ManagedResourceItem[];\n deletes: ManagedResourceItem[];\n replaces: ManagedResourceItem[];\n unchanged: ManagedResourceItem[];\n};\n\ntype ManagedResourceGroup = {\n changeSet: ManagedResourceChangeSet;\n resourceType: string;\n namespaceFields?: readonly string[];\n namespaceOwnerResourceType?: string;\n getName?: (item: ManagedResourceItem) => string;\n};\n\nfunction readResourceField(item: ManagedResourceItem, field: string): string | undefined {\n const itemRecord = item as unknown as Record<string, unknown>;\n for (const requestField of [\"request\", \"deleteRequest\", \"createRequest\"]) {\n const request = itemRecord[requestField];\n if (request && typeof request === \"object\" && field in request) {\n const value = (request as Record<string, unknown>)[field];\n return value == null ? undefined : String(value);\n }\n }\n\n const value = itemRecord[field];\n return value == null ? undefined : String(value);\n}\n\nfunction managedResourceName(group: ManagedResourceGroup, item: ManagedResourceItem): string {\n if (group.getName) {\n return group.getName(item);\n }\n return (item as HasName).name;\n}\n\nfunction managedResourceKey(group: ManagedResourceGroup, item: ManagedResourceItem): string {\n const namespace = group.namespaceFields\n ?.map((field) => readResourceField(item, field))\n .find((value) => value !== undefined);\n const name = managedResourceName(group, item);\n return namespace !== undefined\n ? `${group.resourceType}:${namespace}:${name}`\n : `${group.resourceType}:${name}`;\n}\n\nfunction managedNamespaceOwnerKey(\n group: ManagedResourceGroup,\n item: ManagedResourceItem,\n): string | undefined {\n if (!group.namespaceOwnerResourceType) {\n return undefined;\n }\n const namespace = group.namespaceFields\n ?.map((field) => readResourceField(item, field))\n .find((value) => value !== undefined);\n return namespace !== undefined ? `${group.namespaceOwnerResourceType}:${namespace}` : undefined;\n}\n\nfunction addManagedResourceClaims(\n claims: Set<string>,\n group: ManagedResourceGroup,\n item: ManagedResourceItem,\n): void {\n claims.add(managedResourceKey(group, item));\n const namespaceOwnerKey = managedNamespaceOwnerKey(group, item);\n if (namespaceOwnerKey) {\n claims.add(namespaceOwnerKey);\n }\n}\n\nfunction isManagedResourceClaimed(\n claims: ReadonlySet<string>,\n group: ManagedResourceGroup,\n item: ManagedResourceItem,\n): boolean {\n if (claims.has(managedResourceKey(group, item))) {\n return true;\n }\n const namespaceOwnerKey = managedNamespaceOwnerKey(group, item);\n return namespaceOwnerKey ? claims.has(namespaceOwnerKey) : false;\n}\n\nfunction retainDeletesNotClaimed(\n group: ManagedResourceGroup,\n otherClaims: ReadonlySet<string>,\n): void {\n let writeIndex = 0;\n for (const item of group.changeSet.deletes) {\n if (isManagedResourceClaimed(otherClaims, group, item)) {\n logger.debug(\n `Skipping delete of ${managedResourceKey(group, item)}: still managed by another config in this deploy.`,\n );\n continue;\n }\n group.changeSet.deletes[writeIndex] = item;\n writeIndex += 1;\n }\n group.changeSet.deletes.length = writeIndex;\n}\n\nfunction workflowJobFunctionItems(items: ReadonlyArray<ManagedResourceItem>): HasName[] {\n const jobNames = new Set<string>();\n for (const item of items) {\n const usedJobNames = (item as unknown as { usedJobNames?: unknown }).usedJobNames;\n if (!Array.isArray(usedJobNames)) {\n continue;\n }\n for (const jobName of usedJobNames) {\n if (typeof jobName === \"string\") {\n jobNames.add(jobName);\n }\n }\n }\n return [...jobNames].map((name) => ({ name }));\n}\n\nfunction workflowJobFunctionResourceGroup(results: PlanResults): ManagedResourceGroup {\n return {\n changeSet: {\n creates: workflowJobFunctionItems(results.workflow.changeSet.creates),\n updates: workflowJobFunctionItems(results.workflow.changeSet.updates),\n replaces: workflowJobFunctionItems(results.workflow.changeSet.replaces),\n unchanged: [...results.workflow.unchangedWorkflowJobNames].map((name) => ({ name })),\n deletes: results.workflow.jobFunctionDeletes,\n },\n resourceType: \"workflow_job_function\",\n getName: (item) => (\"jobFunctionName\" in item ? item.jobFunctionName : item.name),\n };\n}\n\nconst MANAGED_RESOURCE_NAMESPACE_FIELDS = [\n \"namespaceName\",\n \"authNamespace\",\n \"vaultName\",\n \"staticWebsiteName\",\n] as const;\n\ntype DeployManagedResourceDefinition = Omit<ManagedResourceGroup, \"changeSet\"> & {\n resourceLabel: string;\n namesOf: (target: BuiltDeploymentTarget) => Iterable<string>;\n changeSetOf: (results: PlanResults) => ManagedResourceChangeSet;\n};\n\nconst DEPLOY_MANAGED_RESOURCE_DEFINITIONS: ReadonlyArray<DeployManagedResourceDefinition> = [\n {\n resourceLabel: \"Application\",\n resourceType: \"application\",\n namesOf: (target) => [target.application.name],\n changeSetOf: (results) => results.app,\n },\n {\n resourceLabel: \"Executor\",\n resourceType: \"executor\",\n namesOf: (target) =>\n Object.values(target.application.executorService?.executors ?? {}).map(\n (executor) => executor.name,\n ),\n changeSetOf: (results) => results.executor.changeSet,\n },\n {\n resourceLabel: \"Workflow job\",\n resourceType: \"workflow_job_function\",\n namesOf: (target) => target.bundledScripts.workflowJobs.keys(),\n changeSetOf: (results) => workflowJobFunctionResourceGroup(results).changeSet,\n getName: (item) => (\"jobFunctionName\" in item ? item.jobFunctionName : item.name),\n },\n {\n resourceLabel: \"Workflow\",\n resourceType: \"workflow\",\n namesOf: (target) =>\n Object.values(target.application.workflowService?.workflows ?? {}).map(\n (workflow) => workflow.name,\n ),\n changeSetOf: (results) => results.workflow.changeSet,\n },\n {\n resourceLabel: \"Workflow execution policy\",\n resourceType: \"workflow_job_function_execution_policy\",\n namesOf: (target) =>\n Object.values(target.config.workflow?.executionPolicies ?? {}).map((policy) => policy.name),\n changeSetOf: (results) => results.workflowExecutionPolicy.changeSet,\n },\n {\n resourceLabel: \"Auth connection\",\n resourceType: \"auth.connection\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n namesOf: (target) => Object.keys(target.application.authService?.connections ?? {}),\n changeSetOf: (results) => results.auth.changeSet.connection,\n },\n {\n resourceLabel: \"StaticWebsite\",\n resourceType: \"staticwebsite\",\n namesOf: (target) => target.application.staticWebsiteServices.map((service) => service.name),\n changeSetOf: (results) => results.staticWebsite.changeSet,\n },\n {\n resourceLabel: \"TailorDB namespace\",\n resourceType: \"tailordb.service\",\n namesOf: (target) => target.application.tailorDBServices.map((service) => service.namespace),\n changeSetOf: (results) => results.tailorDB.changeSet.service,\n },\n {\n resourceLabel: \"Auth namespace\",\n resourceType: \"auth.service\",\n namesOf: (target) => {\n const name = target.application.authService?.config.name;\n return name === undefined ? [] : [name];\n },\n changeSetOf: (results) => results.auth.changeSet.service,\n },\n {\n resourceLabel: \"IdP namespace\",\n resourceType: \"idp.service\",\n namesOf: (target) => target.application.idpServices.map((idp) => idp.name),\n changeSetOf: (results) => results.idp.changeSet.service,\n },\n {\n resourceLabel: \"Resolver namespace\",\n resourceType: \"pipeline.service\",\n namesOf: (target) => target.application.resolverServices.map((service) => service.namespace),\n changeSetOf: (results) => results.pipeline.changeSet.service,\n },\n {\n resourceLabel: \"AIGateway\",\n resourceType: \"aigateway\",\n namesOf: (target) => target.application.aiGatewayServices.map((service) => service.name),\n changeSetOf: (results) => results.aiGateway.changeSet,\n },\n {\n resourceLabel: \"Secret Manager vault\",\n resourceType: \"secret.vault\",\n namesOf: (target) => target.application.secrets.map((vault) => vault.vaultName),\n changeSetOf: (results) => results.secretManager.vaultChangeSet,\n },\n];\n\nfunction managedResourceGroupFromDefinition(\n definition: DeployManagedResourceDefinition,\n results: PlanResults,\n): ManagedResourceGroup {\n const { changeSetOf, namesOf: _namesOf, resourceLabel: _resourceLabel, ...group } = definition;\n return {\n ...group,\n changeSet: changeSetOf(results),\n };\n}\n\nfunction managedResourceGroups(results: PlanResults): ManagedResourceGroup[] {\n return [\n { changeSet: results.functionRegistry.changeSet, resourceType: \"function_registry\" },\n ...DEPLOY_MANAGED_RESOURCE_DEFINITIONS.map((definition) =>\n managedResourceGroupFromDefinition(definition, results),\n ),\n {\n changeSet: results.tailorDB.changeSet.type,\n resourceType: \"tailordb.type\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"tailordb.service\",\n },\n {\n changeSet: results.tailorDB.changeSet.gqlPermission,\n resourceType: \"tailordb.gql_permission\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"tailordb.service\",\n },\n {\n changeSet: results.staticWebsite.customDomainChangeSet,\n resourceType: \"staticwebsite.custom_domain\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"staticwebsite\",\n },\n {\n changeSet: results.idp.changeSet.client,\n resourceType: \"idp.client\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"idp.service\",\n },\n {\n changeSet: results.auth.changeSet.idpConfig,\n resourceType: \"auth.idp_config\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.userProfileConfig,\n resourceType: \"auth.user_profile_config\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.tenantConfig,\n resourceType: \"auth.tenant_config\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.machineUser,\n resourceType: \"auth.machine_user\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.oauth2Client,\n resourceType: \"auth.oauth2_client\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.authHook,\n resourceType: \"auth.hook\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.scim,\n resourceType: \"auth.scim\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.auth.changeSet.scimResource,\n resourceType: \"auth.scim_resource\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"auth.service\",\n },\n {\n changeSet: results.pipeline.changeSet.resolver,\n resourceType: \"pipeline.resolver\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"pipeline.service\",\n },\n {\n changeSet: results.secretManager.secretChangeSet,\n resourceType: \"secret.secret\",\n namespaceFields: MANAGED_RESOURCE_NAMESPACE_FIELDS,\n namespaceOwnerResourceType: \"secret.vault\",\n },\n ];\n}\n\nexport function dropCrossDeploymentManagedDeletes(\n deployments: ReadonlyArray<PlannedDeployment>,\n): void {\n const groupsByDeployment = deployments.map((deployment) =>\n managedResourceGroups(deploymentPlanResults(deployment)),\n );\n const claimsByDeployment = groupsByDeployment.map((groups) =>\n groups.reduce((claims, group) => {\n for (const item of [\n ...group.changeSet.creates,\n ...group.changeSet.updates,\n ...group.changeSet.replaces,\n ...group.changeSet.unchanged,\n ]) {\n addManagedResourceClaims(claims, group, item);\n }\n return claims;\n }, new Set<string>()),\n );\n\n groupsByDeployment.forEach((groups, deploymentIndex) => {\n const otherClaims = new Set<string>();\n claimsByDeployment.forEach((claims, claimIndex) => {\n if (claimIndex === deploymentIndex) {\n return;\n }\n for (const claim of claims) {\n otherClaims.add(claim);\n }\n });\n\n for (const group of groups) {\n retainDeletesNotClaimed(group, otherClaims);\n }\n });\n}\n\nfunction collectDeploymentResourceOwners(\n deployments: ReadonlyArray<PlannedDeployment>,\n): Set<string> {\n const owners = new Set<string>();\n for (const deployment of deployments) {\n for (const owner of collectResourceOwners(deploymentPlanResults(deployment))) {\n owners.add(owner);\n }\n }\n return owners;\n}\n\nexport async function confirmDeploymentPlans(params: ConfirmDeploymentPlansParams): Promise<void> {\n const { deployments, yes, dryRun = false, missingDependentApps = [] } = params;\n if (!dryRun) {\n await confirmMigrationCheckpointRepairs(\n deployments.flatMap((deployment) => deployment.tailorDB.context.checkpointRepairs),\n yes,\n );\n }\n await confirmMissingDependentApps(missingDependentApps, yes);\n const targetAppNames = new Set(deployments.map((deployment) => deployment.application.name));\n const resourceOwners = collectDeploymentResourceOwners(deployments);\n const scheduledRenamedAppDeletes = new Set<string>();\n const importantDeletions: ImportantResourceDeletion[] = [];\n\n for (const deployment of deployments) {\n const results = deploymentPlanResults(deployment);\n const conflicts = collectOwnerConflicts(results);\n await confirmOwnerConflict(\n conflicts,\n deployment.application.name,\n yes,\n deployment.application.id,\n );\n\n const unmanaged = collectUnmanagedResources(results);\n await confirmUnmanagedResources(unmanaged, deployment.application.name, yes);\n\n importantDeletions.push(...collectImportantResourceDeletions(results));\n\n const emptyApps = computeRenamedAppDeletions({\n conflicts,\n resourceOwners,\n protectedAppNames: targetAppNames,\n });\n for (const emptyApp of emptyApps) {\n if (scheduledRenamedAppDeletes.has(emptyApp)) {\n continue;\n }\n scheduledRenamedAppDeletes.add(emptyApp);\n deployment.app.deletes.push({\n name: emptyApp,\n request: {\n workspaceId: deployment.tailorDB.context.workspaceId,\n applicationName: emptyApp,\n },\n });\n }\n }\n\n await confirmImportantResourceDeletion(importantDeletions, yes);\n}\n\nfunction sumPlanSummaries(summaries: ReadonlyArray<PlanSummary>): PlanSummary {\n return summaries.reduce<PlanSummary>(\n (acc, summary) => ({\n create: acc.create + summary.create,\n update: acc.update + summary.update,\n delete: acc.delete + summary.delete,\n replace: acc.replace + summary.replace,\n }),\n { create: 0, update: 0, delete: 0, replace: 0 },\n );\n}\n\nexport function printDeploymentPlans(\n deployments: ReadonlyArray<PlannedDeployment>,\n opts?: PrintPlanOptions,\n): PlanSummary {\n if (logger.jsonMode && opts?.dryRun) {\n const reports = deployments.map((deployment) =>\n buildPlanReport(deploymentPlanResults(deployment)),\n );\n const summary = sumPlanSummaries(reports.map((report) => report.summary));\n logger.out({\n summary,\n changes: reports.flatMap((report) => report.json.changes),\n warnings: reports.flatMap((report) => report.json.warnings),\n conflicts: reports.flatMap((report) => report.json.conflicts),\n });\n return summary;\n }\n\n const summaries = deployments.map((deployment) =>\n printPlanResults(deploymentPlanResults(deployment), opts),\n );\n return sumPlanSummaries(summaries);\n}\n\nasync function validateDeploymentPlans(\n deployments: ReadonlyArray<PlannedDeployment>,\n): Promise<void> {\n for (const deployment of deployments) {\n await validatePlan(deploymentPlanResults(deployment));\n }\n}\n\n/**\n * Strip the services a migration test deploy must not manage, so plan modules\n * see an application that already reflects the deploy's scope. Baseline deploys\n * omit executors and Auth user profiles (data loading must not trigger current\n * event handlers or reference the final schema); every migration test deploy\n * omits workspace-bound static website custom domains.\n * @param application - Application built from the user's config\n * @param internalContext - Internal deployment behavior used by composed CLI workflows\n * @returns The application as the migration test deploy manages it\n */\nexport function adjustApplicationForMigrationTest(\n application: Application,\n internalContext: DeployInternalContext | undefined,\n): Application {\n if (!internalContext?.migrationTestSnapshots) {\n return application;\n }\n const forBaseline = internalContext.migrationTestBaselines !== undefined;\n const authService =\n forBaseline && application.authService\n ? { ...application.authService, userProfile: undefined }\n : application.authService;\n const adjusted: Application = {\n ...application,\n executorService: forBaseline ? undefined : application.executorService,\n authService,\n staticWebsiteServices: application.staticWebsiteServices.map((website) => ({\n ...website,\n customDomains: undefined,\n })),\n get applications() {\n return [adjusted];\n },\n };\n return adjusted;\n}\n\n/**\n * Deploy the configured application to the Tailor platform.\n * @param options - Deploy execution options\n * @param cliContext - Global CLI arguments to preserve in recovery actions\n * @param internalContext - Internal deployment behavior used by composed CLI workflows\n * @returns Promise that resolves to `{ bundledScripts }` when `buildOnly` is true, otherwise void\n */\nasync function deployInternal(\n options?: DeployOptions,\n cliContext?: DeployCLIContext,\n internalContext?: DeployInternalContext,\n) {\n return withSpan(\"deploy\", async (rootSpan) => {\n rootSpan.setAttribute(\"deploy.dry_run\", options?.dryRun ?? false);\n\n const configPaths = parseDeployConfigPaths(options?.configPath);\n const dryRun = options?.dryRun ?? false;\n const buildOnly =\n options?.buildOnly ?? parseBoolean(process.env.TAILOR_DEPLOY_BUILD_ONLY) === true;\n const preflightConfigs = buildOnly\n ? []\n : await withSpan(\"config.preflight\", () =>\n Promise.all(\n configPaths.map((configPath) => loadDeployConfig({ configPath, dryRun, buildOnly })),\n ),\n );\n const resolvedConfigPaths = preflightConfigs.map(({ config }) => config.path);\n const workspaceContextTargets = preflightConfigs.map(({ config }) => ({\n configPath: config.path,\n applicationId: config.id ?? `name:${config.name}`,\n }));\n const workspace = buildOnly\n ? undefined\n : await resolveDeployWorkspace({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n createWorkspace: options?.createWorkspace,\n workspaceName: options?.workspaceName,\n workspaceRegion: options?.workspaceRegion,\n organizationId: options?.organizationId,\n folderId: options?.folderId,\n dryRun,\n contextTargets: workspaceContextTargets,\n deployArgs: retryDeployArgs(options, resolvedConfigPaths, cliContext),\n workspaceCommandArgs: workspaceRecoveryArgs(options, cliContext),\n workspaceCommandJson: cliContext?.json || logger.jsonMode,\n });\n const targets = await withSpan(\"build\", async () => {\n const noCache = options?.noCache ?? false;\n const packageJson = await readPackageJson();\n const cacheDir = path.resolve(getDistDir(), \"cache\");\n if (options?.cleanCache) {\n fs.rmSync(cacheDir, { recursive: true, force: true });\n logger.info(\"Bundle cache cleaned\");\n }\n\n const targets = await buildDeploymentTargets({\n configPaths,\n loadedConfigs: preflightConfigs,\n dryRun,\n buildOnly,\n noCache,\n packageVersion: packageJson.version ?? \"unknown\",\n cacheDir,\n });\n\n return targets;\n });\n if (buildOnly) {\n return { bundledScripts: mergeBundledScripts(targets) };\n }\n\n assertUniqueGlobalResourceNames(targets);\n\n // Note: the normal apply path intentionally skips writing bundle files to\n // .tailor/. Bundles are kept in memory and uploaded directly to the\n // function registry. To test a function locally, use `function test-run`\n // with a .ts source file instead of a pre-bundled .js file.\n\n if (!workspace) throw new Error(\"Workspace was not resolved\");\n const { client, workspaceId } = workspace;\n\n rootSpan.setAttribute(\"app.name\", targets.map((target) => target.application.name).join(\",\"));\n rootSpan.setAttribute(\"workspace.id\", workspaceId);\n\n const planTargets = targets.map((target) => ({\n ...target,\n application: adjustApplicationForMigrationTest(target.application, internalContext),\n }));\n const runInputs = collectDeployRunPlanInputs(planTargets, !options?.dryRun);\n const deployments = await planDeploymentTargets({\n targets: planTargets,\n runInputs,\n client,\n workspaceId,\n noSchemaCheck: options?.noSchemaCheck,\n migrationTestBaselines: internalContext?.migrationTestBaselines,\n migrationTestSnapshots: internalContext?.migrationTestSnapshots,\n });\n\n const yes = options?.yes ?? false;\n\n dropCrossDeploymentManagedDeletes(deployments);\n\n // Phase 1b: Confirm\n const missingDependentApps = (\n await Promise.all(\n planTargets.map((target) =>\n fetchMissingDependentApps({\n client,\n workspaceId,\n application: target.application,\n runAppIds: runInputs.runAppIds ?? new Set<string>(),\n subscribedKeys: subscribedResourceKeys(runInputs.eventSubscriptions, target),\n jobsByWorkflow: target.workflowBuildResult?.mainJobDeps ?? {},\n }),\n ),\n )\n ).flat();\n\n await withSpan(\"confirm\", async () => {\n await confirmDeploymentPlans({ deployments, yes, dryRun, missingDependentApps });\n });\n\n const planSummary = printDeploymentPlans(deployments, { dryRun: options?.dryRun });\n\n if (options?.noValidate) {\n logger.warn(\"Client-side validation skipped (--no-validate).\");\n } else {\n await validateDeploymentPlans(deployments);\n }\n\n if (dryRun) {\n logger.info(\"Dry run enabled. No changes applied.\");\n return undefined;\n }\n\n await applyDeploymentPlans(client, workspaceId, deployments);\n\n if (!internalContext?.suppressResultOutput) {\n if (logger.jsonMode) {\n logger.out({ summary: planSummary, status: \"applied\" });\n } else {\n logger.success(\"Successfully applied changes.\");\n }\n }\n\n return undefined;\n });\n}\n\n/**\n * Deploy using the programmatic CLI API.\n * @param options - Deploy execution options\n * @returns Deploy result\n */\nexport function deploy(options?: DeployOptions) {\n return deployInternal(options);\n}\n\n/**\n * Deploy TailorDB baseline snapshots for an isolated migration test.\n * @param options - Deploy execution options\n * @param baselines - Baseline snapshots keyed by TailorDB namespace\n * @param baselineSnapshots - All schema snapshots that must match the source before data loading\n * @returns Deploy result\n */\nexport function deployMigrationTestBaseline(\n options: DeployOptions,\n baselines: ReadonlyMap<string, TailorDBMigrationTestBaseline>,\n baselineSnapshots: TailorDBMigrationTestSnapshots,\n) {\n return deployInternal(options, undefined, {\n migrationTestBaselines: baselines,\n migrationTestSnapshots: baselineSnapshots,\n suppressResultOutput: true,\n });\n}\n\n/**\n * Deploy pending migrations without emitting deploy's standalone result payload.\n * @param options - Deploy execution options\n * @param snapshots - Final committed snapshots keyed by TailorDB namespace\n * @returns Deploy result\n */\nexport function deployMigrationTestTarget(\n options: DeployOptions,\n snapshots: TailorDBMigrationTestSnapshots,\n) {\n return deployInternal(options, undefined, {\n migrationTestSnapshots: snapshots,\n suppressResultOutput: true,\n });\n}\n\n/**\n * Deploy from the command adapter while preserving global CLI arguments in recovery actions.\n * @param options - Deploy execution options\n * @param cliContext - Global CLI arguments already applied by the command runner\n * @returns Deploy result\n */\nexport function deployFromCLI(options: DeployOptions | undefined, cliContext: DeployCLIContext) {\n return deployInternal(options, cliContext);\n}\n","import {\n ExecutorJobStatus,\n ExecutorTargetType,\n ExecutorTriggerType,\n} from \"@tailor-platform/tailor-proto/executor_resource_pb\";\nimport { FunctionExecution_Status } from \"@tailor-platform/tailor-proto/function_resource_pb\";\nimport { styles } from \"#/cli/shared/logger\";\n\n// ============================================================================\n// Executor Job Status\n// ============================================================================\n\nexport type ExecutorJobStatusClass = \"success\" | \"failure\" | \"transient\";\n\n/**\n * Colorize executor job status string.\n * @param status - Executor job status string\n * @returns Colorized status string\n */\nexport function colorizeExecutorJobStatus(status: string): string {\n switch (status) {\n case \"PENDING\":\n return styles.dim(status);\n case \"RUNNING\":\n return styles.info(status);\n case \"SUCCESS\":\n return styles.success(status);\n case \"FAILED\":\n return styles.error(status);\n case \"CANCELED\":\n return styles.warning(status);\n default:\n return status;\n }\n}\n\n/**\n * Check if executor job status is terminal.\n * @param status - Executor job status enum value\n * @returns True if status is terminal\n */\nexport function isExecutorJobTerminalStatus(status: ExecutorJobStatus): boolean {\n return isExecutorJobSuccessStatus(status) || isExecutorJobFailureStatus(status);\n}\n\n/**\n * Check if executor job status is successful.\n * @param status - Executor job status enum value\n * @returns True if status is success\n */\nexport function isExecutorJobSuccessStatus(status: ExecutorJobStatus): boolean {\n return status === ExecutorJobStatus.SUCCESS;\n}\n\n/**\n * Check if executor job status is a terminal failure.\n * @param status - Executor job status enum value\n * @returns True if status is failure\n */\nexport function isExecutorJobFailureStatus(status: ExecutorJobStatus): boolean {\n return status === ExecutorJobStatus.FAILED || status === ExecutorJobStatus.CANCELED;\n}\n\n/**\n * Check if executor job status can still progress.\n * @param status - Executor job status enum value\n * @returns True if status is transient\n */\nexport function isExecutorJobTransientStatus(status: ExecutorJobStatus): boolean {\n return (\n status === ExecutorJobStatus.UNSPECIFIED ||\n status === ExecutorJobStatus.PENDING ||\n status === ExecutorJobStatus.RUNNING\n );\n}\n\n/**\n * Classify executor job status for waiter decisions.\n * @param status - Executor job status enum value\n * @returns Classified executor job status\n */\nexport function classifyExecutorJobStatus(status: ExecutorJobStatus): ExecutorJobStatusClass {\n if (isExecutorJobSuccessStatus(status)) {\n return \"success\";\n }\n if (isExecutorJobTerminalStatus(status)) {\n return \"failure\";\n }\n if (isExecutorJobTransientStatus(status)) {\n return \"transient\";\n }\n // Safety net: unknown future statuses are treated as transient\n return \"transient\";\n}\n\n/**\n * Parse executor job status string to enum.\n * @param status - Status string to parse\n * @returns ExecutorJobStatus enum value\n */\nexport function parseExecutorJobStatus(status: string): ExecutorJobStatus {\n const upperStatus = status.toUpperCase();\n switch (upperStatus) {\n case \"PENDING\":\n return ExecutorJobStatus.PENDING;\n case \"RUNNING\":\n return ExecutorJobStatus.RUNNING;\n case \"SUCCESS\":\n return ExecutorJobStatus.SUCCESS;\n case \"FAILED\":\n return ExecutorJobStatus.FAILED;\n case \"CANCELED\":\n return ExecutorJobStatus.CANCELED;\n default:\n throw new Error(\n `Invalid status: ${status}. Valid values: PENDING, RUNNING, SUCCESS, FAILED, CANCELED`,\n );\n }\n}\n\n// ============================================================================\n// Function Execution Status\n// ============================================================================\n\n/**\n * Colorize function execution status string.\n * @param status - Function execution status string\n * @returns Colorized status string\n */\nexport function colorizeFunctionExecutionStatus(status: string): string {\n switch (status) {\n case \"RUNNING\":\n return styles.info(status);\n case \"SUCCESS\":\n return styles.success(status);\n case \"FAILED\":\n return styles.error(status);\n default:\n return status;\n }\n}\n\n/**\n * Check if function execution status is terminal.\n * @param status - Function execution status enum value\n * @returns True if status is terminal\n */\nexport function isFunctionExecutionTerminalStatus(status: FunctionExecution_Status): boolean {\n return status === FunctionExecution_Status.SUCCESS || status === FunctionExecution_Status.FAILED;\n}\n\n// ============================================================================\n// Executor Target Type\n// ============================================================================\n\n/**\n * Convert executor target type enum to string.\n * @param targetType - Executor target type enum value\n * @returns Target type string representation\n */\nexport function executorTargetTypeToString(targetType: ExecutorTargetType): string {\n switch (targetType) {\n case ExecutorTargetType.WEBHOOK:\n return \"WEBHOOK\";\n case ExecutorTargetType.TAILOR_GRAPHQL:\n return \"GRAPHQL\";\n case ExecutorTargetType.FUNCTION:\n return \"FUNCTION\";\n case ExecutorTargetType.JOB_FUNCTION:\n return \"JOB_FUNCTION\";\n case ExecutorTargetType.WORKFLOW:\n return \"WORKFLOW\";\n default:\n return \"UNSPECIFIED\";\n }\n}\n\n/**\n * Convert executor trigger type enum to string.\n * @param triggerType - Executor trigger type enum value\n * @returns Trigger type string representation\n */\nexport function executorTriggerTypeToString(triggerType: ExecutorTriggerType): string {\n switch (triggerType) {\n case ExecutorTriggerType.SCHEDULE:\n return \"SCHEDULE\";\n case ExecutorTriggerType.EVENT:\n return \"EVENT\";\n case ExecutorTriggerType.INCOMING_WEBHOOK:\n return \"INCOMING_WEBHOOK\";\n default:\n return \"UNSPECIFIED\";\n }\n}\n","import { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport { ExecutorJobStatus } from \"@tailor-platform/tailor-proto/executor_resource_pb\";\nimport { executorTargetTypeToString, executorTriggerTypeToString } from \"./status\";\nimport type {\n ExecutorExecutor,\n ExecutorJob,\n ExecutorJobAttempt,\n ExecutorTriggerEventConfig,\n} from \"@tailor-platform/tailor-proto/executor_resource_pb\";\n\nexport interface ExecutorJobListInfo {\n id: string;\n executorName: string;\n status: string;\n createdAt: string;\n}\n\nexport interface ExecutorJobInfo {\n id: string;\n executorName: string;\n status: string;\n scheduledAt: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ExecutorJobAttemptInfo {\n id: string;\n jobId: string;\n status: string;\n error: string;\n startedAt: string;\n finishedAt: string;\n operationReference: string;\n}\n\nfunction executorJobStatusToString(status: ExecutorJobStatus): string {\n switch (status) {\n case ExecutorJobStatus.PENDING:\n return \"PENDING\";\n case ExecutorJobStatus.RUNNING:\n return \"RUNNING\";\n case ExecutorJobStatus.SUCCESS:\n return \"SUCCESS\";\n case ExecutorJobStatus.FAILED:\n return \"FAILED\";\n case ExecutorJobStatus.CANCELED:\n return \"CANCELED\";\n default:\n return \"UNSPECIFIED\";\n }\n}\n\n/**\n * Transform ExecutorJob to ExecutorJobListInfo for list display.\n * @param job - ExecutorJob from proto\n * @returns Executor job list info\n */\nexport function toExecutorJobListInfo(job: ExecutorJob): ExecutorJobListInfo {\n return {\n id: job.id,\n executorName: job.executorName,\n status: executorJobStatusToString(job.status),\n createdAt: job.createdAt ? timestampDate(job.createdAt).toISOString() : \"N/A\",\n };\n}\n\n/**\n * Transform ExecutorJob to ExecutorJobInfo for detail display.\n * @param job - ExecutorJob from proto\n * @returns Executor job info\n */\nexport function toExecutorJobInfo(job: ExecutorJob): ExecutorJobInfo {\n return {\n id: job.id,\n executorName: job.executorName,\n status: executorJobStatusToString(job.status),\n scheduledAt: job.scheduledAt ? timestampDate(job.scheduledAt).toISOString() : \"N/A\",\n createdAt: job.createdAt ? timestampDate(job.createdAt).toISOString() : \"N/A\",\n updatedAt: job.updatedAt ? timestampDate(job.updatedAt).toISOString() : \"N/A\",\n };\n}\n\n/**\n * Transform ExecutorJobAttempt to ExecutorJobAttemptInfo.\n * @param attempt - ExecutorJobAttempt from proto\n * @returns Executor job attempt info\n */\nexport function toExecutorJobAttemptInfo(attempt: ExecutorJobAttempt): ExecutorJobAttemptInfo {\n return {\n id: attempt.id,\n jobId: attempt.jobId,\n status: executorJobStatusToString(attempt.status),\n error: attempt.error || \"\",\n startedAt: attempt.startedAt ? timestampDate(attempt.startedAt).toISOString() : \"N/A\",\n finishedAt: attempt.finishedAt ? timestampDate(attempt.finishedAt).toISOString() : \"N/A\",\n operationReference: attempt.operationReference || \"\",\n };\n}\n\n// ============================================================================\n// Executor (ExecutorExecutor) Transform Functions\n// ============================================================================\n\nexport interface ExecutorListInfo {\n name: string;\n triggerType: string;\n targetType: string;\n disabled: boolean;\n}\n\nexport interface ExecutorInfo {\n name: string;\n description: string;\n triggerType: string;\n targetType: string;\n disabled: boolean;\n triggerConfig: Record<string, unknown>;\n targetConfig: Record<string, unknown>;\n}\n\nfunction formatSubjectEvent(subject: string, eventTypes: readonly string[]): string {\n const actions = eventTypes\n .map((eventType) => eventType.split(\".\").at(-1) ?? eventType)\n .join(\", \");\n return actions ? `event: ${subject} ${actions}` : `event: ${subject}`;\n}\n\nfunction formatTypedEventTrigger(config: ExecutorTriggerEventConfig): string | null {\n const typedConfig = config.typedConfig;\n if (typedConfig.case === undefined) {\n return null;\n }\n\n switch (typedConfig.case) {\n case \"tailordb\":\n return formatSubjectEvent(typedConfig.value.typeName, typedConfig.value.eventTypes);\n case \"pipeline\":\n return formatSubjectEvent(typedConfig.value.resolverName, typedConfig.value.eventTypes);\n case \"idp\":\n return formatSubjectEvent(\"idp user\", typedConfig.value.eventTypes);\n case \"auth\":\n return formatSubjectEvent(\"auth access_token\", typedConfig.value.eventTypes);\n default:\n return null;\n }\n}\n\n/**\n * Format trigger type for human-readable display.\n * Examples:\n * - event with typeName \"User\" and action \"created\" → \"event: User created\"\n * - event with resolverName \"myResolver\" → \"event: myResolver executed\"\n * - schedule with frequency \"0 12 * * *\" and timezone \"UTC\" → \"schedule: 0 12 * * * (UTC)\"\n * - incomingWebhook → \"webhook\"\n * @param executor - Executor from proto\n * @returns Formatted trigger type string\n */\nfunction formatTriggerType(executor: ExecutorExecutor): string {\n const config = executor.triggerConfig?.config;\n if (!config || config.case === undefined) {\n return executorTriggerTypeToString(executor.triggerType);\n }\n\n switch (config.case) {\n case \"schedule\":\n return `schedule: ${config.value.frequency} (${config.value.timezone})`;\n case \"event\": {\n const typedTrigger = formatTypedEventTrigger(config.value);\n if (typedTrigger) {\n return typedTrigger;\n }\n if (!config.value.eventType) {\n return executorTriggerTypeToString(executor.triggerType);\n }\n return formatEventTrigger(config.value.eventType, config.value.condition?.expr);\n }\n case \"incomingWebhook\":\n return \"webhook\";\n default:\n return executorTriggerTypeToString(executor.triggerType);\n }\n}\n\n/**\n * Format event trigger for display by parsing condition to extract type/resolver name.\n * @param eventType - Event type string (e.g., \"tailordb.type_record.created\")\n * @param condition - Condition expression that may contain args.typeName or args.resolverName\n * @returns Formatted string (e.g., \"event: User created\")\n */\nfunction formatEventTrigger(eventType: string, condition?: string): string {\n const parts = eventType.split(\".\");\n if (parts.length < 3) {\n return `event: ${eventType}`;\n }\n\n const [service, resource, action] = parts;\n\n // Try to extract name from condition\n if (condition) {\n // Match args.typeName === \"User\" or args.typeName === 'User'\n const typeNameMatch = condition.match(/args\\.typeName\\s*===?\\s*[\"']([^\"']+)[\"']/);\n if (typeNameMatch) {\n return `event: ${typeNameMatch[1]} ${action}`;\n }\n\n // Match args.resolverName === \"myResolver\" or args.resolverName === 'myResolver'\n const resolverNameMatch = condition.match(/args\\.resolverName\\s*===?\\s*[\"']([^\"']+)[\"']/);\n if (resolverNameMatch) {\n return `event: ${resolverNameMatch[1]} ${action}`;\n }\n }\n\n // Fallback: use service, resource and action\n return `event: ${service} ${resource} ${action}`;\n}\n\n/**\n * Format trigger config for display.\n * @param executor - Executor from proto\n * @returns Formatted trigger config\n */\nfunction formatTriggerConfig(executor: ExecutorExecutor): Record<string, unknown> {\n const config = executor.triggerConfig?.config;\n if (!config || config.case === undefined) {\n return {};\n }\n\n switch (config.case) {\n case \"schedule\":\n return {\n timezone: config.value.timezone,\n frequency: config.value.frequency,\n };\n case \"event\":\n return formatEventTriggerConfig(config.value);\n case \"incomingWebhook\":\n return {\n secret: config.value.secret ? \"***\" : \"\",\n };\n default:\n return {};\n }\n}\n\nfunction formatEventTriggerConfig(config: ExecutorTriggerEventConfig): Record<string, unknown> {\n const typedConfig = config.typedConfig;\n if (typedConfig.case === undefined) {\n return {\n eventType: config.eventType,\n condition: config.condition?.expr || \"\",\n };\n }\n\n // Workflows are workspace-scoped, so this is the only case with no namespace.\n // Returning early keeps `namespaceName` in the key position every other case\n // has always emitted it in.\n if (typedConfig.case === \"workflow\") {\n return {\n kind: typedConfig.case,\n eventTypes: typedConfig.value.eventTypes,\n condition: typedConfig.value.condition?.expr || \"\",\n ...(typedConfig.value.workflowName && { workflowName: typedConfig.value.workflowName }),\n };\n }\n\n const base = {\n kind: typedConfig.case,\n eventTypes: typedConfig.value.eventTypes,\n namespaceName: typedConfig.value.namespaceName,\n condition: typedConfig.value.condition?.expr || \"\",\n };\n\n switch (typedConfig.case) {\n case \"tailordb\":\n return { ...base, typeName: typedConfig.value.typeName };\n case \"pipeline\":\n return { ...base, resolverName: typedConfig.value.resolverName };\n default:\n return base;\n }\n}\n\n/**\n * Format target config for display.\n * @param executor - Executor from proto\n * @returns Formatted target config\n */\nfunction formatTargetConfig(executor: ExecutorExecutor): Record<string, unknown> {\n const config = executor.targetConfig?.config;\n if (!config || config.case === undefined) {\n return {};\n }\n\n switch (config.case) {\n case \"webhook\":\n return {\n url: config.value.url?.expr || \"\",\n headers: config.value.headers.length,\n };\n case \"tailorGraphql\":\n return {\n appName: config.value.appName,\n query: config.value.query,\n };\n case \"function\":\n return {\n name: config.value.name,\n };\n case \"workflow\":\n return {\n workflowName: config.value.workflowName,\n };\n default:\n return {};\n }\n}\n\n/**\n * Transform ExecutorExecutor to ExecutorListInfo for list display.\n * @param executor - Executor from proto\n * @returns Executor list info\n */\nexport function toExecutorListInfo(executor: ExecutorExecutor): ExecutorListInfo {\n return {\n name: executor.name,\n triggerType: formatTriggerType(executor),\n targetType: executorTargetTypeToString(executor.targetType),\n disabled: executor.disabled,\n };\n}\n\n/**\n * Transform ExecutorExecutor to ExecutorInfo for detail display.\n * @param executor - Executor from proto\n * @returns Executor info\n */\nexport function toExecutorInfo(executor: ExecutorExecutor): ExecutorInfo {\n return {\n name: executor.name,\n description: executor.description,\n triggerType: formatTriggerType(executor),\n targetType: executorTargetTypeToString(executor.targetType),\n disabled: executor.disabled,\n triggerConfig: formatTriggerConfig(executor),\n targetConfig: formatTargetConfig(executor),\n };\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { type ExecutorInfo, toExecutorInfo } from \"./transform\";\n\ntype ExecutorLike = {\n name: string;\n};\n\nconst nameArgs = {\n name: arg(z.string(), {\n positional: true,\n description: \"Executor name\",\n }),\n};\n\nexport type GetExecutorTypedOptions<E extends ExecutorLike = ExecutorLike> = {\n executor: E;\n workspaceId?: string;\n profile?: string;\n};\n\n/**\n * Resolve an executor by name.\n * @param client - Operator client\n * @param workspaceId - Workspace ID\n * @param name - Executor name\n * @returns Resolved executor\n */\nasync function resolveExecutor(\n client: Awaited<ReturnType<typeof initOperatorClient>>,\n workspaceId: string,\n name: string,\n) {\n const { executor } = await client.getExecutorExecutor({\n workspaceId,\n name,\n });\n if (!executor) {\n throw new Error(`Executor '${name}' not found.`);\n }\n return executor;\n}\n\n/**\n * Get an executor by name and return CLI-friendly info.\n * @param options - Executor lookup options\n * @returns Executor information\n */\nexport async function getExecutor<E extends ExecutorLike>(\n options: GetExecutorTypedOptions<E>,\n): Promise<ExecutorInfo> {\n const name = options.executor.name;\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n try {\n const executor = await resolveExecutor(client, workspaceId, name);\n return toExecutorInfo(executor);\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`Executor '${name}' not found.`, { cause: error });\n }\n throw error;\n }\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Get executor details\",\n args: z.strictObject({\n ...workspaceArgs,\n ...nameArgs,\n }),\n run: async (args) => {\n const executor = await getExecutor({\n executor: { name: args.name },\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n\n logger.out(executor, {\n display: {\n triggerConfig: null,\n targetConfig: null,\n },\n });\n },\n});\n","import { FunctionExecution_Status } from \"@tailor-platform/tailor-proto/function_resource_pb\";\n\n/**\n * Convert function execution status enum to string.\n * @param status - Function execution status enum value\n * @returns Status string representation\n */\nexport function functionExecutionStatusToString(status: FunctionExecution_Status): string {\n switch (status) {\n case FunctionExecution_Status.RUNNING:\n return \"RUNNING\";\n case FunctionExecution_Status.SUCCESS:\n return \"SUCCESS\";\n case FunctionExecution_Status.FAILED:\n return \"FAILED\";\n default:\n return \"UNSPECIFIED\";\n }\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\n\n/**\n * Format a caught error into a string for diagnostics.\n * @param error - Error to format\n * @returns Error message string\n */\nexport function formatWaitError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Check whether a polling error is retryable (transient platform errors).\n * @param error - Error to check\n * @returns True if the error should be retried\n */\nexport function isRetryableWaitError(error: unknown): boolean {\n if (!(error instanceof ConnectError)) {\n return false;\n }\n return (\n error.code === Code.Aborted ||\n error.code === Code.ResourceExhausted ||\n error.code === Code.Unavailable\n );\n}\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { durationArg } from \"#/cli/shared/args\";\nimport type { WorkflowWaitUntil } from \"./status\";\n\ntype ArgsShape = Record<string, z.ZodType>;\n\nexport const workflowWaitUntilArg = z.enum([\n \"success\",\n \"suspended\",\n \"terminal\",\n]) satisfies z.ZodType<WorkflowWaitUntil>;\n\nexport const nameArgs = {\n name: arg(z.string(), {\n positional: true,\n description: \"Workflow name\",\n }),\n} satisfies ArgsShape;\n\nexport const workflowWaitControlArgs = {\n interval: arg(durationArg.default(\"3s\"), {\n alias: \"i\",\n description: \"Polling interval when waiting (e.g., '3s', '500ms', '1m')\",\n }),\n timeout: arg(durationArg.default(\"10m\"), {\n alias: \"t\",\n description: \"Maximum time to wait (e.g., '30s', '10m')\",\n }),\n until: arg(workflowWaitUntilArg.default(\"terminal\"), {\n alias: \"u\",\n description: \"Wait target (success, suspended, terminal)\",\n }),\n logs: arg(z.boolean().default(false), {\n alias: \"l\",\n description: \"Display job execution logs after completion\",\n }),\n} satisfies ArgsShape;\n\nexport const waitArgs = {\n wait: arg(z.boolean().default(false), {\n alias: \"W\",\n description: \"Wait for execution to complete\",\n }),\n ...workflowWaitControlArgs,\n} satisfies ArgsShape;\n","import {\n WorkflowExecution_Status,\n WorkflowJobExecution_Status,\n} from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\nimport type { WorkflowExecution } from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\n\nexport type WorkflowWaitUntil = \"success\" | \"suspended\" | \"terminal\";\n\nexport type WorkflowExecutionStatusClass = \"success\" | \"suspended\" | \"failure\" | \"transient\";\n\nexport interface WorkflowExecutionStatusClassification {\n statusClass: WorkflowExecutionStatusClass;\n status: WorkflowExecution_Status;\n}\n\n/**\n * Check if workflow execution status is successful.\n * @param status - Workflow execution status enum value\n * @returns True if status is success\n */\nexport function isWorkflowExecutionSuccessStatus(status: WorkflowExecution_Status): boolean {\n return status === WorkflowExecution_Status.SUCCESS;\n}\n\n/**\n * Check if workflow job execution status is suspended or waiting.\n * @param status - Workflow job execution status enum value\n * @returns True if status represents a wait point\n */\nexport function isWorkflowJobExecutionSuspendedStatus(\n status: WorkflowJobExecution_Status,\n): boolean {\n return (\n status === WorkflowJobExecution_Status.SUSPEND || status === WorkflowJobExecution_Status.WAITING\n );\n}\n\n/**\n * Check if workflow execution status is suspended or waiting.\n * @param status - Workflow execution status enum value\n * @returns True if status represents a suspended execution\n */\nexport function isWorkflowExecutionSuspendedStatus(status: WorkflowExecution_Status): boolean {\n return (\n status === WorkflowExecution_Status.PENDING_RESUME ||\n status === WorkflowExecution_Status.WAITING\n );\n}\n\n/**\n * Check if workflow execution status is a terminal failure.\n * @param status - Workflow execution status enum value\n * @returns True if status represents failure\n */\nexport function isWorkflowExecutionFailureStatus(status: WorkflowExecution_Status): boolean {\n return status === WorkflowExecution_Status.FAILED;\n}\n\n/**\n * Check if workflow execution status can still progress without user action.\n * @param status - Workflow execution status enum value\n * @returns True if status is transient\n */\nexport function isWorkflowExecutionTransientStatus(status: WorkflowExecution_Status): boolean {\n return (\n status === WorkflowExecution_Status.UNSPECIFIED ||\n status === WorkflowExecution_Status.PENDING ||\n status === WorkflowExecution_Status.RUNNING ||\n status === WorkflowExecution_Status.PENDING_RETRY\n );\n}\n\n/**\n * Check if workflow execution status is terminal.\n * @param status - Workflow execution status enum value\n * @returns True if status is terminal\n */\nexport function isWorkflowExecutionTerminalStatus(status: WorkflowExecution_Status): boolean {\n return (\n isWorkflowExecutionSuccessStatus(status) ||\n isWorkflowExecutionFailureStatus(status) ||\n isWorkflowExecutionSuspendedStatus(status)\n );\n}\n\n/**\n * Classify workflow execution status for waiter decisions.\n * @param execution - Workflow execution to classify\n * @returns Classified workflow execution status\n */\nexport function classifyWorkflowExecutionStatus(\n execution: WorkflowExecution,\n): WorkflowExecutionStatusClassification {\n if (isWorkflowExecutionTerminalStatus(execution.status)) {\n if (isWorkflowExecutionSuccessStatus(execution.status)) {\n return { statusClass: \"success\", status: execution.status };\n }\n if (isWorkflowExecutionFailureStatus(execution.status)) {\n return { statusClass: \"failure\", status: execution.status };\n }\n return { statusClass: \"suspended\", status: execution.status };\n }\n if (execution.jobExecutions.some((job) => isWorkflowJobExecutionSuspendedStatus(job.status))) {\n return { statusClass: \"suspended\", status: execution.status };\n }\n if (isWorkflowExecutionTransientStatus(execution.status)) {\n return { statusClass: \"transient\", status: execution.status };\n }\n // Safety net: unknown future statuses are treated as transient\n return { statusClass: \"transient\", status: execution.status };\n}\n\n/**\n * Check if a classified workflow execution has reached the requested waiter target.\n * @param classification - Workflow execution status classification\n * @param until - Requested wait target\n * @returns True if the wait target is reached\n */\nexport function hasReachedWorkflowWaitTarget(\n classification: WorkflowExecutionStatusClassification,\n until: WorkflowWaitUntil,\n): boolean {\n switch (until) {\n case \"success\":\n return classification.statusClass === \"success\";\n case \"suspended\":\n return classification.statusClass === \"suspended\";\n case \"terminal\":\n return (\n classification.statusClass === \"success\" ||\n classification.statusClass === \"failure\" ||\n classification.statusClass === \"suspended\"\n );\n }\n}\n","import { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport {\n WorkflowExecution_Status,\n WorkflowJobExecution_Status,\n} from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\nimport type {\n Workflow,\n WorkflowExecution,\n WorkflowJobExecution,\n} from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\n\nexport interface WorkflowListInfo {\n name: string;\n mainJob: string;\n jobFunctions: number;\n updatedAt: Date | null;\n}\n\nexport interface WorkflowInfo {\n name: string;\n id: string;\n mainJob: string;\n jobFunctions: Record<string, string>;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\nexport interface WorkflowJobExecutionInfo {\n id: string;\n stackedJobName: string;\n status: string;\n executionId: string;\n startedAt: Date | null;\n finishedAt: Date | null;\n}\n\nexport interface WorkflowExecutionInfo {\n id: string;\n workflowName: string;\n status: string;\n jobExecutions: number;\n startedAt: Date | null;\n finishedAt: Date | null;\n}\n\n/**\n * Convert a workflow execution status enum to a string.\n * @param status - Workflow execution status\n * @returns String representation of the status\n */\nfunction workflowExecutionStatusToString(status: WorkflowExecution_Status): string {\n switch (status) {\n case WorkflowExecution_Status.PENDING:\n return \"PENDING\";\n case WorkflowExecution_Status.PENDING_RESUME:\n return \"PENDING_RESUME\";\n case WorkflowExecution_Status.RUNNING:\n return \"RUNNING\";\n case WorkflowExecution_Status.SUCCESS:\n return \"SUCCESS\";\n case WorkflowExecution_Status.FAILED:\n return \"FAILED\";\n case WorkflowExecution_Status.PENDING_RETRY:\n return \"PENDING_RETRY\";\n case WorkflowExecution_Status.WAITING:\n return \"WAITING\";\n default:\n return \"UNSPECIFIED\";\n }\n}\n\n/**\n * Convert a workflow job execution status enum to a string.\n * @param status - Workflow job execution status\n * @returns String representation of the status\n */\nfunction workflowJobExecutionStatusToString(status: WorkflowJobExecution_Status): string {\n switch (status) {\n case WorkflowJobExecution_Status.RUNNING:\n return \"RUNNING\";\n case WorkflowJobExecution_Status.SUSPEND:\n return \"SUSPEND\";\n case WorkflowJobExecution_Status.SUCCESS:\n return \"SUCCESS\";\n case WorkflowJobExecution_Status.FAILED:\n return \"FAILED\";\n case WorkflowJobExecution_Status.WAITING:\n return \"WAITING\";\n default:\n return \"UNSPECIFIED\";\n }\n}\n\n/**\n * Convert a Workflow proto to CLI-friendly list info.\n * @param workflow - Workflow resource\n * @returns Flattened workflow list info\n */\nexport function toWorkflowListInfo(workflow: Workflow): WorkflowListInfo {\n return {\n name: workflow.name,\n mainJob: workflow.mainJobFunctionName,\n jobFunctions: Object.keys(workflow.jobFunctions).length,\n updatedAt: workflow.updatedAt ? timestampDate(workflow.updatedAt) : null,\n };\n}\n\n/**\n * Convert a Workflow proto to detailed workflow info for CLI output.\n * @param workflow - Workflow resource\n * @returns Detailed workflow info\n */\nexport function toWorkflowInfo(workflow: Workflow): WorkflowInfo {\n const jobFunctions: Record<string, string> = {};\n for (const [name, version] of Object.entries(workflow.jobFunctions)) {\n jobFunctions[name] = version.toString();\n }\n\n return {\n name: workflow.name,\n id: workflow.id,\n mainJob: workflow.mainJobFunctionName,\n jobFunctions: jobFunctions,\n createdAt: workflow.createdAt ? timestampDate(workflow.createdAt) : null,\n updatedAt: workflow.updatedAt ? timestampDate(workflow.updatedAt) : null,\n };\n}\n\n/**\n * Convert a WorkflowJobExecution proto to CLI-friendly job execution info.\n * @param jobExecution - Workflow job execution resource\n * @returns Flattened job execution info\n */\nexport function toWorkflowJobExecutionInfo(\n jobExecution: WorkflowJobExecution,\n): WorkflowJobExecutionInfo {\n return {\n id: jobExecution.id,\n stackedJobName: jobExecution.stackedJobName,\n status: workflowJobExecutionStatusToString(jobExecution.status),\n executionId: jobExecution.executionId,\n startedAt: jobExecution.startedAt ? timestampDate(jobExecution.startedAt) : null,\n finishedAt: jobExecution.finishedAt ? timestampDate(jobExecution.finishedAt) : null,\n };\n}\n\n/**\n * Convert a WorkflowExecution proto to CLI-friendly execution info.\n * @param execution - Workflow execution resource\n * @returns Flattened execution info\n */\nexport function toWorkflowExecutionInfo(execution: WorkflowExecution): WorkflowExecutionInfo {\n return {\n id: execution.id,\n workflowName: execution.workflowName,\n status: workflowExecutionStatusToString(execution.status),\n jobExecutions: execution.jobExecutions.length,\n startedAt: execution.startedAt ? timestampDate(execution.startedAt) : null,\n finishedAt: execution.finishedAt ? timestampDate(execution.finishedAt) : null,\n };\n}\n","import { setTimeout } from \"node:timers/promises\";\nimport {\n WorkflowExecution_Status,\n WorkflowJobExecution_Status,\n} from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { spinner } from \"#/cli/shared/spinner\";\nimport { formatWaitError, isRetryableWaitError } from \"#/cli/shared/wait-error\";\nimport {\n classifyWorkflowExecutionStatus,\n hasReachedWorkflowWaitTarget,\n isWorkflowExecutionFailureStatus,\n isWorkflowExecutionSuspendedStatus,\n type WorkflowExecutionStatusClass,\n type WorkflowWaitUntil,\n} from \"./status\";\nimport { type WorkflowExecutionInfo, toWorkflowExecutionInfo } from \"./transform\";\nimport type { WorkflowExecution } from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\n\nexport const DEFAULT_WORKFLOW_WAIT_INTERVAL_MS = 3000;\n\nexport interface WorkflowWaitOptions {\n client: Awaited<ReturnType<typeof initOperatorClient>>;\n workspaceId: string;\n executionId: string;\n interval?: number;\n timeout?: number;\n until?: WorkflowWaitUntil;\n showProgress?: boolean;\n trackJobs?: boolean;\n}\n\nexport interface WaitWorkflowExecutionOptions {\n executionId: string;\n workspaceId?: string;\n profile?: string;\n interval?: number;\n timeout?: number;\n until?: WorkflowWaitUntil;\n showProgress?: boolean;\n trackJobs?: boolean;\n}\n\nexport interface WorkflowWaitResult extends WorkflowExecutionInfo {\n statusClass: WorkflowExecutionStatusClass | \"unknown\";\n elapsedMs: number;\n attempts: number;\n timedOut: boolean;\n lastError: string | null;\n}\n\nfunction formatTime(date: Date): string {\n return date.toLocaleTimeString(\"en-US\", { hour12: false });\n}\n\nfunction colorizeStatus(status: WorkflowExecution_Status): string {\n const statusText = WorkflowExecution_Status[status];\n switch (status) {\n case WorkflowExecution_Status.PENDING:\n case WorkflowExecution_Status.UNSPECIFIED:\n return styles.dim(statusText);\n case WorkflowExecution_Status.PENDING_RESUME:\n case WorkflowExecution_Status.PENDING_RETRY:\n case WorkflowExecution_Status.WAITING:\n return styles.warning(statusText);\n case WorkflowExecution_Status.RUNNING:\n return styles.info(statusText);\n case WorkflowExecution_Status.SUCCESS:\n return styles.success(statusText);\n case WorkflowExecution_Status.FAILED:\n return styles.error(statusText);\n default:\n return statusText;\n }\n}\n\nfunction getActiveJobs(execution: WorkflowExecution): string {\n return execution.jobExecutions\n .filter(\n (job) =>\n job.status === WorkflowJobExecution_Status.RUNNING ||\n job.status === WorkflowJobExecution_Status.SUSPEND ||\n job.status === WorkflowJobExecution_Status.WAITING,\n )\n .map((job) => job.stackedJobName)\n .join(\", \");\n}\n\ninterface CreateWorkflowWaitResultOptions {\n executionId: string;\n execution: WorkflowExecution | undefined;\n startedAt: number;\n attempts: number;\n timedOut: boolean;\n lastError: string | null;\n}\n\nfunction createWorkflowWaitResult(options: CreateWorkflowWaitResultOptions): WorkflowWaitResult {\n const elapsedMs = Date.now() - options.startedAt;\n if (options.execution) {\n const classification = classifyWorkflowExecutionStatus(options.execution);\n return {\n ...toWorkflowExecutionInfo(options.execution),\n statusClass: classification.statusClass,\n elapsedMs,\n attempts: options.attempts,\n timedOut: options.timedOut,\n lastError: options.lastError,\n };\n }\n return {\n id: options.executionId,\n workflowName: \"\",\n status: \"UNKNOWN\",\n statusClass: \"unknown\",\n jobExecutions: 0,\n startedAt: null,\n finishedAt: null,\n elapsedMs,\n attempts: options.attempts,\n timedOut: options.timedOut,\n lastError: options.lastError,\n };\n}\n\n/**\n * Wait for a workflow execution to reach the requested state.\n * @param options - Workflow waiter options\n * @returns Final or timed-out workflow wait result\n */\nexport async function waitForWorkflowExecution(\n options: WorkflowWaitOptions,\n): Promise<WorkflowWaitResult> {\n const interval = options.interval ?? DEFAULT_WORKFLOW_WAIT_INTERVAL_MS;\n const until = options.until ?? \"terminal\";\n const startedAt = Date.now();\n const sp = options.showProgress\n ? spinner({ indent: 2 }).start(\"Waiting for workflow to complete...\")\n : null;\n\n let attempts = 0;\n let lastExecution: WorkflowExecution | undefined;\n let lastError: string | null = null;\n let lastStatus: WorkflowExecution_Status | undefined;\n let lastActiveJobs: string | undefined;\n\n try {\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const elapsedMs = Date.now() - startedAt;\n const remainingMs = options.timeout === undefined ? undefined : options.timeout - elapsedMs;\n if (remainingMs !== undefined && remainingMs <= 0) {\n sp?.fail(\"Workflow wait timed out.\");\n return createWorkflowWaitResult({\n executionId: options.executionId,\n execution: lastExecution,\n startedAt,\n attempts,\n timedOut: true,\n lastError,\n });\n }\n\n try {\n attempts += 1;\n const { execution } = await options.client.getWorkflowExecution({\n workspaceId: options.workspaceId,\n executionId: options.executionId,\n });\n\n if (!execution) {\n sp?.fail(`Execution '${options.executionId}' not found.`);\n throw new Error(`Execution '${options.executionId}' not found.`);\n }\n\n lastExecution = execution;\n lastError = null;\n\n const classification = classifyWorkflowExecutionStatus(execution);\n const coloredStatus = colorizeStatus(execution.status);\n\n if (execution.status !== lastStatus) {\n if (options.showProgress) {\n sp?.stop();\n logger.info(`Status: ${coloredStatus}`, {\n mode: \"stream\",\n indent: 2,\n });\n sp?.start(\"Waiting for workflow to complete...\");\n }\n lastStatus = execution.status;\n }\n\n if (options.trackJobs) {\n const activeJobs = getActiveJobs(execution);\n if (activeJobs && activeJobs !== lastActiveJobs) {\n if (options.showProgress) {\n sp?.stop();\n logger.info(`Job | ${activeJobs}: ${coloredStatus}`, {\n mode: \"stream\",\n indent: 2,\n });\n sp?.start(\"Waiting for workflow to complete...\");\n }\n lastActiveJobs = activeJobs;\n }\n }\n\n if (sp) {\n sp.text = `Waiting for workflow to complete... (${formatTime(new Date())})`;\n }\n\n if (\n hasReachedWorkflowWaitTarget(classification, until) ||\n classification.statusClass === \"failure\" ||\n (until === \"suspended\" && classification.statusClass === \"success\")\n ) {\n if (execution.status === WorkflowExecution_Status.SUCCESS) {\n sp?.succeed(`Completed: ${coloredStatus}`);\n } else if (isWorkflowExecutionFailureStatus(execution.status)) {\n sp?.fail(`Completed: ${coloredStatus}`);\n } else if (isWorkflowExecutionSuspendedStatus(execution.status)) {\n sp?.warn(`Completed: ${coloredStatus}`);\n } else {\n sp?.succeed(`Completed: ${coloredStatus}`);\n }\n return createWorkflowWaitResult({\n executionId: options.executionId,\n execution,\n startedAt,\n attempts,\n timedOut: false,\n lastError,\n });\n }\n } catch (error) {\n if (!isRetryableWaitError(error)) {\n throw error;\n }\n lastError = formatWaitError(error);\n if (options.showProgress) {\n if (sp) {\n sp.text = `Retrying workflow status poll... (${formatTime(new Date())})`;\n }\n }\n }\n\n const nextElapsedMs = Date.now() - startedAt;\n const nextRemainingMs =\n options.timeout === undefined ? undefined : options.timeout - nextElapsedMs;\n if (nextRemainingMs !== undefined && nextRemainingMs <= 0) {\n sp?.fail(\"Workflow wait timed out.\");\n return createWorkflowWaitResult({\n executionId: options.executionId,\n execution: lastExecution,\n startedAt,\n attempts,\n timedOut: true,\n lastError,\n });\n }\n\n await setTimeout(\n nextRemainingMs === undefined ? interval : Math.min(interval, nextRemainingMs),\n );\n }\n } finally {\n sp?.stop();\n }\n}\n\n/**\n * Wait for an existing workflow execution by ID.\n * @param options - Workflow execution wait options\n * @returns Workflow wait result\n */\nexport async function waitForWorkflowExecutionById(\n options: WaitWorkflowExecutionOptions,\n): Promise<WorkflowWaitResult> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n return await waitForWorkflowExecution({\n client,\n workspaceId,\n executionId: options.executionId,\n interval: options.interval,\n timeout: options.timeout,\n until: options.until,\n showProgress: options.showProgress,\n trackJobs: options.trackJobs,\n });\n}\n\n/**\n * Build a user-facing failure message for a workflow wait result.\n * @param result - Workflow wait result\n * @param until - Requested wait target\n * @returns Failure message, or undefined when the wait succeeded\n */\nexport function getWorkflowWaitFailureMessage(\n result: WorkflowWaitResult,\n until: WorkflowWaitUntil,\n): string | undefined {\n if (result.timedOut) {\n return `Timed out waiting for workflow execution '${result.id}' to reach ${until}. Last status: ${result.status}.`;\n }\n if (result.status === \"FAILED\") {\n return `Workflow execution '${result.id}' failed.`;\n }\n if (until === \"success\" && result.statusClass !== \"success\") {\n return `Workflow execution '${result.id}' reached ${result.status} before success.`;\n }\n if (until === \"suspended\" && result.statusClass !== \"suspended\") {\n return `Workflow execution '${result.id}' reached ${result.status} before suspension.`;\n }\n return undefined;\n}\n","import { create } from \"@bufbuild/protobuf\";\nimport {\n Condition_Operator,\n ConditionSchema,\n FilterSchema,\n} from \"@tailor-platform/tailor-proto/resource_pb\";\nimport { WorkflowExecution_Status } from \"@tailor-platform/tailor-proto/workflow_resource_pb\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport {\n type Order,\n pagedLogArgs,\n parseDuration,\n toPageDirection,\n workspaceArgs,\n} from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { formatKeyValueTable } from \"#/cli/shared/format\";\nimport { styles, logger } from \"#/cli/shared/logger\";\nimport { waitArgs } from \"./args\";\nimport { type WorkflowWaitUntil } from \"./status\";\nimport {\n type WorkflowExecutionInfo,\n type WorkflowJobExecutionInfo,\n toWorkflowExecutionInfo,\n toWorkflowJobExecutionInfo,\n} from \"./transform\";\nimport {\n getWorkflowWaitFailureMessage,\n waitForWorkflowExecution,\n waitForWorkflowExecutionById,\n type WorkflowWaitResult,\n} from \"./waiter\";\nimport type { FunctionExecution } from \"@tailor-platform/tailor-proto/function_resource_pb\";\n\ntype WorkflowLike = {\n name: string;\n};\n\nexport type ListWorkflowExecutionsTypedOptions<W extends WorkflowLike = WorkflowLike> = {\n workflow?: W;\n status?: string;\n workspaceId?: string;\n profile?: string;\n order?: Order;\n limit?: number;\n};\n\nexport interface GetWorkflowExecutionOptions {\n executionId: string;\n workspaceId?: string;\n profile?: string;\n interval?: number;\n timeout?: number;\n until?: WorkflowWaitUntil;\n logs?: boolean;\n}\n\nexport interface WorkflowExecutionDetailInfo extends WorkflowExecutionInfo {\n jobDetails?: (WorkflowJobExecutionInfo & {\n logs?: string;\n result?: string;\n })[];\n}\n\nexport interface WorkflowExecutionWaitInfo extends WorkflowExecutionDetailInfo {\n statusClass: WorkflowWaitResult[\"statusClass\"];\n elapsedMs: number;\n attempts: number;\n timedOut: boolean;\n lastError: string | null;\n}\n\nexport interface GetWorkflowExecutionResult {\n execution: WorkflowExecutionDetailInfo;\n wait: () => Promise<WorkflowExecutionWaitInfo>;\n}\n\nfunction parseStatus(status: string): WorkflowExecution_Status {\n const upperStatus = status.toUpperCase();\n switch (upperStatus) {\n case \"PENDING\":\n return WorkflowExecution_Status.PENDING;\n case \"PENDING_RESUME\":\n return WorkflowExecution_Status.PENDING_RESUME;\n case \"RUNNING\":\n return WorkflowExecution_Status.RUNNING;\n case \"SUCCESS\":\n return WorkflowExecution_Status.SUCCESS;\n case \"FAILED\":\n return WorkflowExecution_Status.FAILED;\n case \"PENDING_RETRY\":\n return WorkflowExecution_Status.PENDING_RETRY;\n case \"WAITING\":\n return WorkflowExecution_Status.WAITING;\n case \"UNSPECIFIED\":\n return WorkflowExecution_Status.UNSPECIFIED;\n default:\n throw new Error(\n `Invalid status: ${status}. Valid values: UNSPECIFIED, PENDING, PENDING_RESUME, RUNNING, SUCCESS, FAILED, PENDING_RETRY, WAITING`,\n );\n }\n}\n\n/**\n * List workflow executions with optional filters.\n *\n * Returns at most `options.limit` items. When `limit` is omitted or 0 the\n * function pages through every execution. The CLI caps this at 50 by\n * default via `pagedLogArgs`; programmatic callers that want the same\n * cap should pass `limit: 50` explicitly.\n * @param options - Workflow execution listing options\n * @returns List of workflow executions\n */\nexport async function listWorkflowExecutions<W extends WorkflowLike>(\n options?: ListWorkflowExecutionsTypedOptions<W>,\n): Promise<WorkflowExecutionInfo[]> {\n const workflowName = options?.workflow?.name;\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n const filters: ReturnType<typeof create<typeof FilterSchema>>[] = [];\n\n if (options?.status) {\n const statusValue = parseStatus(options.status);\n filters.push(\n create(FilterSchema, {\n condition: create(ConditionSchema, {\n field: \"status\",\n operator: Condition_Operator.EQ,\n value: { kind: { case: \"numberValue\", value: statusValue } },\n }),\n }),\n );\n }\n\n const filter =\n filters.length > 0\n ? create(FilterSchema, {\n and: filters,\n })\n : undefined;\n\n const pageDirection = toPageDirection(options?.order ?? \"desc\");\n const executions = await fetchPaged(\n async (pageToken, pageSize) => {\n const { executions, nextPageToken } = await client.listWorkflowExecutions({\n workspaceId,\n workflowName: workflowName ?? \"\",\n pageToken,\n pageSize,\n pageDirection,\n filter,\n });\n return [executions, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return executions.map(toWorkflowExecutionInfo);\n}\n\n/**\n * Get a single workflow execution with optional logs.\n * @param options - Workflow execution lookup options\n * @returns Workflow execution with optional logs\n */\nexport async function getWorkflowExecution(\n options: GetWorkflowExecutionOptions,\n): Promise<GetWorkflowExecutionResult> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n async function fetchFunctionExecution(\n functionExecutionId: string,\n ): Promise<FunctionExecution | undefined> {\n try {\n const filter = create(FilterSchema, {\n condition: create(ConditionSchema, {\n field: \"id\",\n operator: Condition_Operator.EQ,\n value: { kind: { case: \"stringValue\", value: functionExecutionId } },\n }),\n });\n\n const response = await client.listFunctionExecutions({\n workspaceId,\n filter,\n pageSize: 1,\n });\n\n return response.executions[0];\n } catch {\n return undefined;\n }\n }\n\n async function fetchExecutionWithLogs(\n executionId: string,\n includeLogs: boolean,\n ): Promise<WorkflowExecutionDetailInfo> {\n const { execution } = await client.getWorkflowExecution({\n workspaceId,\n executionId,\n });\n\n if (!execution) {\n throw new Error(`Execution '${executionId}' not found.`);\n }\n\n const result: WorkflowExecutionDetailInfo = toWorkflowExecutionInfo(execution);\n\n if (includeLogs && execution.jobExecutions.length > 0) {\n result.jobDetails = await Promise.all(\n execution.jobExecutions.map(async (job) => {\n const jobInfo = toWorkflowJobExecutionInfo(job);\n if (job.executionId) {\n const functionExecution = await fetchFunctionExecution(job.executionId);\n if (functionExecution) {\n return {\n ...jobInfo,\n logs: functionExecution.logs || undefined,\n result: functionExecution.result || undefined,\n };\n }\n }\n return jobInfo;\n }),\n );\n }\n\n return result;\n }\n\n async function waitForCompletion(): Promise<WorkflowExecutionWaitInfo> {\n const interval = options.interval ?? 3000;\n const waitResult = await waitForWorkflowExecution({\n client,\n workspaceId,\n executionId: options.executionId,\n interval,\n timeout: options.timeout,\n until: options.until ?? \"terminal\",\n });\n const execution = await fetchExecutionWithLogs(options.executionId, options.logs ?? false);\n return {\n ...execution,\n statusClass: waitResult.statusClass,\n elapsedMs: waitResult.elapsedMs,\n attempts: waitResult.attempts,\n timedOut: waitResult.timedOut,\n lastError: waitResult.lastError,\n };\n }\n\n const execution = await fetchExecutionWithLogs(options.executionId, options.logs ?? false);\n\n return {\n execution,\n wait: waitForCompletion,\n };\n}\n\n/**\n * Print a workflow execution and its logs in a human-readable format.\n * @param execution - Workflow execution detail info\n */\nexport function printExecutionWithLogs(execution: WorkflowExecutionDetailInfo): void {\n // Helper to format Date as ISO string or \"N/A\"\n const formatDate = (date: Date | null): string => (date ? date.toISOString() : \"N/A\");\n\n // Print execution summary\n const summaryData: [string, string][] = [\n [\"id\", execution.id],\n [\"workflowName\", execution.workflowName],\n [\"status\", execution.status],\n [\"jobExecutions\", execution.jobExecutions.toString()],\n [\"startedAt\", formatDate(execution.startedAt)],\n [\"finishedAt\", formatDate(execution.finishedAt)],\n ];\n logger.out(formatKeyValueTable(summaryData));\n\n // Print job details with logs\n if (execution.jobDetails && execution.jobDetails.length > 0) {\n logger.log(styles.bold(\"\\nJob Executions:\"));\n for (const job of execution.jobDetails) {\n logger.log(styles.info(`\\n--- ${job.stackedJobName} ---`));\n logger.log(` Status: ${job.status}`);\n logger.log(` Started: ${formatDate(job.startedAt)}`);\n logger.log(` Finished: ${formatDate(job.finishedAt)}`);\n\n if (job.logs) {\n logger.log(styles.warning(\"\\n Logs:\"));\n const logLines = job.logs.split(\"\\n\");\n for (const line of logLines) {\n logger.log(` ${line}`);\n }\n }\n\n if (job.result) {\n logger.log(styles.success(\"\\n Result:\"));\n try {\n const parsed = JSON.parse(job.result);\n logger.log(` ${JSON.stringify(parsed, null, 2).split(\"\\n\").join(\"\\n \")}`);\n } catch {\n logger.log(` ${job.result}`);\n }\n }\n }\n }\n}\n\nexport const executionsCommand = defineAppCommand({\n name: \"executions\",\n description: \"List or get workflow executions.\",\n args: z.strictObject({\n ...workspaceArgs,\n ...pagedLogArgs,\n \"execution-id\": arg(z.string().optional(), {\n positional: true,\n description: \"Execution ID (if provided, shows details)\",\n }),\n \"workflow-name\": arg(\n z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/,\n \"Must be 3-63 lowercase alphanumeric characters or hyphens, starting and ending with alphanumeric\",\n )\n .optional(),\n {\n alias: \"n\",\n description: \"Filter by workflow name (list mode only)\",\n },\n ),\n status: arg(z.string().optional(), {\n alias: \"s\",\n description: \"Filter by status (list mode only)\",\n }),\n ...waitArgs,\n logs: arg(z.boolean().default(false), {\n description: \"Display job execution logs (detail mode only)\",\n }),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode || args.json;\n if (args.executionId) {\n const interval = parseDuration(args.interval);\n\n if (!jsonOutput) {\n logger.info(`Execution ID: ${args.executionId}`, { mode: \"stream\" });\n }\n\n if (args.wait) {\n const result = await waitForWorkflowExecutionById({\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval,\n timeout: parseDuration(args.timeout),\n until: args.until,\n showProgress: !jsonOutput,\n trackJobs: true,\n });\n\n if (args.logs && !jsonOutput) {\n const { execution } = await getWorkflowExecution({\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n logs: true,\n });\n printExecutionWithLogs(execution);\n } else if (args.logs) {\n const { execution } = await getWorkflowExecution({\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n logs: true,\n });\n const output: WorkflowWaitResult & Pick<WorkflowExecutionDetailInfo, \"jobDetails\"> = {\n ...result,\n jobDetails: execution.jobDetails,\n };\n logger.out(output);\n } else {\n logger.out(result);\n }\n\n const failureMessage = getWorkflowWaitFailureMessage(result, args.until);\n if (failureMessage) {\n throw new Error(failureMessage);\n }\n return;\n }\n\n const { execution } = await getWorkflowExecution({\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval,\n logs: args.logs,\n });\n\n if (args.logs && !jsonOutput) {\n printExecutionWithLogs(execution);\n } else {\n logger.out(execution);\n }\n } else {\n const executions = await listWorkflowExecutions({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n workflow: args[\"workflow-name\"] === undefined ? undefined : { name: args[\"workflow-name\"] },\n status: args.status,\n order: args.order,\n limit: args.limit,\n });\n logger.out(executions);\n }\n },\n});\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { nameArgs } from \"./args\";\nimport { type WorkflowInfo, toWorkflowInfo } from \"./transform\";\n\ntype WorkflowLike = {\n name: string;\n};\n\nexport type GetWorkflowTypedOptions<W extends WorkflowLike = WorkflowLike> = {\n workflow: W;\n workspaceId?: string;\n profile?: string;\n};\n\n/**\n * Resolve a workflow definition by name.\n * @param client - Operator client\n * @param workspaceId - Workspace ID\n * @param name - Workflow name\n * @returns Resolved workflow\n */\nexport async function resolveWorkflow(\n client: Awaited<ReturnType<typeof initOperatorClient>>,\n workspaceId: string,\n name: string,\n) {\n const { workflow } = await client.getWorkflowByName({\n workspaceId,\n workflowName: name,\n });\n if (!workflow) {\n throw new Error(`Workflow '${name}' not found.`);\n }\n return workflow;\n}\n\n/**\n * Get a workflow by name and return CLI-friendly info.\n * @param options - Workflow lookup options\n * @returns Workflow information\n */\nexport async function getWorkflow<W extends WorkflowLike>(\n options: GetWorkflowTypedOptions<W>,\n): Promise<WorkflowInfo> {\n const name = options.workflow.name;\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n try {\n const workflow = await resolveWorkflow(client, workspaceId, name);\n return toWorkflowInfo(workflow);\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`Workflow '${name}' not found.`, { cause: error });\n }\n throw error;\n }\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Get workflow details.\",\n args: z.strictObject({\n ...workspaceArgs,\n ...nameArgs,\n }),\n run: async (args) => {\n const workflow = await getWorkflow({\n workflow: { name: args.name },\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n\n logger.out(workflow);\n },\n});\n","import { create } from \"@bufbuild/protobuf\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { AuthInvokerSchema } from \"@tailor-platform/tailor-proto/auth_resource_pb\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport {\n deploymentArgs,\n parseDuration,\n resolveMachineUserInputSource,\n type MachineUserInputSource,\n} from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadMachineUserName, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { nameArgs, waitArgs } from \"./args\";\nimport { getWorkflowExecution, printExecutionWithLogs } from \"./executions\";\nimport { resolveWorkflow } from \"./get\";\nimport { type WorkflowWaitUntil } from \"./status\";\nimport {\n getWorkflowWaitFailureMessage,\n waitForWorkflowExecution,\n type WorkflowWaitResult,\n} from \"./waiter\";\n// Import from the public entry (not `@/types/auth`) so the `./cli` d.ts references\n// `@tailor-platform/sdk` externally instead of inlining the registry — a single\n// generated `declare module \"@tailor-platform/sdk\"` then narrows both entries.\nimport type { MachineUserName } from \"@tailor-platform/sdk\";\nimport type { Jsonifiable } from \"type-fest\";\n\ntype WorkflowLike = {\n name: string;\n mainJob: {\n body: unknown;\n };\n};\n\ntype WorkflowInvoker<M extends string = string> = {\n namespace: string;\n machineUserName: M;\n};\n\ntype WorkflowInput<W extends WorkflowLike> = W extends WorkflowLike\n ? W[\"mainJob\"][\"body\"] extends (...args: infer Args) => unknown\n ? Args[0]\n : never\n : never;\n\ntype StartWorkflowArgOptionForSingleWorkflow<W extends WorkflowLike> = WorkflowLike extends W\n ? { arg?: Jsonifiable }\n : undefined extends WorkflowInput<W>\n ? { arg?: WorkflowInput<W> }\n : { arg: WorkflowInput<W> };\n\ntype StartWorkflowArgOption<W extends WorkflowLike> = W extends WorkflowLike\n ? StartWorkflowArgOptionForSingleWorkflow<W>\n : never;\n\ntype StartWorkflowByNameOptions = {\n name: string;\n machineUser?: string;\n arg?: Jsonifiable;\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n interval?: number;\n machineUserSource?: MachineUserInputSource;\n};\n\ntype StartWorkflowTypedBaseOptions<W extends WorkflowLike> = {\n workflow: W;\n invoker: MachineUserName;\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n interval?: number;\n};\n\nexport type StartWorkflowTypedOptions<W extends WorkflowLike = WorkflowLike> =\n W extends WorkflowLike ? StartWorkflowTypedBaseOptions<W> & StartWorkflowArgOption<W> : never;\n\nexport { waitForWorkflowExecution as waitForExecution };\n\nexport interface WaitOptions {\n showProgress?: boolean;\n timeout?: number;\n until?: WorkflowWaitUntil;\n}\n\nexport interface StartWorkflowResultWithWait {\n executionId: string;\n wait: (options?: WaitOptions) => Promise<WorkflowWaitResult>;\n}\n\ninterface StartWorkflowCoreOptions {\n client: Awaited<ReturnType<typeof initOperatorClient>>;\n workspaceId: string;\n workflowName: string;\n invoker: WorkflowInvoker<string>;\n arg?: unknown;\n interval?: number;\n}\n\nasync function startWorkflowCore(\n options: StartWorkflowCoreOptions,\n): Promise<StartWorkflowResultWithWait> {\n const { client, workspaceId, workflowName } = options;\n\n try {\n const workflow = await resolveWorkflow(client, workspaceId, workflowName);\n const invoker = create(AuthInvokerSchema, options.invoker);\n const arg =\n options.arg === undefined\n ? undefined\n : typeof options.arg === \"string\"\n ? options.arg\n : JSON.stringify(options.arg);\n\n const { executionId } = await client.testStartWorkflow({\n workspaceId,\n workflowId: workflow.id,\n authInvoker: invoker,\n arg,\n });\n\n return {\n executionId,\n wait: (waitOptions?: WaitOptions) =>\n waitForWorkflowExecution({\n client,\n workspaceId,\n executionId,\n interval: options.interval ?? 3000,\n timeout: waitOptions?.timeout,\n until: waitOptions?.until,\n showProgress: waitOptions?.showProgress,\n trackJobs: true,\n }),\n };\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`Workflow '${workflowName}' not found.`, { cause: error });\n }\n throw error;\n }\n}\n\nasync function resolveApplicationAuthNamespace(options: {\n client: Awaited<ReturnType<typeof initOperatorClient>>;\n workspaceId: string;\n configPath?: string;\n}): Promise<string> {\n const { config } = await loadConfig(options.configPath);\n const { application } = await options.client.getApplication({\n workspaceId: options.workspaceId,\n applicationName: config.name,\n });\n const authNamespace = application?.authNamespace || config.auth?.name;\n if (!authNamespace) {\n throw new Error(`Application ${config.name} does not have an auth configuration.`);\n }\n return authNamespace;\n}\n\n/**\n * Start a workflow looked up by name, resolving the machine user from the\n * flag, environment, or profile default. Backs the `workflow start` command;\n * programmatic callers use {@link startWorkflow} with a workflow definition.\n * @param options - Start options keyed by workflow name\n * @returns Start result with wait helper\n */\nexport async function startWorkflowByName(\n options: StartWorkflowByNameOptions,\n): Promise<StartWorkflowResultWithWait> {\n const machineUser = await loadMachineUserName({\n machineUser: options.machineUser,\n machineUserSource: options.machineUserSource,\n profile: options.profile,\n });\n if (!machineUser) {\n throw new Error(\n \"Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.\",\n );\n }\n\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n const authNamespace = await resolveApplicationAuthNamespace({\n client,\n workspaceId,\n configPath: options.configPath,\n });\n\n return await startWorkflowCore({\n client,\n workspaceId,\n workflowName: options.name,\n invoker: {\n namespace: authNamespace,\n machineUserName: machineUser,\n },\n arg: options.arg,\n interval: options.interval,\n });\n}\n\n/**\n * Start a workflow and return a handle to wait for completion.\n * @param options - Start options\n * @returns Start result with wait helper\n */\nexport async function startWorkflow<W extends WorkflowLike>(\n options: StartWorkflowTypedOptions<W>,\n): Promise<StartWorkflowResultWithWait> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n const authNamespace = await resolveApplicationAuthNamespace({\n client,\n workspaceId,\n configPath: options.configPath,\n });\n\n return await startWorkflowCore({\n client,\n workspaceId,\n workflowName: options.workflow.name,\n invoker: {\n namespace: authNamespace,\n machineUserName: options.invoker,\n },\n arg: options.arg,\n interval: options.interval,\n });\n}\n\nexport const startCommand = defineAppCommand({\n name: \"start\",\n description: \"Start a workflow execution.\",\n args: z.strictObject({\n ...deploymentArgs,\n ...nameArgs,\n \"machine-user\": arg(z.string().optional(), {\n alias: \"m\",\n description: \"Machine user name. Falls back to the active profile's default machine user.\",\n env: \"TAILOR_PLATFORM_MACHINE_USER_NAME\",\n }),\n arg: arg(z.string().optional(), {\n alias: \"a\",\n description: \"Workflow argument (JSON string)\",\n }),\n ...waitArgs,\n }),\n run: async (args) => {\n const { executionId, wait } = await startWorkflowByName({\n name: args.name,\n machineUser: args[\"machine-user\"],\n machineUserSource: resolveMachineUserInputSource(args[\"machine-user\"]),\n arg: args.arg,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n interval: parseDuration(args.interval),\n });\n const jsonOutput = logger.jsonMode;\n\n logger.info(`Execution ID: ${executionId}`, { mode: \"stream\" });\n\n if (args.wait) {\n const result = await wait({\n showProgress: !jsonOutput,\n timeout: parseDuration(args.timeout),\n until: args.until,\n });\n if (args.logs && !jsonOutput) {\n const { execution } = await getWorkflowExecution({\n executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n logs: true,\n });\n printExecutionWithLogs(execution);\n } else if (args.logs) {\n const { execution } = await getWorkflowExecution({\n executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n logs: true,\n });\n logger.out({ ...result, jobDetails: execution.jobDetails });\n } else {\n logger.out(result);\n }\n const failureMessage = getWorkflowWaitFailureMessage(result, args.until);\n if (failureMessage) {\n throw new Error(failureMessage);\n }\n } else {\n logger.out({ executionId });\n }\n },\n});\n","import { setTimeout } from \"timers/promises\";\nimport { create } from \"@bufbuild/protobuf\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n ExecutorJobStatus,\n ExecutorTargetType,\n} from \"@tailor-platform/tailor-proto/executor_resource_pb\";\nimport { FunctionExecution_Status } from \"@tailor-platform/tailor-proto/function_resource_pb\";\nimport {\n Condition_Operator,\n ConditionSchema,\n FilterSchema,\n PageDirection,\n} from \"@tailor-platform/tailor-proto/resource_pb\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport {\n durationArg,\n nonNegativeIntArg,\n type Order,\n pagedLogArgs,\n parseDuration,\n toPageDirection,\n workspaceArgs,\n} from \"#/cli/shared/args\";\nimport { fetchAll, fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { formatKeyValueTable } from \"#/cli/shared/format\";\nimport { functionExecutionStatusToString } from \"#/cli/shared/function-execution\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { spinner } from \"#/cli/shared/spinner\";\nimport { formatWaitError, isRetryableWaitError } from \"#/cli/shared/wait-error\";\nimport { getWorkflowExecution } from \"../workflow/executions\";\nimport { waitForExecution } from \"../workflow/start\";\nimport {\n classifyExecutorJobStatus,\n colorizeExecutorJobStatus,\n colorizeFunctionExecutionStatus,\n executorTargetTypeToString,\n isFunctionExecutionTerminalStatus,\n parseExecutorJobStatus,\n} from \"./status\";\nimport {\n type ExecutorJobListInfo,\n type ExecutorJobInfo,\n type ExecutorJobAttemptInfo,\n toExecutorJobListInfo,\n toExecutorJobInfo,\n toExecutorJobAttemptInfo,\n} from \"./transform\";\n\ntype ExecutorLike = {\n name: string;\n};\n\nexport type ListExecutorJobsTypedOptions<E extends ExecutorLike = ExecutorLike> = {\n executor: E;\n status?: string;\n order?: Order;\n limit?: number;\n workspaceId?: string;\n profile?: string;\n};\n\nexport type GetExecutorJobTypedOptions<E extends ExecutorLike = ExecutorLike> = {\n executor: E;\n jobId: string;\n attempts?: boolean;\n workspaceId?: string;\n profile?: string;\n};\n\nexport type WatchExecutorJobTypedOptions<E extends ExecutorLike = ExecutorLike> = {\n executor: E;\n jobId: string;\n workspaceId?: string;\n profile?: string;\n interval?: number;\n timeout?: number;\n logs?: boolean;\n showProgress?: boolean;\n};\n\nexport interface ExecutorJobDetailInfo extends ExecutorJobInfo {\n attempts?: ExecutorJobAttemptInfo[];\n}\n\nexport interface WorkflowJobLog {\n jobName: string;\n logs?: string;\n result?: string;\n}\n\nexport interface WatchExecutorJobResult {\n job: ExecutorJobDetailInfo;\n targetType: string;\n elapsedMs: number;\n attempts: number;\n timedOut: boolean;\n lastError: string | null;\n workflowExecutionId?: string;\n workflowStatus?: string;\n workflowJobLogs?: WorkflowJobLog[];\n functionExecutionId?: string;\n functionStatus?: string;\n functionLogs?: string;\n}\n\nfunction formatTime(date: Date): string {\n return date.toLocaleTimeString(\"en-US\", { hour12: false });\n}\n\nfunction createUnknownExecutorJob(executorName: string, jobId: string): ExecutorJobDetailInfo {\n return {\n id: jobId,\n executorName,\n status: \"UNKNOWN\",\n scheduledAt: \"N/A\",\n createdAt: \"N/A\",\n updatedAt: \"N/A\",\n };\n}\n\n/**\n * List executor jobs for a given executor.\n *\n * Returns at most `options.limit` items. When `limit` is omitted or 0 the\n * function pages through every job. The CLI caps this at 50 by default\n * via `pagedLogArgs`; programmatic callers that want the same cap should\n * pass `limit: 50` explicitly.\n * @param options - Options for listing executor jobs\n * @returns List of executor job information\n */\nexport async function listExecutorJobs<E extends ExecutorLike>(\n options: ListExecutorJobsTypedOptions<E>,\n): Promise<ExecutorJobListInfo[]> {\n const executorName = options.executor.name;\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n const filters: ReturnType<typeof create<typeof FilterSchema>>[] = [];\n\n if (options.status) {\n const statusValue = parseExecutorJobStatus(options.status);\n filters.push(\n create(FilterSchema, {\n condition: create(ConditionSchema, {\n field: \"status\",\n operator: Condition_Operator.EQ,\n value: { kind: { case: \"numberValue\", value: statusValue } },\n }),\n }),\n );\n }\n\n const filter = filters.length > 0 ? create(FilterSchema, { and: filters }) : undefined;\n\n const pageDirection = toPageDirection(options.order ?? \"desc\");\n\n try {\n const jobs = await fetchPaged(\n async (pageToken, pageSize) => {\n const { jobs, nextPageToken } = await client.listExecutorJobs({\n workspaceId,\n executorName,\n pageToken,\n pageSize,\n pageDirection,\n filter,\n });\n return [jobs, nextPageToken];\n },\n { limit: options.limit },\n );\n\n return jobs.map(toExecutorJobListInfo);\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`Executor '${executorName}' not found.`, { cause: error });\n }\n throw error;\n }\n}\n\n/**\n * Get details of a specific executor job.\n * @param options - Options for getting executor job details\n * @returns Executor job detail information\n */\nexport async function getExecutorJob<E extends ExecutorLike>(\n options: GetExecutorJobTypedOptions<E>,\n): Promise<ExecutorJobDetailInfo> {\n const executorName = options.executor.name;\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n try {\n const { job } = await client.getExecutorJob({\n workspaceId,\n executorName,\n jobId: options.jobId,\n });\n\n if (!job) {\n throw new Error(`Job '${options.jobId}' not found.`);\n }\n\n const jobInfo = toExecutorJobInfo(job);\n\n if (options.attempts) {\n const attempts = await fetchAll(async (pageToken, maxPageSize) => {\n const { attempts, nextPageToken } = await client.listExecutorJobAttempts({\n workspaceId,\n jobId: options.jobId,\n pageToken,\n pageSize: maxPageSize,\n pageDirection: PageDirection.DESC,\n });\n return [attempts, nextPageToken];\n });\n\n return {\n ...jobInfo,\n attempts: attempts.map(toExecutorJobAttemptInfo),\n };\n }\n\n return jobInfo;\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`Job '${options.jobId}' not found for executor '${executorName}'.`, {\n cause: error,\n });\n }\n throw error;\n }\n}\n\n/**\n * Watch an executor job until completion, including downstream executions.\n * @param options - Options for watching executor job\n * @returns Result including job details and downstream execution info\n */\nexport async function watchExecutorJob<E extends ExecutorLike>(\n options: WatchExecutorJobTypedOptions<E>,\n): Promise<WatchExecutorJobResult> {\n const executorName = options.executor.name;\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n const interval = options.interval ?? 3000;\n const timeout = options.timeout;\n const showProgress = options.showProgress ?? !logger.jsonMode;\n const startedAt = Date.now();\n const sp = showProgress ? spinner().start(\"Waiting for executor job to complete...\") : null;\n\n let attempts = 0;\n let lastError: string | null = null;\n\n type WatchExecutorJobResultBase = Omit<\n WatchExecutorJobResult,\n \"elapsedMs\" | \"attempts\" | \"timedOut\" | \"lastError\"\n >;\n\n const remainingTimeout = (): number | undefined => {\n if (timeout === undefined) {\n return undefined;\n }\n return timeout - (Date.now() - startedAt);\n };\n\n const withWaitMetadata = (\n result: WatchExecutorJobResultBase,\n timedOut: boolean,\n ): WatchExecutorJobResult => ({\n ...result,\n elapsedMs: Date.now() - startedAt,\n attempts,\n timedOut,\n lastError,\n });\n\n const timeoutResult = (\n targetType: string,\n job: Awaited<ReturnType<typeof client.getExecutorJob>>[\"job\"],\n ): WatchExecutorJobResult =>\n withWaitMetadata(\n {\n job: job ? toExecutorJobInfo(job) : createUnknownExecutorJob(executorName, options.jobId),\n targetType,\n },\n true,\n );\n\n try {\n // Get executor details to determine target type\n const { executor } = await client.getExecutorExecutor({\n workspaceId,\n name: executorName,\n });\n\n if (!executor) {\n throw new Error(`Executor '${executorName}' not found.`);\n }\n\n const targetType = executor.targetType;\n const targetTypeStr = executorTargetTypeToString(targetType);\n\n // Phase 1: Wait for executor job to complete\n let job: Awaited<ReturnType<typeof client.getExecutorJob>>[\"job\"];\n // loop exits when the executor job reaches a terminal status\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const remainingMs = remainingTimeout();\n if (remainingMs !== undefined && remainingMs <= 0) {\n sp?.fail(\"Executor job wait timed out.\");\n return timeoutResult(targetTypeStr, job);\n }\n\n try {\n attempts += 1;\n const response = await client.getExecutorJob({\n workspaceId,\n executorName,\n jobId: options.jobId,\n });\n\n job = response.job;\n if (!job) {\n throw new Error(`Job '${options.jobId}' not found.`);\n }\n lastError = null;\n\n if (classifyExecutorJobStatus(job.status) !== \"transient\") {\n break;\n }\n } catch (error) {\n if (!isRetryableWaitError(error)) {\n throw error;\n }\n lastError = formatWaitError(error);\n if (sp) {\n sp.text = `Retrying executor job poll... (${formatTime(new Date())})`;\n }\n }\n\n const nextRemainingMs = remainingTimeout();\n if (nextRemainingMs !== undefined && nextRemainingMs <= 0) {\n sp?.fail(\"Executor job wait timed out.\");\n return timeoutResult(targetTypeStr, job);\n }\n\n if (sp) {\n sp.text = `Waiting for executor job... (${formatTime(new Date())})`;\n }\n await setTimeout(\n nextRemainingMs === undefined ? interval : Math.min(interval, nextRemainingMs),\n );\n }\n\n const jobInfo = toExecutorJobInfo(job);\n const coloredStatus = colorizeExecutorJobStatus(jobInfo.status);\n\n if (job.status === ExecutorJobStatus.SUCCESS) {\n sp?.succeed(`Executor job completed: ${coloredStatus}`);\n } else {\n sp?.fail(`Executor job completed: ${coloredStatus}`);\n }\n\n // Get attempts to find operationReference\n const attemptRecords = await fetchAll(async (pageToken, maxPageSize) => {\n const { attempts: jobAttempts, nextPageToken } = await client.listExecutorJobAttempts({\n workspaceId,\n jobId: options.jobId,\n pageToken,\n pageSize: maxPageSize,\n pageDirection: PageDirection.DESC,\n });\n return [jobAttempts, nextPageToken];\n });\n\n const attemptInfos = attemptRecords.map(toExecutorJobAttemptInfo);\n const jobDetail: ExecutorJobDetailInfo = {\n ...jobInfo,\n attempts: attemptInfos,\n };\n\n const latestAttempt = attemptInfos[0];\n const operationReference = latestAttempt?.operationReference;\n\n // Phase 2: Based on target type, wait for the downstream execution\n if (operationReference) {\n switch (targetType) {\n case ExecutorTargetType.WORKFLOW: {\n // Wait for workflow execution with progress display\n sp?.stop();\n\n try {\n const workflowTimeout = remainingTimeout();\n if (workflowTimeout !== undefined && workflowTimeout <= 0) {\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n workflowExecutionId: operationReference,\n },\n true,\n );\n }\n\n // Use waitForExecution with progress display (same as workflow start)\n const executionResult = await waitForExecution({\n client,\n workspaceId,\n executionId: operationReference,\n interval,\n timeout: workflowTimeout,\n showProgress,\n trackJobs: true,\n });\n attempts += executionResult.attempts;\n lastError = executionResult.lastError;\n\n // Fetch logs if requested\n let workflowJobLogs: WorkflowJobLog[] | undefined;\n if (options.logs) {\n try {\n const { execution: execWithLogs } = await getWorkflowExecution({\n executionId: operationReference,\n workspaceId: options.workspaceId,\n profile: options.profile,\n logs: true,\n });\n if (execWithLogs.jobDetails) {\n workflowJobLogs = execWithLogs.jobDetails\n .filter((job) => job.logs || job.result)\n .map((job) => ({\n jobName: job.stackedJobName || job.id,\n logs: job.logs,\n result: job.result,\n }));\n }\n } catch (error) {\n logger.warn(\n `Could not fetch workflow execution logs: ${error instanceof Error ? error.message : error}`,\n );\n }\n }\n\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n workflowExecutionId: operationReference,\n workflowStatus: executionResult.status,\n workflowJobLogs,\n },\n executionResult.timedOut,\n );\n } catch (error) {\n logger.warn(\n `Could not track workflow execution: ${error instanceof Error ? error.message : error}`,\n );\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n workflowExecutionId: operationReference,\n },\n false,\n );\n }\n }\n\n case ExecutorTargetType.FUNCTION:\n case ExecutorTargetType.JOB_FUNCTION:\n {\n // Wait for function execution\n sp?.start(`Waiting for function execution ${operationReference}...`);\n\n try {\n let functionStatus: string | undefined;\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const functionTimeout = remainingTimeout();\n if (functionTimeout !== undefined && functionTimeout <= 0) {\n sp?.fail(\"Function execution wait timed out.\");\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n functionExecutionId: operationReference,\n functionStatus,\n },\n true,\n );\n }\n\n try {\n attempts += 1;\n const { execution } = await client.getFunctionExecution({\n workspaceId,\n executionId: operationReference,\n });\n\n if (!execution) {\n throw new Error(`Function execution '${operationReference}' not found.`);\n }\n\n lastError = null;\n functionStatus = functionExecutionStatusToString(execution.status);\n\n if (isFunctionExecutionTerminalStatus(execution.status)) {\n const coloredFnStatus = colorizeFunctionExecutionStatus(functionStatus);\n if (execution.status === FunctionExecution_Status.SUCCESS) {\n sp?.succeed(`Function execution completed: ${coloredFnStatus}`);\n } else {\n sp?.fail(`Function execution completed: ${coloredFnStatus}`);\n }\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n functionExecutionId: operationReference,\n functionStatus,\n functionLogs: options.logs ? execution.logs || undefined : undefined,\n },\n false,\n );\n }\n } catch (error) {\n if (!isRetryableWaitError(error)) {\n throw error;\n }\n lastError = formatWaitError(error);\n if (sp) {\n sp.text = `Retrying function execution poll... (${formatTime(new Date())})`;\n }\n }\n\n const nextFunctionTimeout = remainingTimeout();\n if (nextFunctionTimeout !== undefined && nextFunctionTimeout <= 0) {\n sp?.fail(\"Function execution wait timed out.\");\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n functionExecutionId: operationReference,\n functionStatus,\n },\n true,\n );\n }\n\n if (sp) {\n sp.text = `Waiting for function execution... (${formatTime(new Date())})`;\n }\n await setTimeout(\n nextFunctionTimeout === undefined\n ? interval\n : Math.min(interval, nextFunctionTimeout),\n );\n }\n } catch (error) {\n sp?.warn(\n `Could not track function execution: ${error instanceof Error ? error.message : error}`,\n );\n return withWaitMetadata(\n {\n job: jobDetail,\n targetType: targetTypeStr,\n functionExecutionId: operationReference,\n },\n false,\n );\n }\n }\n break;\n default:\n // WEBHOOK, TAILOR_GRAPHQL, or unknown - no downstream execution to track\n break;\n }\n }\n\n return withWaitMetadata({ job: jobDetail, targetType: targetTypeStr }, false);\n } finally {\n sp?.stop();\n }\n}\n\n/**\n * Build a user-facing failure message for an executor job wait result.\n * @param result - Executor job wait result\n * @returns Failure message, or undefined when the wait succeeded\n */\nexport function getExecutorWaitFailureMessage(result: WatchExecutorJobResult): string | undefined {\n if (result.timedOut) {\n return `Timed out waiting for executor job '${result.job.id}'. Last status: ${result.job.status}.`;\n }\n if (result.job.status === \"FAILED\" || result.job.status === \"CANCELED\") {\n return `Executor job '${result.job.id}' completed with status ${result.job.status}.`;\n }\n if (result.workflowStatus === \"FAILED\") {\n return `Workflow execution '${result.workflowExecutionId}' failed.`;\n }\n if (result.functionStatus === \"FAILED\") {\n return `Function execution '${result.functionExecutionId}' failed.`;\n }\n return undefined;\n}\n\nfunction printJobWithAttempts(job: ExecutorJobDetailInfo): void {\n // Print job summary\n const summaryData: [string, string][] = [\n [\"id\", job.id],\n [\"executorName\", job.executorName],\n [\"status\", job.status],\n [\"scheduledAt\", job.scheduledAt],\n [\"createdAt\", job.createdAt],\n [\"updatedAt\", job.updatedAt],\n ];\n logger.log(formatKeyValueTable(summaryData));\n\n // Print attempts\n if (job.attempts && job.attempts.length > 0) {\n logger.log(styles.bold(\"\\nAttempts:\"));\n for (const attempt of job.attempts) {\n logger.log(styles.info(`\\n--- Attempt ${attempt.id} ---`));\n logger.log(` Status: ${attempt.status}`);\n logger.log(` Started: ${attempt.startedAt}`);\n logger.log(` Finished: ${attempt.finishedAt}`);\n\n if (attempt.error) {\n logger.log(styles.error(\"\\n Error:\"));\n const errorLines = attempt.error.split(\"\\n\");\n for (const line of errorLines) {\n logger.log(` ${line}`);\n }\n }\n }\n }\n}\n\nexport const jobsCommand = defineAppCommand({\n name: \"jobs\",\n description: \"List or get executor jobs.\",\n examples: [\n {\n cmd: \"my-executor\",\n desc: \"List jobs for an executor (default: 50 jobs)\",\n },\n { cmd: \"my-executor --limit 10\", desc: \"Limit the number of jobs\" },\n { cmd: \"my-executor -s RUNNING\", desc: \"Filter by status\" },\n { cmd: \"my-executor <job-id>\", desc: \"Get job details\" },\n {\n cmd: \"my-executor <job-id> --attempts\",\n desc: \"Get job details with attempts\",\n },\n { cmd: \"my-executor <job-id> -W\", desc: \"Wait for job to complete\" },\n {\n cmd: \"my-executor <job-id> -W -l\",\n desc: \"Wait for job with logs\",\n },\n ],\n args: z.strictObject({\n ...workspaceArgs,\n \"executor-name\": arg(z.string(), {\n positional: true,\n description: \"Executor name\",\n }),\n \"job-id\": arg(z.string().optional(), {\n positional: true,\n description: \"Job ID (if provided, shows job details)\",\n }),\n status: arg(z.string().optional(), {\n alias: \"s\",\n description:\n \"Filter by status (PENDING, RUNNING, SUCCESS, FAILED, CANCELED) (list mode only)\",\n }),\n attempts: arg(z.boolean().default(false), {\n description: \"Show job attempts (only with job ID) (detail mode only)\",\n }),\n wait: arg(z.boolean().default(false), {\n alias: \"W\",\n description:\n \"Wait for job completion and downstream execution (workflow/function) if applicable (detail mode only)\",\n }),\n interval: arg(durationArg.default(\"3s\"), {\n alias: \"i\",\n description: \"Polling interval when using --wait (e.g., '3s', '500ms', '1m')\",\n }),\n timeout: arg(durationArg.default(\"5m\"), {\n alias: \"t\",\n description: \"Maximum time to wait when using --wait (e.g., '30s', '5m')\",\n }),\n ...pagedLogArgs,\n limit: arg(nonNegativeIntArg.default(50), {\n description: \"Maximum number of jobs to list (0: unlimited, default: 50) (list mode only)\",\n }),\n logs: arg(z.boolean().default(false), {\n alias: \"l\",\n description: \"Display function execution logs after completion (requires --wait)\",\n }),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode || args.json;\n if (args.jobId) {\n if (args.wait) {\n const result = await watchExecutorJob({\n executor: { name: args.executorName },\n jobId: args.jobId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval: parseDuration(args.interval),\n timeout: parseDuration(args.timeout),\n logs: args.logs,\n showProgress: !jsonOutput,\n });\n\n // Print result\n if (!jsonOutput) {\n logger.log(styles.bold(`Target Type: ${result.targetType}\\n`));\n printJobWithAttempts(result.job);\n if (result.workflowExecutionId) {\n logger.log(styles.bold(\"\\nWorkflow Execution:\"));\n logger.log(` ID: ${result.workflowExecutionId}`);\n if (result.workflowStatus) {\n logger.log(` Status: ${result.workflowStatus}`);\n }\n if (result.workflowJobLogs && result.workflowJobLogs.length > 0) {\n for (const jobLog of result.workflowJobLogs) {\n logger.log(styles.bold(`\\n Job: ${jobLog.jobName}`));\n if (jobLog.logs) {\n logger.log(styles.dim(\" Logs:\"));\n for (const line of jobLog.logs.split(\"\\n\")) {\n logger.log(` ${line}`);\n }\n }\n if (jobLog.result) {\n logger.log(styles.dim(\" Result:\"));\n try {\n const parsed = JSON.parse(jobLog.result);\n const formatted = JSON.stringify(parsed, null, 2);\n for (const line of formatted.split(\"\\n\")) {\n logger.log(` ${line}`);\n }\n } catch {\n logger.log(` ${jobLog.result}`);\n }\n }\n }\n }\n }\n if (result.functionExecutionId) {\n logger.log(styles.bold(\"\\nFunction Execution:\"));\n logger.log(` ID: ${result.functionExecutionId}`);\n if (result.functionStatus) {\n logger.log(` Status: ${result.functionStatus}`);\n }\n if (result.functionLogs) {\n logger.log(styles.dim(\" Logs:\"));\n for (const line of result.functionLogs.split(\"\\n\")) {\n logger.log(` ${line}`);\n }\n }\n }\n } else {\n logger.out(result);\n }\n const failureMessage = getExecutorWaitFailureMessage(result);\n if (failureMessage) {\n throw new Error(failureMessage);\n }\n return;\n }\n\n const job = await getExecutorJob({\n executor: { name: args.executorName },\n jobId: args.jobId,\n attempts: args.attempts,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n if (args.attempts && !jsonOutput) {\n printJobWithAttempts(job);\n } else {\n logger.out(job);\n }\n } else {\n if (args.wait) {\n logger.warn(\"--wait flag is ignored in list mode. Specify a job ID to wait.\");\n }\n const jobs = await listExecutorJobs({\n executor: { name: args.executorName },\n status: args.status,\n order: args.order,\n limit: args.limit,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n logger.out(jobs);\n }\n },\n});\n","import { z } from \"zod\";\nimport { type Order, paginationArgs, toPageDirection, workspaceArgs } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { type ExecutorListInfo, toExecutorListInfo } from \"./transform\";\n\nexport interface ListExecutorsOptions {\n workspaceId?: string;\n profile?: string;\n order?: Order;\n limit?: number;\n}\n\n/**\n * List executors in the workspace and return CLI-friendly info.\n * @param options - Executor listing options\n * @returns List of executors\n */\nexport async function listExecutors(options?: ListExecutorsOptions): Promise<ExecutorListInfo[]> {\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n const pageDirection = toPageDirection(options?.order);\n const executors = await fetchPaged(\n async (pageToken, pageSize) => {\n const { executors, nextPageToken } = await client.listExecutorExecutors({\n workspaceId,\n pageToken,\n pageSize,\n pageDirection,\n });\n return [executors, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return executors.map((e) => toExecutorListInfo(e));\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all executors\",\n args: z.strictObject({\n ...workspaceArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode;\n const executors = await listExecutors({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n order: args.order,\n limit: args.limit,\n });\n\n if (executors.length === 0) {\n logger.info(\"No executors found.\");\n if (jsonOutput) {\n logger.out([]);\n }\n return;\n }\n\n logger.out(executors, {\n display: {\n disabled: (v) => (v ? styles.warning(\"true\") : styles.dim(\"false\")),\n },\n });\n\n // Show hint if there are webhook executors (non-JSON mode only)\n if (!jsonOutput) {\n const hasWebhook = executors.some((e) => e.triggerType === \"webhook\");\n if (hasWebhook) {\n logger.info(\"To see webhook URLs, run: tailor executor webhook list\");\n }\n }\n },\n});\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { ExecutorTriggerType } from \"@tailor-platform/tailor-proto/executor_resource_pb\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { durationArg, parseDuration, workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { getExecutorWaitFailureMessage, watchExecutorJob } from \"./jobs\";\nimport { executorTriggerTypeToString } from \"./status\";\nimport type { IncomingWebhookTrigger, ScheduleTriggerInput } from \"#/types/executor.generated\";\nimport type { JsonObject } from \"@bufbuild/protobuf\";\n\n/**\n * Schema for JSON string validation (object only)\n * Transforms the string to a parsed object\n */\nconst jsonDataArg = z\n .string()\n .transform((val) => {\n try {\n return JSON.parse(val) as unknown;\n } catch {\n throw new Error(`Invalid JSON data: ${val}. Please provide a valid JSON string.`);\n }\n })\n .refine((v): v is JsonObject => typeof v === \"object\" && v !== null && !Array.isArray(v), {\n message: \"JSON data must be an object, not an array or primitive value\",\n });\n\n/**\n * Schema for header string validation (format: \"Key: Value\")\n * Transforms the string to an object with key and value properties\n */\nconst headerArg = z\n .string()\n .superRefine((val, ctx) => {\n if (!val.includes(\":\")) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid header format: '${val}'. Expected format: 'Key: Value'`,\n });\n }\n })\n .transform((val) => {\n const colonIndex = val.indexOf(\":\");\n return {\n key: val.slice(0, colonIndex).trim(),\n value: val.slice(colonIndex + 1).trim(),\n };\n })\n .refine((h) => h.key.length > 0, {\n message: \"Header name cannot be empty\",\n });\n\ntype ManualTrigger = IncomingWebhookTrigger | ScheduleTriggerInput;\n\ntype ManualTriggerExecutor<T extends ManualTrigger = ManualTrigger> = T extends ManualTrigger\n ? {\n name: string;\n trigger: T;\n }\n : never;\n\ntype TriggerExecutorBaseOptions<E extends ManualTriggerExecutor> = {\n executor: E;\n workspaceId?: string;\n profile?: string;\n};\n\ninterface TriggerExecutorByNameOptions {\n executorName: string;\n payload?: JsonObject;\n workspaceId?: string;\n profile?: string;\n}\n\nexport type TriggerExecutorTypedOptions<E extends ManualTriggerExecutor = ManualTriggerExecutor> =\n E extends ManualTriggerExecutor<IncomingWebhookTrigger>\n ? TriggerExecutorBaseOptions<E> & { payload?: JsonObject }\n : TriggerExecutorBaseOptions<E> & { payload?: never };\n\nexport interface TriggerExecutorResult {\n jobId?: string;\n}\n\nasync function triggerExecutorByName(\n options: TriggerExecutorByNameOptions,\n): Promise<TriggerExecutorResult> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n try {\n const response = await client.triggerExecutor({\n workspaceId,\n executorName: options.executorName,\n payload: options.payload,\n });\n\n return { jobId: response.jobId };\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`Executor '${options.executorName}' not found.`, { cause: error });\n }\n if (error instanceof ConnectError && error.code === Code.InvalidArgument) {\n throw new Error(`Invalid argument: ${error.message}`, { cause: error });\n }\n throw error;\n }\n}\n\n/**\n * Trigger an executor and return the job ID.\n * @param options - Options for triggering executor\n * @returns Result containing the job ID if available\n */\nexport async function triggerExecutor<E extends ManualTriggerExecutor>(\n options: TriggerExecutorTypedOptions<E>,\n): Promise<TriggerExecutorResult> {\n if (options.executor.trigger.kind !== \"incomingWebhook\" && options.payload !== undefined) {\n throw new Error(\n `Executor '${options.executor.name}' has '${options.executor.trigger.kind}' trigger type. ` +\n `The payload is only available for 'incomingWebhook' trigger type.`,\n );\n }\n\n return await triggerExecutorByName({\n executorName: options.executor.name,\n payload: options.payload,\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n}\n\nexport const triggerCommand = defineAppCommand({\n name: \"trigger\",\n description: \"Trigger an executor manually.\",\n notes: `Only executors with \\`INCOMING_WEBHOOK\\` or \\`SCHEDULE\\` trigger types can be triggered manually.\nExecutors with \\`EVENT\\` trigger types (such as \\`recordCreated\\`, \\`recordUpdated\\`, \\`recordDeleted\\`) cannot be triggered manually.\n\nThe \\`--data\\` and \\`--header\\` options are only available for \\`INCOMING_WEBHOOK\\` trigger type.\n\n**Downstream Execution Tracking**\n\nWhen using \\`--wait\\`, the CLI tracks not only the executor job but also any downstream executions:\n\n- **Workflow targets**: Waits for the workflow execution to complete (SUCCESS, FAILED, or PENDING_RESUME). Shows real-time status changes and currently running job names during execution (same output as \\`workflow start --wait\\`).\n- **Function targets**: Waits for the function execution to complete\n- **Webhook/GraphQL targets**: Only waits for the executor job itself\n\nThe \\`--logs\\` option displays logs from the downstream execution when available.`,\n examples: [\n { cmd: \"my-executor\", desc: \"Trigger an executor\" },\n {\n cmd: 'my-executor -d \\'{\"message\": \"hello\"}\\'',\n desc: \"Trigger with data\",\n },\n {\n cmd: 'my-executor -d \\'{\"message\": \"hello\"}\\' -H \"X-Custom: value\" -H \"X-Another: value2\"',\n desc: \"Trigger with data and headers\",\n },\n { cmd: \"my-executor -W\", desc: \"Trigger and wait for completion\" },\n { cmd: \"my-executor -W -l\", desc: \"Trigger, wait, and show logs\" },\n ],\n args: z.strictObject({\n ...workspaceArgs,\n \"executor-name\": arg(z.string(), {\n positional: true,\n description: \"Executor name\",\n }),\n data: arg(jsonDataArg.optional(), {\n alias: \"d\",\n description: \"Request body (JSON string)\",\n }),\n header: arg(headerArg.array().optional(), {\n alias: \"H\",\n overrideBuiltinAlias: true,\n description: \"Request header (format: 'Key: Value', can be specified multiple times)\",\n }),\n wait: arg(z.boolean().default(false), {\n alias: \"W\",\n description:\n \"Wait for job completion and downstream execution (workflow/function) if applicable\",\n }),\n interval: arg(durationArg.default(\"3s\"), {\n alias: \"i\",\n description: \"Polling interval when using --wait (e.g., '3s', '500ms', '1m')\",\n }),\n timeout: arg(durationArg.default(\"5m\"), {\n alias: \"t\",\n description: \"Maximum time to wait when using --wait (e.g., '30s', '5m')\",\n }),\n logs: arg(z.boolean().default(false), {\n alias: \"l\",\n description: \"Display function execution logs after completion (requires --wait)\",\n }),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode || args.json;\n await assertWritable({ profile: args.profile });\n // Validate trigger type before processing\n const accessToken = await loadAccessToken({\n profile: args.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n\n const { executor } = await client.getExecutorExecutor({\n workspaceId,\n name: args.executorName,\n });\n\n if (!executor) {\n throw new Error(`Executor '${args.executorName}' not found.`);\n }\n\n // EVENT trigger type cannot be triggered manually\n if (executor.triggerType === ExecutorTriggerType.EVENT) {\n throw new Error(\n `Executor '${args.executorName}' has '${executorTriggerTypeToString(executor.triggerType)}' trigger type and cannot be triggered manually. ` +\n `Only executors with 'INCOMING_WEBHOOK' or 'SCHEDULE' triggers can be triggered manually.`,\n );\n }\n\n // SCHEDULE trigger type does not accept --data or --header options\n if (executor.triggerType === ExecutorTriggerType.SCHEDULE && (args.data || args.header)) {\n throw new Error(\n `Executor '${args.executorName}' has 'SCHEDULE' trigger type. ` +\n `The --data and --header options are only available for 'INCOMING_WEBHOOK' trigger type.`,\n );\n }\n\n let payload: JsonObject | undefined;\n\n // Build payload if data or headers are provided\n const body: JsonObject | undefined = args.data;\n const headers: Record<string, string> = {};\n if (args.header) {\n for (const h of args.header) {\n headers[h.key] = h.value;\n }\n }\n\n if (body !== undefined || Object.keys(headers).length > 0) {\n payload = {\n body: body ?? {},\n headers,\n };\n }\n\n const result = await triggerExecutorByName({\n executorName: args.executorName,\n payload,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n\n if (!result.jobId) {\n logger.success(`Executor '${args.executorName}' triggered successfully.`);\n if (args.wait) {\n logger.warn(\"Cannot watch: job ID not available. The API may need to be updated.\");\n }\n return;\n }\n\n logger.success(\n `Executor '${args.executorName}' triggered successfully. Job ID: ${result.jobId}`,\n );\n\n if (args.wait) {\n const watchResult = await watchExecutorJob({\n executor: { name: args.executorName },\n jobId: result.jobId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval: parseDuration(args.interval),\n timeout: parseDuration(args.timeout),\n logs: args.logs,\n showProgress: !jsonOutput,\n });\n\n // Print result\n if (!jsonOutput) {\n logger.log(styles.bold(`\\nTarget Type: ${watchResult.targetType}`));\n logger.log(`Job Status: ${watchResult.job.status}`);\n\n if (watchResult.workflowExecutionId) {\n logger.log(styles.bold(\"\\nWorkflow Execution:\"));\n logger.log(` ID: ${watchResult.workflowExecutionId}`);\n if (watchResult.workflowStatus) {\n logger.log(` Status: ${watchResult.workflowStatus}`);\n }\n if (watchResult.workflowJobLogs && watchResult.workflowJobLogs.length > 0) {\n for (const jobLog of watchResult.workflowJobLogs) {\n logger.log(styles.bold(`\\n Job: ${jobLog.jobName}`));\n if (jobLog.logs) {\n logger.log(styles.dim(\" Logs:\"));\n for (const line of jobLog.logs.split(\"\\n\")) {\n logger.log(` ${line}`);\n }\n }\n if (jobLog.result) {\n logger.log(styles.dim(\" Result:\"));\n try {\n const parsed = JSON.parse(jobLog.result);\n const formatted = JSON.stringify(parsed, null, 2);\n for (const line of formatted.split(\"\\n\")) {\n logger.log(` ${line}`);\n }\n } catch {\n logger.log(` ${jobLog.result}`);\n }\n }\n }\n }\n }\n if (watchResult.functionExecutionId) {\n logger.log(styles.bold(\"\\nFunction Execution:\"));\n logger.log(` ID: ${watchResult.functionExecutionId}`);\n if (watchResult.functionStatus) {\n logger.log(` Status: ${watchResult.functionStatus}`);\n }\n if (watchResult.functionLogs) {\n logger.log(styles.dim(\" Logs:\"));\n for (const line of watchResult.functionLogs.split(\"\\n\")) {\n logger.log(` ${line}`);\n }\n }\n }\n } else {\n logger.out(watchResult);\n }\n const failureMessage = getExecutorWaitFailureMessage(watchResult);\n if (failureMessage) {\n throw new Error(failureMessage);\n }\n }\n },\n});\n","import { defineCommand, runCommand } from \"politty\";\nimport { z } from \"zod\";\nimport { type Order, paginationArgs, toPageDirection, workspaceArgs } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger, styles } from \"#/cli/shared/logger\";\n\nexport interface WebhookExecutorInfo {\n name: string;\n webhookUrl: string;\n disabled: boolean;\n}\n\nexport interface ListWebhookExecutorsOptions {\n workspaceId?: string;\n profile?: string;\n order?: Order;\n limit?: number;\n}\n\n/**\n * List executors with incoming webhook triggers and return CLI-friendly info.\n * @param options - Listing options\n * @returns List of webhook executors with URLs\n */\nexport async function listWebhookExecutors(\n options?: ListWebhookExecutorsOptions,\n): Promise<WebhookExecutorInfo[]> {\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n const pageDirection = toPageDirection(options?.order);\n const webhooks = await fetchPaged(\n async (pageToken, pageSize) => {\n const { webhooks, nextPageToken } = await client.listExecutorIncomingWebhooks({\n workspaceId,\n pageToken,\n pageSize,\n pageDirection,\n });\n return [webhooks, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return webhooks.map((w) => ({\n name: w.executorName,\n webhookUrl: w.url,\n disabled: w.disabled,\n }));\n}\n\nconst listWebhookCommand = defineAppCommand({\n name: \"list\",\n description: \"List executors with incoming webhook triggers\",\n args: z.strictObject({\n ...workspaceArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode;\n const executors = await listWebhookExecutors({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n order: args.order,\n limit: args.limit,\n });\n\n if (executors.length === 0) {\n logger.info(\"No webhook executors found.\");\n if (jsonOutput) {\n logger.out([]);\n }\n return;\n }\n\n logger.out(executors, {\n display: {\n disabled: (v) => (v ? styles.warning(\"true\") : styles.dim(\"false\")),\n },\n });\n\n if (!jsonOutput) {\n logger.info('To test a webhook, run: tailor executor trigger <name> -d \\'{\"key\":\"value\"}\\'');\n }\n },\n});\n\nexport const webhookCommand = defineCommand({\n name: \"webhook\",\n description: \"Manage executor webhooks\",\n subCommands: {\n list: listWebhookCommand,\n },\n async run() {\n await runCommand(listWebhookCommand, []);\n },\n});\n","import { formatTimestamp } from \"#/cli/shared/format\";\nimport type { FunctionRegistry } from \"@tailor-platform/tailor-proto/function_registry_pb\";\n\nexport interface FunctionRegistryInfo {\n name: string;\n description: string;\n sizeBytes: string;\n contentHash: string;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\nexport const functionRegistryInfo = (fn: FunctionRegistry): FunctionRegistryInfo => {\n return {\n name: fn.name,\n description: fn.description,\n sizeBytes: fn.sizeBytes.toString(),\n contentHash: fn.contentHash,\n createdAt: formatTimestamp(fn.createdAt),\n updatedAt: formatTimestamp(fn.updatedAt),\n };\n};\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { functionRegistryInfo, type FunctionRegistryInfo } from \"./transform\";\n\n// strip unknown keys\nconst getFunctionRegistryOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n name: z.string().min(1, { message: \"name is required\" }),\n});\n\nexport type GetFunctionRegistryOptions = z.input<typeof getFunctionRegistryOptionsSchema>;\n\nasync function loadOptions(options: GetFunctionRegistryOptions) {\n const result = getFunctionRegistryOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n name: result.data.name,\n };\n}\n\n/**\n * Get a function registry by name.\n * @param options - Function registry get options\n * @returns Function registry info\n */\nexport async function getFunctionRegistry(\n options: GetFunctionRegistryOptions,\n): Promise<FunctionRegistryInfo> {\n const { client, workspaceId, name } = await loadOptions(options);\n\n const notFoundErrorMessage = `Function registry \"${name}\" not found.`;\n try {\n const response = await client.getFunctionRegistry({\n workspaceId,\n name,\n });\n\n if (!response.function) {\n throw new Error(notFoundErrorMessage);\n }\n\n return functionRegistryInfo(response.function);\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(notFoundErrorMessage, { cause: error });\n }\n throw error;\n }\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Get a function registry by name\",\n args: z.strictObject({\n ...workspaceArgs,\n name: arg(z.string(), {\n description: \"Function name\",\n alias: \"n\",\n }),\n }),\n run: async (args) => {\n const fn = await getFunctionRegistry({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n name: args.name,\n });\n\n const formatted = args.json\n ? fn\n : {\n ...fn,\n createdAt: humanizeRelativeTime(fn.createdAt),\n updatedAt: humanizeRelativeTime(fn.updatedAt),\n };\n\n logger.out(formatted);\n },\n});\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { z } from \"zod\";\nimport { type Order, paginationArgs, toPageDirection, workspaceArgs } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { functionRegistryInfo, type FunctionRegistryInfo } from \"./transform\";\n\n// strip unknown keys\nconst listFunctionRegistriesOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n order: z.enum([\"asc\", \"desc\"]).optional(),\n limit: z.coerce.number().int().nonnegative().optional(),\n});\n\nexport type ListFunctionRegistriesOptions = z.input<typeof listFunctionRegistriesOptionsSchema>;\n\nasync function loadOptions(options: ListFunctionRegistriesOptions) {\n const result = listFunctionRegistriesOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n order: result.data.order as Order | undefined,\n limit: result.data.limit,\n };\n}\n\n/**\n * List function registries in a workspace with optional pagination.\n * @param options - Function registry listing options\n * @returns List of function registries\n */\nexport async function listFunctionRegistries(\n options: ListFunctionRegistriesOptions,\n): Promise<FunctionRegistryInfo[]> {\n const { client, workspaceId, order, limit } = await loadOptions(options);\n const pageDirection = toPageDirection(order);\n\n const registries = await fetchPaged(\n async (pageToken, pageSize) => {\n try {\n const { functions, nextPageToken } = await client.listFunctionRegistries({\n workspaceId,\n pageToken,\n pageSize,\n sortBy: \"updated_at\",\n pageDirection,\n });\n return [functions, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n },\n { limit },\n );\n\n return registries.map(functionRegistryInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List function registries in a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode;\n const registries = await listFunctionRegistries({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n order: args.order,\n limit: args.limit,\n });\n\n const formatted = jsonOutput\n ? registries\n : registries.map(({ createdAt, updatedAt, ...rest }) => ({\n ...rest,\n createdAt: humanizeRelativeTime(createdAt),\n updatedAt: humanizeRelativeTime(updatedAt),\n }));\n\n logger.out(formatted);\n },\n});\n","import type { Application } from \"#/cli/services/application\";\nimport type { GeneratorAuthInput } from \"#/plugin/types\";\n\n/**\n * Build the auth input passed to generator plugins from an application's\n * auth service.\n * @param application - Application instance to read the auth service from\n * @returns Auth input for generator plugins, or undefined when the config has no auth\n */\nexport function getAuthInput(application: Application): GeneratorAuthInput | undefined {\n const authService = application.authService;\n if (!authService) return undefined;\n\n const authConfig = authService.config;\n const userProfile = authService.userProfile;\n return {\n name: authConfig.name,\n userProfile: userProfile\n ? {\n typeName: userProfile.type.name,\n namespace: userProfile.namespace,\n usernameField: userProfile.usernameField,\n }\n : undefined,\n machineUsers: authConfig.machineUsers,\n oauth2Clients: authConfig.oauth2Clients,\n idProvider: authConfig.idProvider,\n };\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport {\n defineApplication,\n generatePluginFilesIfNeeded,\n type Application,\n} from \"#/cli/services/application\";\nimport { createExecutorService } from \"#/cli/services/executor/service\";\nimport { assertUniqueLocalTailorDBTypeNames } from \"#/cli/services/tailordb/type-name-validation\";\nimport { getAuthInput } from \"#/cli/shared/auth-input\";\nimport { loadConfig, type LoadedConfig } from \"#/cli/shared/config-loader\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { generateUserTypes } from \"#/cli/shared/type-generator\";\nimport { withSpan } from \"#/cli/telemetry/index\";\nimport { PluginManager } from \"#/plugin/manager\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type { TypeSourceInfo, TailorDBType } from \"#/parser/service/tailordb/types\";\nimport type {\n GeneratorResult,\n TailorDBNamespaceData,\n ResolverNamespaceData,\n Plugin,\n PluginAttachment,\n} from \"#/plugin/types\";\nimport type { Executor } from \"#/types/executor.generated\";\nimport type { Resolver } from \"#/types/resolver.generated\";\nimport type { GenerateOptions } from \"./options\";\n\ntype TypeInfo = {\n types: Record<string, TailorDBType>;\n sourceInfo: TypeSourceInfo;\n pluginAttachments: ReadonlyMap<string, readonly PluginAttachment[]>;\n};\n\n/**\n * Generation manager type.\n */\nexport type GenerationManager = {\n readonly application: Application;\n readonly baseDir: string;\n readonly services: {\n tailordb: Record<string, TypeInfo>;\n resolver: Record<string, Record<string, Resolver>>;\n executor: Record<string, Executor>;\n };\n generate: () => Promise<void>;\n};\n\n/**\n * Creates a generation manager.\n * @param params - Parameters for creating the generation manager\n * @param params.application - Application instance to generate code for\n * @param params.config - Loaded configuration\n * @param params.pluginManager - Plugin manager for processing plugins\n * @returns GenerationManager instance\n */\nexport function createGenerationManager(params: {\n application: Application;\n config: LoadedConfig;\n pluginManager?: PluginManager;\n}): GenerationManager {\n const { application, config, pluginManager } = params;\n const baseDir = path.join(getDistDir(), \"generated\");\n fs.mkdirSync(baseDir, { recursive: true });\n\n const services: {\n tailordb: Record<string, TypeInfo>;\n resolver: Record<string, Record<string, Resolver>>;\n executor: Record<string, Executor>;\n } = { tailordb: {}, resolver: {}, executor: {} };\n\n // Get plugins that have generation hooks\n const generationPlugins = pluginManager?.getPluginsWithGenerationHooks() ?? [];\n\n // =========================================================================\n // Plugin phase-complete hook runner\n // =========================================================================\n\n /**\n * Build TailorDB namespace data array from loaded services.\n * @returns Array of TailorDB namespace data\n */\n function buildTailorDBData(): TailorDBNamespaceData[] {\n return Object.entries(services.tailordb).map(([namespace, info]) => ({\n namespace,\n types: info.types,\n sourceInfo: new Map(Object.entries(info.sourceInfo)),\n pluginAttachments: info.pluginAttachments,\n }));\n }\n\n /**\n * Build resolver namespace data array from loaded services.\n * @returns Array of resolver namespace data\n */\n function buildResolverData(): ResolverNamespaceData[] {\n return Object.entries(services.resolver).map(([namespace, resolvers]) => ({\n namespace,\n resolvers,\n }));\n }\n\n /**\n * Run a plugin's phase-complete hook and write any generated files.\n * @param plugin - Plugin to run the hook on\n * @param hookName - Name of the hook to call\n * @returns Promise that resolves when hook completes\n */\n async function runPluginPhaseHook(\n plugin: Plugin,\n hookName: \"onTailorDBReady\" | \"onResolverReady\" | \"onExecutorReady\",\n ): Promise<void> {\n const hook = plugin[hookName];\n if (!hook) return;\n\n const pluginBaseDir = path.join(baseDir, plugin.id);\n const auth = getAuthInput(application);\n const tailordb = buildTailorDBData();\n\n let result: GeneratorResult;\n\n switch (hookName) {\n case \"onTailorDBReady\":\n result = await assertDefined(\n plugin.onTailorDBReady,\n \"plugin.onTailorDBReady hook missing\",\n )({\n tailordb,\n auth,\n baseDir: pluginBaseDir,\n configPath: config.path,\n pluginConfig: plugin.pluginConfig,\n });\n break;\n case \"onResolverReady\":\n result = await assertDefined(\n plugin.onResolverReady,\n \"plugin.onResolverReady hook missing\",\n )({\n tailordb,\n resolvers: buildResolverData(),\n auth,\n baseDir: pluginBaseDir,\n configPath: config.path,\n pluginConfig: plugin.pluginConfig,\n });\n break;\n case \"onExecutorReady\":\n result = await assertDefined(\n plugin.onExecutorReady,\n \"plugin.onExecutorReady hook missing\",\n )({\n tailordb,\n resolvers: buildResolverData(),\n executors: { ...services.executor },\n auth,\n baseDir: pluginBaseDir,\n configPath: config.path,\n pluginConfig: plugin.pluginConfig,\n });\n break;\n }\n\n await writeGeneratedFiles(plugin.id, result);\n }\n\n /**\n * Run a specific generation-time hook for all plugins that implement it.\n * Each hook runs at its natural pipeline phase, ensuring outputs from earlier\n * phases are available when later phases load resolvers/executors.\n * @param hookName - Name of the hook to call\n */\n async function runPluginHook(\n hookName: \"onTailorDBReady\" | \"onResolverReady\" | \"onExecutorReady\",\n ): Promise<void> {\n const plugins = generationPlugins.filter((p) => p[hookName] != null);\n if (plugins.length === 0) return;\n const results = await Promise.allSettled(\n plugins.map(async (plugin) => {\n try {\n await runPluginPhaseHook(plugin, hookName);\n } catch (error) {\n logger.error(`Error processing plugin ${styles.bold(plugin.id)} (${hookName})`);\n logger.error(String(error));\n throw error;\n }\n }),\n );\n const failures = results.filter((r): r is PromiseRejectedResult => r.status === \"rejected\");\n if (failures.length > 0) {\n throw new AggregateError(failures.map((f) => f.reason));\n }\n }\n\n // =========================================================================\n // Shared file writing\n // =========================================================================\n\n /**\n * Write generated files to disk.\n * @param sourceId - Plugin ID for logging\n * @param result - Generation result containing files to write\n */\n async function writeGeneratedFiles(sourceId: string, result: GeneratorResult): Promise<void> {\n await Promise.all(\n result.files.map(async (file) => {\n fs.mkdirSync(path.dirname(file.path), { recursive: true });\n return new Promise<void>((resolve, reject) => {\n if (file.skipIfExists && fs.existsSync(file.path)) {\n const relativePath = path.relative(process.cwd(), file.path);\n logger.debug(`${sourceId} | skip existing: ${relativePath}`);\n return resolve();\n }\n\n fs.writeFile(file.path, file.content, (err) => {\n if (err) {\n const relativePath = path.relative(process.cwd(), file.path);\n logger.error(`Error writing file ${styles.bold(relativePath)}`);\n logger.error(String(err));\n reject(err);\n } else {\n const relativePath = path.relative(process.cwd(), file.path);\n logger.log(`${sourceId} | generate: ${styles.success(relativePath)}`);\n // Set executable permission if requested\n if (file.executable) {\n fs.chmod(file.path, 0o755, (chmodErr) => {\n if (chmodErr) {\n const relativePath = path.relative(process.cwd(), file.path);\n logger.error(\n `Error setting executable permission on ${styles.bold(relativePath)}`,\n );\n logger.error(String(chmodErr));\n reject(chmodErr);\n } else {\n resolve();\n }\n });\n } else {\n resolve();\n }\n }\n });\n });\n }),\n );\n }\n\n return {\n application,\n baseDir,\n services,\n\n async generate(): Promise<void> {\n logger.newline();\n logger.log(`Generation for application: ${styles.highlight(application.config.name)}`);\n\n const app = application;\n\n // Load TailorDB types (includes plugin-generated types)\n await withSpan(\"generate.loadTailorDBTypes\", async (span) => {\n span.setAttribute(\"generate.namespace_count\", app.tailorDBServices.length);\n for (const db of app.tailorDBServices) {\n const namespace = db.namespace;\n await withSpan(`generate.loadTypes.${namespace}`, async () => {\n try {\n await db.loadTypes();\n\n // Process namespace plugins after loading types\n // These plugins generate types without requiring a source type\n await db.processNamespacePlugins();\n\n services.tailordb[namespace] = {\n types: db.types,\n sourceInfo: db.typeSourceInfo,\n pluginAttachments: db.pluginAttachments,\n };\n } catch (error) {\n logger.error(`Error loading types for TailorDB service ${styles.bold(namespace)}`);\n logger.error(String(error));\n throw error;\n }\n });\n }\n try {\n assertUniqueLocalTailorDBTypeNames({\n tailorDBServices: app.tailorDBServices,\n });\n } catch (error) {\n logger.error(\"Error validating TailorDB type names\");\n logger.error(String(error));\n throw error;\n }\n });\n\n // Generate plugin type and executor files\n // This must happen after TailorDB types are loaded since plugins process during type loading\n const { pluginExecutorFiles, executorService } = await withSpan(\n \"generate.pluginFiles\",\n async () => {\n const pluginExecutorFiles = generatePluginFilesIfNeeded(\n pluginManager,\n app.tailorDBServices,\n config.path,\n );\n const executorService =\n app.executorService ??\n (pluginExecutorFiles.length > 0\n ? createExecutorService({ config: { files: [] }, baseDir: path.dirname(config.path) })\n : undefined);\n return { pluginExecutorFiles, executorService };\n },\n );\n\n // Resolve Auth namespaces (depends on TailorDB)\n if (app.authService) {\n const authService = app.authService;\n await withSpan(\"generate.resolveAuthNamespaces\", async () =>\n authService.resolveNamespaces(),\n );\n }\n\n // Add blank line after TailorDB types loaded\n if (app.tailorDBServices.length > 0 || pluginExecutorFiles.length > 0) {\n logger.newline();\n }\n\n // Run plugin hooks for onTailorDBReady\n const hasOnTailorDBReady = generationPlugins.some((p) => p.onTailorDBReady != null);\n if (hasOnTailorDBReady) {\n await withSpan(\"generate.onTailorDBReady\", async () => {\n await runPluginHook(\"onTailorDBReady\");\n });\n logger.newline();\n }\n\n // Load Resolvers (can now import generated files)\n await withSpan(\"generate.loadResolvers\", async () => {\n for (const resolverService of app.resolverServices) {\n const namespace = resolverService.namespace;\n await withSpan(`generate.loadResolvers.${namespace}`, async () => {\n try {\n await resolverService.loadResolvers();\n const namespaceResolvers: Record<string, Resolver> = {};\n services.resolver[namespace] = namespaceResolvers;\n Object.entries(resolverService.resolvers).forEach(([_, resolver]) => {\n namespaceResolvers[resolver.name] = resolver;\n });\n } catch (error) {\n logger.error(\n `Error loading resolvers for Resolver service ${styles.bold(namespace)}`,\n );\n logger.error(String(error));\n throw error;\n }\n });\n }\n });\n\n // Run plugin hooks for onResolverReady\n const hasOnResolverReady = generationPlugins.some((p) => p.onResolverReady != null);\n if (hasOnResolverReady) {\n await withSpan(\"generate.onResolversReady\", async () => {\n await runPluginHook(\"onResolverReady\");\n });\n logger.newline();\n }\n\n // Load Executors (can now import generated files)\n await withSpan(\"generate.loadExecutors\", async () => {\n if (executorService) {\n await executorService.loadExecutors();\n // Load plugin-generated executors from generated TypeScript files\n if (pluginExecutorFiles.length > 0) {\n await executorService.loadPluginExecutorFiles([...pluginExecutorFiles]);\n }\n }\n // Get all executors (file-based and plugin-generated)\n const allExecutors = executorService?.executors ?? {};\n Object.entries(allExecutors).forEach(([key, executor]) => {\n services.executor[key] = executor as Executor;\n });\n });\n\n // Run plugin hooks for onExecutorReady\n const hasOnExecutorReady = generationPlugins.some((p) => p.onExecutorReady != null);\n if (hasOnExecutorReady) {\n await withSpan(\"generate.onExecutorsReady\", async () => {\n await runPluginHook(\"onExecutorReady\");\n });\n logger.newline();\n }\n },\n };\n}\n\n/**\n * Run code generation using the Tailor configuration.\n * @param options - Generation options\n * @returns Promise that resolves when generation completes\n */\nexport async function generate(options?: GenerateOptions) {\n return withSpan(\"generate\", async (rootSpan) => {\n // Load and validate options\n const { config, plugins } = await withSpan(\"generate.loadConfig\", async () => {\n return loadConfig(options?.configPath);\n });\n\n // Generate user types from loaded config\n await withSpan(\"generate.generateUserTypes\", async () =>\n generateUserTypes({ config, configPath: config.path }),\n );\n\n // Initialize plugin manager if plugins are provided\n let pluginManager: PluginManager | undefined;\n if (plugins.length > 0) {\n pluginManager = new PluginManager(plugins);\n }\n\n // Create a lightweight application (types not yet loaded)\n const application = defineApplication({ config, pluginManager });\n\n rootSpan.setAttribute(\"app.name\", application.config.name);\n\n const manager = createGenerationManager({ application, config, pluginManager });\n await manager.generate();\n });\n}\n","import { toJson } from \"@bufbuild/protobuf\";\nimport { timestampDate, ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport { z } from \"zod\";\nimport { deploymentArgs, type Order, paginationArgs, toPageDirection } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport type { MachineUser } from \"@tailor-platform/tailor-proto/auth_resource_pb\";\n\nexport interface ListMachineUsersOptions {\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n order?: Order;\n limit?: number;\n}\n\nexport interface MachineUserInfo {\n name: string;\n clientId: string;\n clientSecret: string;\n createdAt: Date | null;\n updatedAt: Date | null;\n attributes: Record<string, unknown>;\n}\n\n/**\n * Map a MachineUser protobuf message to CLI-friendly info.\n * @param user - Machine user resource\n * @returns Flattened machine user info\n */\nfunction machineUserInfo(user: MachineUser): MachineUserInfo {\n return {\n name: user.name,\n clientId: user.clientId,\n clientSecret: user.clientSecret,\n createdAt: user.createdAt ? timestampDate(user.createdAt) : null,\n updatedAt: user.updatedAt ? timestampDate(user.updatedAt) : null,\n attributes: Object.fromEntries(\n Object.entries(user.attributeMap).map(([key, value]) => [key, toJson(ValueSchema, value)]),\n ),\n };\n}\n\n/**\n * List machine users for the current application.\n * @param options - Machine user listing options\n * @returns List of machine users\n */\nexport async function listMachineUsers(\n options?: ListMachineUsersOptions,\n): Promise<MachineUserInfo[]> {\n // Load and validate options\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n // Get application\n const { config } = await loadConfig(options?.configPath);\n const { application } = await client.getApplication({\n workspaceId,\n applicationName: config.name,\n });\n if (!application?.authNamespace) {\n throw new Error(`Application ${config.name} does not have an auth configuration.`);\n }\n\n const pageDirection = toPageDirection(options?.order);\n const machineUsers = await fetchPaged(\n async (pageToken, pageSize) => {\n const { machineUsers, nextPageToken } = await client.listAuthMachineUsers({\n workspaceId,\n pageToken,\n pageSize,\n authNamespace: application.authNamespace,\n pageDirection,\n });\n return [machineUsers, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return machineUsers.map(machineUserInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all machine users in the application.\",\n args: z.strictObject({\n ...deploymentArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n // Execute machineuser list logic\n const machineUsers = await listMachineUsers({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n order: args.order,\n limit: args.limit,\n });\n\n // Show machine users info\n logger.out(machineUsers, { display: { createdAt: null, updatedAt: null } });\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport {\n deploymentArgs,\n resolveMachineUserInputSource,\n type MachineUserInputSource,\n} from \"#/cli/shared/args\";\nimport { fetchMachineUserToken, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadMachineUserName, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\n\nexport interface GetMachineUserTokenOptions {\n name?: string;\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n}\n\ntype GetMachineUserTokenInternalOptions = GetMachineUserTokenOptions & {\n nameSource?: MachineUserInputSource;\n};\n\nexport interface MachineUserTokenInfo {\n accessToken: string;\n tokenType: string;\n expiresAt: string;\n}\n\nasync function getMachineUserTokenInternal(\n options: GetMachineUserTokenInternalOptions,\n): Promise<MachineUserTokenInfo> {\n // Load and validate options\n const name = await loadMachineUserName({\n machineUser: options.name,\n machineUserSource: options.nameSource,\n profile: options.profile,\n });\n if (!name) {\n throw new Error(\n \"Machine user is required. Provide the NAME positional argument, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.\",\n );\n }\n\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n // Get application\n const { config } = await loadConfig(options.configPath);\n const { application } = await client.getApplication({\n workspaceId,\n applicationName: config.name,\n });\n if (!application?.authNamespace) {\n throw new Error(`Application ${config.name} does not have an auth configuration.`);\n }\n\n // Get machine user\n const { machineUser } = await client.getAuthMachineUser({\n workspaceId,\n authNamespace: application.authNamespace,\n name,\n });\n if (!machineUser) {\n throw new Error(`Machine user ${name} not found.`);\n }\n\n // Fetch machine user token\n const resp = await fetchMachineUserToken(\n application.url,\n machineUser.clientId,\n machineUser.clientSecret,\n );\n const expiresAt = new Date();\n expiresAt.setSeconds(expiresAt.getSeconds() + resp.expires_in);\n\n return {\n accessToken: resp.access_token,\n tokenType: resp.token_type,\n expiresAt: expiresAt.toISOString(),\n };\n}\n\n/**\n * Get a machine user access token for the current application.\n * @param options - Token retrieval options\n * @returns Machine user token info\n */\nexport async function getMachineUserToken(\n options: GetMachineUserTokenOptions,\n): Promise<MachineUserTokenInfo> {\n return await getMachineUserTokenInternal(options);\n}\n\nexport const tokenCommand = defineAppCommand({\n name: \"token\",\n description: \"Get an access token for a machine user.\",\n args: z.strictObject({\n ...deploymentArgs,\n name: arg(z.string().optional(), {\n positional: true,\n description:\n \"Machine user name. Falls back to TAILOR_PLATFORM_MACHINE_USER_NAME, then the active profile's default machine user.\",\n }),\n }),\n run: async (args) => {\n // Execute machineuser token logic\n const token = await getMachineUserTokenInternal({\n name: args.name,\n nameSource: resolveMachineUserInputSource(args.name, process.argv.slice(2), {\n valueIsExplicit: args.name !== undefined,\n }),\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n });\n\n // Show machine user token info\n // TODO: remove this transformation\n const tokenInfo = {\n access_token: token.accessToken,\n token_type: token.tokenType,\n expires_at: token.expiresAt,\n };\n logger.out(tokenInfo);\n },\n});\n","import { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport {\n type AuthOAuth2Client,\n AuthOAuth2Client_GrantType,\n} from \"@tailor-platform/tailor-proto/auth_resource_pb\";\n\nconst grantTypeToString = (grantType: AuthOAuth2Client_GrantType): string => {\n switch (grantType) {\n case AuthOAuth2Client_GrantType.AUTHORIZATION_CODE:\n return \"authorization_code\";\n case AuthOAuth2Client_GrantType.REFRESH_TOKEN:\n return \"refresh_token\";\n default:\n return \"unknown\";\n }\n};\n\nexport interface OAuth2ClientInfo {\n name: string;\n description: string;\n clientId: string;\n grantTypes: string[];\n redirectUris: string[];\n createdAt: Date | null;\n}\n\nexport interface OAuth2ClientCredentials {\n name: string;\n description: string;\n clientId: string;\n clientSecret: string;\n grantTypes: string[];\n redirectUris: string[];\n createdAt: Date | null;\n}\n\n/**\n * Transform an AuthOAuth2Client into CLI-friendly OAuth2 client info.\n * @param client - OAuth2 client resource\n * @returns Flattened OAuth2 client info\n */\nexport function toOAuth2ClientInfo(client: AuthOAuth2Client): OAuth2ClientInfo {\n return {\n name: client.name,\n description: client.description,\n clientId: client.clientId,\n grantTypes: client.grantTypes.map(grantTypeToString),\n redirectUris: client.redirectUris,\n createdAt: client.createdAt ? timestampDate(client.createdAt) : null,\n };\n}\n\n/**\n * Transform an AuthOAuth2Client into OAuth2 client credentials info.\n * @param client - OAuth2 client resource\n * @returns OAuth2 client credentials\n */\nexport function toOAuth2ClientCredentials(client: AuthOAuth2Client): OAuth2ClientCredentials {\n return {\n name: client.name,\n description: client.description,\n clientId: client.clientId,\n clientSecret: client.clientSecret,\n grantTypes: client.grantTypes.map(grantTypeToString),\n redirectUris: client.redirectUris,\n createdAt: client.createdAt ? timestampDate(client.createdAt) : null,\n };\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { deploymentArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { type OAuth2ClientCredentials, toOAuth2ClientCredentials } from \"./transform\";\n\nexport interface GetOAuth2ClientOptions {\n name: string;\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n}\n\n/**\n * Get OAuth2 client credentials for the current application.\n * @param options - OAuth2 client lookup options\n * @returns OAuth2 client credentials\n */\nexport async function getOAuth2Client(\n options: GetOAuth2ClientOptions,\n): Promise<OAuth2ClientCredentials> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n const { config } = await loadConfig(options.configPath);\n const { application } = await client.getApplication({\n workspaceId,\n applicationName: config.name,\n });\n if (!application?.authNamespace) {\n throw new Error(`Application ${config.name} does not have an auth configuration.`);\n }\n\n try {\n const { oauth2Client } = await client.getAuthOAuth2Client({\n workspaceId,\n namespaceName: application.authNamespace,\n name: options.name,\n });\n\n return toOAuth2ClientCredentials(\n assertDefined(oauth2Client, \"oauth2Client missing in response\"),\n );\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n throw new Error(`OAuth2 client '${options.name}' not found.`, { cause: error });\n }\n throw error;\n }\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Get OAuth2 client credentials (including client secret).\",\n args: z.strictObject({\n ...deploymentArgs,\n name: arg(z.string(), {\n positional: true,\n description: \"OAuth2 client name\",\n }),\n }),\n run: async (args) => {\n const credentials = await getOAuth2Client({\n name: args.name,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n });\n\n logger.out(credentials);\n },\n});\n","import { z } from \"zod\";\nimport { deploymentArgs, type Order, paginationArgs, toPageDirection } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { type OAuth2ClientInfo, toOAuth2ClientInfo } from \"./transform\";\n\nexport interface ListOAuth2ClientsOptions {\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n order?: Order;\n limit?: number;\n}\n\n/**\n * List OAuth2 clients for the current application.\n * @param options - OAuth2 client listing options\n * @returns List of OAuth2 clients\n */\nexport async function listOAuth2Clients(\n options?: ListOAuth2ClientsOptions,\n): Promise<OAuth2ClientInfo[]> {\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n const { config } = await loadConfig(options?.configPath);\n const { application } = await client.getApplication({\n workspaceId,\n applicationName: config.name,\n });\n if (!application?.authNamespace) {\n throw new Error(`Application ${config.name} does not have an auth configuration.`);\n }\n\n const pageDirection = toPageDirection(options?.order);\n const oauth2Clients = await fetchPaged(\n async (pageToken, pageSize) => {\n const { oauth2Clients, nextPageToken } = await client.listAuthOAuth2Clients({\n workspaceId,\n pageToken,\n pageSize,\n namespaceName: application.authNamespace,\n pageDirection,\n });\n return [oauth2Clients, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return oauth2Clients.map(toOAuth2ClientInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all OAuth2 clients in the application.\",\n args: z.strictObject({\n ...deploymentArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const oauth2Clients = await listOAuth2Clients({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n order: args.order,\n limit: args.limit,\n });\n\n logger.out(oauth2Clients);\n },\n});\n","import { formatTimestamp } from \"#/cli/shared/format\";\nimport type { ListUserOrganizationsResponse_UserOrganization } from \"@tailor-platform/tailor-proto/workspace_pb\";\nimport type { Organization, Folder } from \"@tailor-platform/tailor-proto/workspace_resource_pb\";\n\nexport interface UserOrganizationInfo {\n organizationId: string;\n organizationName: string;\n rootFolderId: string;\n rootFolderName: string;\n displayName: string;\n}\n\nexport interface OrganizationInfo {\n id: string;\n name: string;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\nexport interface FolderListInfo {\n id: string;\n name: string;\n organizationId: string;\n parentFolderId: string;\n hasChildren: boolean;\n createdAt: Date | null;\n}\n\nexport interface FolderInfo extends FolderListInfo {\n updatedAt: Date | null;\n}\n\nexport const userOrganizationInfo = (\n org: ListUserOrganizationsResponse_UserOrganization,\n): UserOrganizationInfo => ({\n organizationId: org.organizationId,\n organizationName: org.organizationName,\n rootFolderId: org.rootFolderId,\n rootFolderName: org.rootFolderName,\n displayName: org.displayName,\n});\n\nexport const organizationInfo = (org: Organization): OrganizationInfo => ({\n id: org.id,\n name: org.name,\n createdAt: formatTimestamp(org.createTime),\n updatedAt: formatTimestamp(org.updateTime),\n});\n\nexport const folderListInfo = (folder: Folder): FolderListInfo => ({\n id: folder.id,\n name: folder.name,\n organizationId: folder.organizationId,\n parentFolderId: folder.parentFolderId,\n hasChildren: folder.hasChildren,\n createdAt: formatTimestamp(folder.createTime),\n});\n\nexport const folderInfo = (folder: Folder): FolderInfo => ({\n ...folderListInfo(folder),\n updatedAt: formatTimestamp(folder.updateTime),\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { organizationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { folderInfo, type FolderInfo } from \"../transform\";\n\n// strip unknown keys\nconst createFolderOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n parentFolderId: z.string().optional(),\n name: z.string().min(1, \"Name must not be empty\"),\n});\n\nexport type CreateFolderOptions = z.input<typeof createFolderOptionsSchema>;\n\n/**\n * Create a new folder in an organization.\n * @param options - Folder creation options\n * @returns Created folder details\n */\nexport async function createFolder(options: CreateFolderOptions): Promise<FolderInfo> {\n const result = createFolderOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const response = await client.createOrganizationFolder({\n organizationId: result.data.organizationId,\n parentFolderId: result.data.parentFolderId ?? \"\",\n folderName: result.data.name,\n });\n\n if (!response.folder) {\n throw new Error(\"Failed to create folder.\");\n }\n\n return folderInfo(response.folder);\n}\n\nexport const createCommand = defineAppCommand({\n name: \"create\",\n description: \"Create a new folder in an organization.\",\n args: z.strictObject({\n ...organizationArgs,\n \"parent-folder-id\": arg(z.string().optional(), {\n description: \"Parent folder ID\",\n }),\n name: arg(z.string(), {\n alias: \"n\",\n description: \"Folder name\",\n }),\n }),\n run: async (args) => {\n await assertWritable();\n const folder = await createFolder({\n organizationId: args[\"organization-id\"],\n parentFolderId: args[\"parent-folder-id\"],\n name: args.name,\n });\n\n if (!args.json) {\n logger.success(`Folder \"${folder.name}\" created successfully.`);\n }\n\n logger.out(folder);\n },\n});\n","import { z } from \"zod\";\nimport { confirmationArgs, folderArgs, organizationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\n\n// strip unknown keys\nconst deleteFolderOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n folderId: z.uuid({ message: \"folder-id must be a valid UUID\" }),\n});\n\nexport type DeleteFolderOptions = z.input<typeof deleteFolderOptionsSchema>;\n\n/**\n * Delete a folder from an organization.\n * @param options - Folder deletion options\n * @returns Promise that resolves when deletion completes\n */\nexport async function deleteFolder(options: DeleteFolderOptions): Promise<void> {\n const result = deleteFolderOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n await client.deleteOrganizationFolder({\n organizationId: result.data.organizationId,\n folderId: result.data.folderId,\n });\n}\n\nexport const deleteCommand = defineAppCommand({\n name: \"delete\",\n description: \"Delete a folder from an organization.\",\n args: z.strictObject({\n ...organizationArgs,\n ...folderArgs,\n ...confirmationArgs,\n }),\n run: async (args) => {\n await assertWritable();\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n // Check if folder exists and get its name\n let folderName: string | undefined;\n try {\n const response = await client.getOrganizationFolder({\n organizationId: args[\"organization-id\"],\n folderId: args[\"folder-id\"],\n });\n folderName = response.folder?.name;\n } catch {\n throw new Error(`Folder \"${args[\"folder-id\"]}\" not found.`);\n }\n\n // Confirm deletion if not forced\n if (!args.yes) {\n const confirmed = await prompt.confirm({\n message: `Are you sure you want to delete folder \"${folderName}\"?`,\n });\n if (!confirmed) {\n logger.info(\"Folder deletion cancelled.\");\n return;\n }\n }\n\n await client.deleteOrganizationFolder({\n organizationId: args[\"organization-id\"],\n folderId: args[\"folder-id\"],\n });\n\n logger.success(`Folder \"${folderName}\" deleted successfully.`);\n },\n});\n","import { z } from \"zod\";\nimport { folderArgs, organizationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { folderInfo, type FolderInfo } from \"../transform\";\n\n// strip unknown keys\nconst getFolderOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n folderId: z.uuid({ message: \"folder-id must be a valid UUID\" }),\n});\n\nexport type GetFolderOptions = z.input<typeof getFolderOptionsSchema>;\n\n/**\n * Get detailed information about a folder.\n * @param options - Folder get options\n * @returns Folder details\n */\nexport async function getFolder(options: GetFolderOptions): Promise<FolderInfo> {\n const result = getFolderOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const response = await client.getOrganizationFolder({\n organizationId: result.data.organizationId,\n folderId: result.data.folderId,\n });\n\n if (!response.folder) {\n throw new Error(`Folder \"${result.data.folderId}\" not found.`);\n }\n\n return folderInfo(response.folder);\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Show detailed information about a folder.\",\n args: z.strictObject({\n ...organizationArgs,\n ...folderArgs,\n }),\n run: async (args) => {\n const folder = await getFolder({\n organizationId: args[\"organization-id\"],\n folderId: args[\"folder-id\"],\n });\n\n const formattedFolder = args.json\n ? folder\n : {\n ...folder,\n createdAt: humanizeRelativeTime(folder.createdAt),\n updatedAt: humanizeRelativeTime(folder.updatedAt),\n };\n\n logger.out(formattedFolder);\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { orderArg, organizationArgs, paginationArgs, toPageDirection } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { folderListInfo, type FolderListInfo } from \"../transform\";\n\n// strip unknown keys\nconst listFoldersOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n parentFolderId: z.string().optional(),\n order: orderArg.optional(),\n limit: z.number().int().nonnegative().optional(),\n});\n\nexport type ListFoldersOptions = z.input<typeof listFoldersOptionsSchema>;\n\n/**\n * List folders in an organization.\n * @param options - Folder listing options\n * @returns List of folders\n */\nexport async function listFolders(options: ListFoldersOptions): Promise<FolderListInfo[]> {\n const result = listFoldersOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const { organizationId, parentFolderId, order, limit } = result.data;\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const pageDirection = toPageDirection(order);\n const folders = await fetchPaged(\n async (pageToken, pageSize) => {\n const response = await client.listOrganizationFolders({\n organizationId,\n ...(parentFolderId ? { parentFolderId } : {}),\n pageToken,\n pageSize,\n pageDirection,\n });\n return [response.folders, response.nextPageToken];\n },\n { limit },\n );\n\n return folders.map(folderListInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List folders in an organization.\",\n args: z.strictObject({\n ...organizationArgs,\n \"parent-folder-id\": arg(z.string().optional(), {\n description: \"Parent folder ID to list children of\",\n }),\n ...paginationArgs(),\n }),\n run: async (args) => {\n const folders = await listFolders({\n organizationId: args[\"organization-id\"],\n parentFolderId: args[\"parent-folder-id\"],\n order: args.order,\n limit: args.limit,\n });\n logger.out(folders, { display: { updatedAt: null } });\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { folderArgs, organizationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { folderInfo, type FolderInfo } from \"../transform\";\n\n// strip unknown keys\nconst updateFolderOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n folderId: z.uuid({ message: \"folder-id must be a valid UUID\" }),\n name: z.string().min(1, \"Name must not be empty\"),\n});\n\nexport type UpdateFolderOptions = z.input<typeof updateFolderOptionsSchema>;\n\n/**\n * Update a folder's name.\n * @param options - Folder update options\n * @returns Updated folder details\n */\nexport async function updateFolder(options: UpdateFolderOptions): Promise<FolderInfo> {\n const result = updateFolderOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const response = await client.updateOrganizationFolder({\n organizationId: result.data.organizationId,\n folderId: result.data.folderId,\n folderName: result.data.name,\n });\n\n if (!response.folder) {\n throw new Error(`Failed to update folder \"${result.data.folderId}\".`);\n }\n\n return folderInfo(response.folder);\n}\n\nexport const updateCommand = defineAppCommand({\n name: \"update\",\n description: \"Update a folder's name.\",\n args: z.strictObject({\n ...organizationArgs,\n ...folderArgs,\n name: arg(z.string(), {\n alias: \"n\",\n description: \"New folder name\",\n }),\n }),\n run: async (args) => {\n await assertWritable();\n const folder = await updateFolder({\n organizationId: args[\"organization-id\"],\n folderId: args[\"folder-id\"],\n name: args.name,\n });\n\n if (!args.json) {\n logger.success(`Folder \"${folder.name}\" updated successfully.`);\n }\n\n logger.out(folder);\n },\n});\n","import { z } from \"zod\";\nimport { organizationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { organizationInfo, type OrganizationInfo } from \"./transform\";\n\n// strip unknown keys\nconst getOrganizationOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n});\n\nexport type GetOrganizationOptions = z.input<typeof getOrganizationOptionsSchema>;\n\n/**\n * Get detailed information about an organization.\n * @param options - Organization get options\n * @returns Organization details\n */\nexport async function getOrganization(options: GetOrganizationOptions): Promise<OrganizationInfo> {\n const result = getOrganizationOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const response = await client.getOrganization({\n organizationId: result.data.organizationId,\n });\n\n if (!response.organization) {\n throw new Error(`Organization \"${result.data.organizationId}\" not found.`);\n }\n\n return organizationInfo(response.organization);\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Show detailed information about an organization.\",\n args: z.strictObject({\n ...organizationArgs,\n }),\n run: async (args) => {\n const organization = await getOrganization({\n organizationId: args[\"organization-id\"],\n });\n\n const formattedOrganization = args.json\n ? organization\n : {\n ...organization,\n createdAt: humanizeRelativeTime(organization.createdAt),\n updatedAt: humanizeRelativeTime(organization.updatedAt),\n };\n\n logger.out(formattedOrganization);\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { positiveIntArg } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { userOrganizationInfo, type UserOrganizationInfo } from \"./transform\";\n\nexport interface ListOrganizationsOptions {\n limit?: number;\n}\n\n/**\n * List organizations the current user belongs to.\n * @param options - Organization listing options\n * @returns List of user organizations\n */\nexport async function listOrganizations(\n options?: ListOrganizationsOptions,\n): Promise<UserOrganizationInfo[]> {\n const limit = options?.limit;\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const { userOrganizations } = await client.listUserOrganizations({});\n const results = userOrganizations.map(userOrganizationInfo);\n\n if (limit !== undefined) {\n return results.slice(0, limit);\n }\n return results;\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List organizations you belong to.\",\n args: z.strictObject({\n limit: arg(positiveIntArg.optional(), {\n alias: \"l\",\n description: \"Maximum number of organizations to list\",\n }),\n }),\n run: async (args) => {\n const organizations = await listOrganizations({ limit: args.limit });\n logger.out(organizations);\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { positiveIntArg } from \"#/cli/shared/args\";\nimport { fetchAll, initOperatorClient, type OperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { listOrganizations } from \"./list\";\nimport type { UserOrganizationInfo } from \"./transform\";\n\ninterface TreeNode {\n name: string;\n children: TreeNode[];\n}\n\nexport interface OrganizationTreeOptions {\n organizationId?: string;\n depth?: number;\n}\n\ninterface OrganizationTreeJson {\n organizationId: string;\n organizationName: string;\n folders: FolderTreeJson[];\n}\n\ninterface FolderTreeJson {\n id: string;\n name: string;\n children: FolderTreeJson[];\n}\n\nasync function fetchChildFolders(\n client: OperatorClient,\n organizationId: string,\n parentFolderId: string,\n currentDepth: number,\n maxDepth: number | undefined,\n): Promise<TreeNode[]> {\n if (maxDepth !== undefined && currentDepth >= maxDepth) {\n return [];\n }\n\n const folders = await fetchAll(async (pageToken, maxPageSize) => {\n const response = await client.listOrganizationFolders({\n organizationId,\n parentFolderId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [response.folders, response.nextPageToken];\n });\n\n const nodes: TreeNode[] = [];\n for (const folder of folders) {\n const children = folder.hasChildren\n ? await fetchChildFolders(client, organizationId, folder.id, currentDepth + 1, maxDepth)\n : [];\n nodes.push({ name: folder.name, children });\n }\n return nodes;\n}\n\nasync function buildFolderTreeJson(\n client: OperatorClient,\n organizationId: string,\n parentFolderId: string,\n currentDepth: number,\n maxDepth: number | undefined,\n): Promise<FolderTreeJson[]> {\n if (maxDepth !== undefined && currentDepth >= maxDepth) {\n return [];\n }\n\n const folders = await fetchAll(async (pageToken, maxPageSize) => {\n const response = await client.listOrganizationFolders({\n organizationId,\n parentFolderId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [response.folders, response.nextPageToken];\n });\n\n const result: FolderTreeJson[] = [];\n for (const folder of folders) {\n const children = folder.hasChildren\n ? await buildFolderTreeJson(client, organizationId, folder.id, currentDepth + 1, maxDepth)\n : [];\n result.push({ id: folder.id, name: folder.name, children });\n }\n return result;\n}\n\nfunction renderTree(nodes: TreeNode[], prefix: string): string {\n let output = \"\";\n for (const [i, node] of nodes.entries()) {\n const isLast = i === nodes.length - 1;\n const connector = isLast ? \"\\u2514\\u2500\\u2500 \" : \"\\u251c\\u2500\\u2500 \";\n const childPrefix = isLast ? \" \" : \"\\u2502 \";\n output += `${prefix}${connector}${node.name}\\n`;\n if (node.children.length > 0) {\n output += renderTree(node.children, prefix + childPrefix);\n }\n }\n return output;\n}\n\nasync function buildOrgTree(\n client: OperatorClient,\n org: UserOrganizationInfo,\n depth: number | undefined,\n): Promise<string> {\n const children = await fetchChildFolders(client, org.organizationId, org.rootFolderId, 0, depth);\n let output = `${org.organizationName}\\n`;\n output += renderTree(children, \"\");\n return output;\n}\n\n/**\n * Display a tree view of organizations and their folder hierarchy.\n * @param options - Tree display options\n * @returns Organization tree as structured data\n */\nexport async function organizationTree(\n options?: OrganizationTreeOptions,\n): Promise<OrganizationTreeJson[]> {\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n let orgs: UserOrganizationInfo[];\n if (options?.organizationId) {\n orgs = (await listOrganizations()).filter((o) => o.organizationId === options.organizationId);\n if (orgs.length === 0) {\n throw new Error(`Organization \"${options.organizationId}\" not found.`);\n }\n } else {\n orgs = await listOrganizations();\n }\n\n const depth = options?.depth;\n\n const jsonResult: OrganizationTreeJson[] = [];\n for (const org of orgs) {\n const folders = await buildFolderTreeJson(\n client,\n org.organizationId,\n org.rootFolderId,\n 0,\n depth,\n );\n jsonResult.push({\n organizationId: org.organizationId,\n organizationName: org.organizationName,\n folders,\n });\n }\n\n return jsonResult;\n}\n\nexport const treeCommand = defineAppCommand({\n name: \"tree\",\n description: \"Display organization folder hierarchy as a tree.\",\n args: z.strictObject({\n \"organization-id\": arg(z.string().optional(), {\n alias: \"o\",\n description: \"Organization ID (show all if omitted)\",\n env: \"TAILOR_PLATFORM_ORGANIZATION_ID\",\n }),\n depth: arg(positiveIntArg.optional(), {\n alias: \"d\",\n description: \"Maximum folder depth to display\",\n }),\n }),\n run: async (args) => {\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n let orgs: UserOrganizationInfo[];\n if (args[\"organization-id\"]) {\n orgs = (await listOrganizations()).filter(\n (o) => o.organizationId === args[\"organization-id\"],\n );\n if (orgs.length === 0) {\n throw new Error(`Organization \"${args[\"organization-id\"]}\" not found.`);\n }\n } else {\n orgs = await listOrganizations();\n }\n\n if (args.json) {\n const jsonResult: OrganizationTreeJson[] = [];\n for (const org of orgs) {\n const folders = await buildFolderTreeJson(\n client,\n org.organizationId,\n org.rootFolderId,\n 0,\n args.depth,\n );\n jsonResult.push({\n organizationId: org.organizationId,\n organizationName: org.organizationName,\n folders,\n });\n }\n logger.out(jsonResult);\n return;\n }\n\n const trees: string[] = [];\n for (const org of orgs) {\n trees.push(await buildOrgTree(client, org, args.depth));\n }\n\n logger.log(trees.join(\"\\n\"));\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { organizationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { organizationInfo, type OrganizationInfo } from \"./transform\";\n\n// strip unknown keys\nconst updateOrganizationOptionsSchema = z.object({\n organizationId: z.uuid({ message: \"organization-id must be a valid UUID\" }),\n name: z.string().min(1, \"Name must not be empty\"),\n});\n\nexport type UpdateOrganizationOptions = z.input<typeof updateOrganizationOptionsSchema>;\n\n/**\n * Update an organization's name.\n * @param options - Organization update options\n * @returns Updated organization details\n */\nexport async function updateOrganization(\n options: UpdateOrganizationOptions,\n): Promise<OrganizationInfo> {\n const result = updateOrganizationOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n const response = await client.updateOrganization({\n organizationId: result.data.organizationId,\n organizationName: result.data.name,\n });\n\n if (!response.organization) {\n throw new Error(`Failed to update organization \"${result.data.organizationId}\".`);\n }\n\n return organizationInfo(response.organization);\n}\n\nexport const updateCommand = defineAppCommand({\n name: \"update\",\n description: \"Update an organization's name.\",\n args: z.strictObject({\n ...organizationArgs,\n name: arg(z.string(), {\n alias: \"n\",\n description: \"New organization name\",\n }),\n }),\n run: async (args) => {\n await assertWritable();\n const organization = await updateOrganization({\n organizationId: args[\"organization-id\"],\n name: args.name,\n });\n\n if (!args.json) {\n logger.success(`Organization \"${organization.name}\" updated successfully.`);\n }\n\n logger.out(organization);\n },\n});\n","import { z } from \"zod\";\nimport { applyAIGateway, planAIGateway } from \"#/cli/commands/deploy/aigateway\";\nimport { applyApplication, planApplication } from \"#/cli/commands/deploy/application\";\nimport { applyAuth, planAuth } from \"#/cli/commands/deploy/auth\";\nimport { warnMissingAppId } from \"#/cli/commands/deploy/config-id-injector\";\nimport { applyExecutor, planExecutor } from \"#/cli/commands/deploy/executor\";\nimport {\n applyFunctionRegistry,\n planFunctionRegistry,\n} from \"#/cli/commands/deploy/function-registry\";\nimport { applyIdP, planIdP } from \"#/cli/commands/deploy/idp\";\nimport { applyPipeline, planPipeline } from \"#/cli/commands/deploy/resolver\";\nimport { applySecretManager, planSecretManager } from \"#/cli/commands/deploy/secret-manager\";\nimport { applyStaticWebsite, planStaticWebsite } from \"#/cli/commands/deploy/staticwebsite\";\nimport { applyTailorDB, planTailorDB } from \"#/cli/commands/deploy/tailordb/index\";\nimport { applyWorkflow, planWorkflow } from \"#/cli/commands/deploy/workflow\";\nimport {\n applyWorkflowJobFunctionExecutionPolicy,\n planWorkflowJobFunctionExecutionPolicy,\n} from \"#/cli/commands/deploy/workflow-execution-policy\";\nimport { type Application, defineApplication } from \"#/cli/services/application\";\nimport { confirmationArgs, deploymentArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient, type OperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig, type LoadedConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport ml from \"#/utils/multiline\";\nimport type { PlannedDeployment } from \"#/cli/commands/deploy/apply-phases\";\nimport type { PlanContext } from \"#/cli/commands/deploy/types\";\n\nexport interface RemoveOptions {\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n}\n\nasync function loadOptions(options?: RemoveOptions) {\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n const { config } = await loadConfig(options?.configPath);\n const application = defineApplication({ config });\n warnMissingAppId(application.id);\n return {\n client,\n workspaceId,\n application,\n config,\n };\n}\n\nasync function execRemove(\n client: OperatorClient,\n workspaceId: string,\n application: Application,\n config: LoadedConfig,\n confirm?: () => Promise<void>,\n) {\n // Plan all resources with forRemoval=true\n const ctx: PlanContext = {\n client,\n workspaceId,\n application,\n forRemoval: true,\n config,\n };\n // Keyed like `PlannedDeployment` (deploy/apply-phases.ts): adding a resource\n // type there without also adding it here fails to compile.\n const plans = {\n tailorDB: await planTailorDB(ctx),\n staticWebsite: await planStaticWebsite(ctx),\n aiGateway: await planAIGateway(ctx),\n idp: await planIdP(ctx),\n auth: await planAuth(ctx),\n pipeline: await planPipeline(ctx),\n app: await planApplication(ctx),\n executor: await planExecutor(ctx),\n workflow: await planWorkflow(client, workspaceId, application.name, application.id, {}, {}),\n workflowExecutionPolicy: await planWorkflowJobFunctionExecutionPolicy(\n client,\n workspaceId,\n application.name,\n application.id,\n {},\n ),\n functionRegistry: await planFunctionRegistry(\n client,\n workspaceId,\n application.name,\n application.id,\n [],\n ),\n secretManager: await planSecretManager(ctx),\n } satisfies Omit<PlannedDeployment, \"application\">;\n\n // Resources carrying this application's sdk-name whose sdk-app-id the config\n // does not match, because it holds a different id or none. They are skipped,\n // so removal is not complete.\n const leftBehind = Object.values(plans).some(\n (plan) => \"resourceOwners\" in plan && plan.resourceOwners.has(application.name),\n );\n\n // Print planned deletions (same order as apply dry-run)\n const removeLines = [\n ...plans.functionRegistry.changeSet.lines(),\n ...plans.staticWebsite.changeSet.lines(),\n ...plans.aiGateway.changeSet.lines(),\n ...plans.app.lines(),\n ...plans.tailorDB.changeSet.service.lines(),\n ...plans.tailorDB.changeSet.type.lines(),\n ...plans.tailorDB.changeSet.gqlPermission.lines(),\n ...plans.pipeline.changeSet.service.lines(),\n ...plans.pipeline.changeSet.resolver.lines(),\n ...plans.executor.changeSet.lines(),\n ...plans.workflow.changeSet.lines(),\n ...plans.workflowExecutionPolicy.changeSet.lines(),\n ...plans.idp.changeSet.service.lines(),\n ...plans.idp.changeSet.client.lines(),\n ...plans.auth.changeSet.service.lines(),\n ...plans.auth.changeSet.idpConfig.lines(),\n ...plans.auth.changeSet.userProfileConfig.lines(),\n ...plans.auth.changeSet.tenantConfig.lines(),\n ...plans.auth.changeSet.machineUser.lines(),\n ...plans.auth.changeSet.oauth2Client.lines(),\n ...plans.auth.changeSet.authHook.lines(),\n ...plans.auth.changeSet.scim.lines(),\n ...plans.auth.changeSet.scimResource.lines(),\n ...plans.auth.changeSet.connection.lines(),\n ...plans.secretManager.vaultChangeSet.lines(),\n ...plans.secretManager.secretChangeSet.lines(),\n ];\n if (removeLines.length > 0) logger.log(removeLines.join(\"\\n\"));\n\n if (\n plans.tailorDB.changeSet.service.deletes.length === 0 &&\n plans.staticWebsite.changeSet.deletes.length === 0 &&\n plans.aiGateway.changeSet.deletes.length === 0 &&\n plans.idp.changeSet.service.deletes.length === 0 &&\n plans.auth.changeSet.service.deletes.length === 0 &&\n plans.pipeline.changeSet.service.deletes.length === 0 &&\n plans.app.deletes.length === 0 &&\n plans.executor.changeSet.deletes.length === 0 &&\n plans.workflow.changeSet.deletes.length === 0 &&\n plans.workflowExecutionPolicy.changeSet.deletes.length === 0 &&\n plans.functionRegistry.changeSet.deletes.length === 0 &&\n plans.secretManager.vaultChangeSet.deletes.length === 0 &&\n plans.secretManager.secretChangeSet.deletes.length === 0\n ) {\n return { leftBehind };\n }\n\n // Confirm deletion\n if (confirm) {\n await confirm();\n }\n\n // Apply deletions in reverse order of dependencies\n await applyWorkflow(client, plans.workflow, \"delete\");\n await applyWorkflowJobFunctionExecutionPolicy(client, plans.workflowExecutionPolicy, \"delete\");\n await applyExecutor(client, plans.executor, \"delete\");\n await applyStaticWebsite(client, plans.staticWebsite, \"delete\");\n await applyAIGateway(client, plans.aiGateway, \"delete\");\n await applyApplication(client, plans.app, \"delete\");\n await applyPipeline(client, plans.pipeline, \"delete-resources\");\n await applyPipeline(client, plans.pipeline, \"delete-services\");\n await applyAuth(client, plans.auth, \"delete-resources\");\n await applyAuth(client, plans.auth, \"delete-services\");\n await applyIdP(client, plans.idp, \"delete-resources\");\n await applyIdP(client, plans.idp, \"delete-services\");\n await applyTailorDB(client, plans.tailorDB, \"delete-resources\");\n await applyTailorDB(client, plans.tailorDB, \"delete-services\");\n await applyFunctionRegistry(client, workspaceId, plans.functionRegistry, \"delete\");\n await applySecretManager(client, plans.secretManager, \"delete\");\n\n return { leftBehind };\n}\n\n/**\n * Remove all resources managed by the current application.\n * @param options - Remove options\n * @returns Promise that resolves when removal completes\n */\nexport async function remove(options?: RemoveOptions): Promise<void> {\n const { client, workspaceId, application, config } = await loadOptions(options);\n await execRemove(client, workspaceId, application, config);\n}\n\nexport const removeCommand = defineAppCommand({\n name: \"remove\",\n description: \"Remove all resources managed by the application from the workspace.\",\n args: z.strictObject({\n ...deploymentArgs,\n ...confirmationArgs,\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n const { client, workspaceId, application, config } = await loadOptions({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n });\n\n logger.info(`Planning removal of resources managed by \"${application.name}\"...`);\n logger.newline();\n\n const { leftBehind } = await execRemove(client, workspaceId, application, config, async () => {\n if (!args.yes) {\n const confirmed = await prompt.confirm({\n message: \"Are you sure you want to remove all resources?\",\n default: false,\n });\n if (!confirmed) {\n throw new Error(ml`\n Remove cancelled. No resources were deleted.\n To override, run again and confirm, or use --yes flag.\n `);\n }\n } else {\n logger.success(\"Removing all resources (--yes flag specified)...\");\n }\n });\n\n if (leftBehind) {\n logger.warn(ml`\n Resources tagged with \"${application.name}\" were left in place: they carry an application id this config does not match.\n Put that id in your config, or run deploy to take them over first, then remove again.\n `);\n return;\n }\n logger.success(`Successfully removed all resources managed by \"${application.name}\".`);\n },\n});\n","import { logger } from \"./logger\";\n\n/**\n * Warn that a feature is in beta.\n * @param {string} featureName - Name of the beta feature (e.g., \"tailordb migration\")\n */\nexport function logBetaWarning(featureName: string): void {\n logger.warn(\n `The '${featureName}' command is a beta feature and may introduce breaking changes in future releases.`,\n );\n logger.newline();\n}\n","import type { LoadedConfig } from \"./config-loader\";\n\n/**\n * Extracts every namespace key declared under `config.db`, including those\n * declared with `{ external: true }`.\n * @param config - Loaded application configuration.\n * @returns Namespace names in insertion order.\n */\nexport function extractAllNamespaces(config: LoadedConfig): string[] {\n const namespaces = new Set<string>();\n\n if (config.db) {\n for (const namespaceName of Object.keys(config.db)) {\n namespaces.add(namespaceName);\n }\n }\n\n return Array.from(namespaces);\n}\n\n/**\n * Extracts namespace keys under `config.db` that this app owns\n * (i.e. not declared with `{ external: true }`). Use this for destructive\n * operations like `tailordb truncate --all` to avoid touching namespaces\n * owned by other apps.\n * @param config - Loaded application configuration.\n * @returns Owned namespace names in insertion order.\n */\nexport function extractOwnedNamespaces(config: LoadedConfig): string[] {\n const namespaces = new Set<string>();\n\n if (config.db) {\n for (const [namespaceName, nsConfig] of Object.entries(config.db)) {\n if (\"external\" in nsConfig) continue;\n namespaces.add(namespaceName);\n }\n }\n\n return Array.from(namespaces);\n}\n","import { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { z } from \"zod\";\nimport { deploymentArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { createWorkspaceNameTransformer, resolveWorkspaceFolderName } from \"./workspace/transform\";\nimport type { OperatorClient } from \"#/cli/shared/client\";\nimport type { Application } from \"@tailor-platform/tailor-proto/application_resource_pb\";\n\nexport interface ShowOptions {\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n}\n\nexport interface WorkspaceInfo {\n workspaceId: string;\n workspaceName: string;\n workspaceFolderName?: string;\n workspaceRegion?: string;\n}\n\nexport interface ApplicationInfo {\n name: string;\n domain: string;\n url: string;\n auth: string;\n cors: string[];\n allowedIpAddresses: string[];\n disableIntrospection: boolean;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\nexport interface AIGatewayInfo {\n name: string;\n url: string;\n}\n\nexport interface ShowInfo extends ApplicationInfo, WorkspaceInfo {\n aiGateways: AIGatewayInfo[];\n}\n\nfunction applicationInfo(app: Application): ApplicationInfo {\n return {\n name: app.name,\n domain: app.domain,\n url: app.url,\n auth: app.authNamespace,\n cors: app.cors,\n allowedIpAddresses: app.allowedIpAddresses,\n disableIntrospection: app.disableIntrospection,\n createdAt: app.createTime ? timestampDate(app.createTime) : null,\n updatedAt: app.updateTime ? timestampDate(app.updateTime) : null,\n };\n}\n\nasync function fetchAIGateways(\n client: OperatorClient,\n workspaceId: string,\n names: string[],\n): Promise<AIGatewayInfo[]> {\n const gateways = await Promise.all(\n names.map(async (name) => {\n try {\n const { aigateway } = await client.getAIGateway({ workspaceId, aigatewayName: name });\n return aigateway ? { name: aigateway.name, url: aigateway.url } : undefined;\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return undefined;\n }\n throw error;\n }\n }),\n );\n return gateways.filter((gateway): gateway is AIGatewayInfo => gateway !== undefined);\n}\n\n/**\n * Show applied application information for the current workspace.\n * @param options - Show options\n * @returns Deployed application, workspace, and AI Gateway information\n */\nexport async function show(options?: ShowOptions): Promise<ShowInfo> {\n // Load and validate options\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n const { config } = await loadConfig(options?.configPath);\n const aiGatewayNames = config.aiGateways?.length\n ? [...new Set(config.aiGateways.map((gateway) => gateway.name))]\n : [];\n const [workspaceResp, resp, aiGateways] = await Promise.all([\n client.getWorkspace({\n workspaceId,\n }),\n client.getApplication({\n workspaceId,\n applicationName: config.name,\n }),\n fetchAIGateways(client, workspaceId, aiGatewayNames),\n ]);\n const { name, ...appInfo } = applicationInfo(\n assertDefined(resp.application, `application \"${config.name}\" not found in workspace`),\n );\n const workspace = workspaceResp.workspace;\n const workspaceFolderName = workspace ? await resolveWorkspaceFolderName(client, workspace) : \"\";\n\n return {\n name,\n workspaceId,\n workspaceName: workspace?.name ?? \"\",\n ...(workspaceFolderName ? { workspaceFolderName } : {}),\n workspaceRegion: workspace?.region ?? \"\",\n ...appInfo,\n aiGateways,\n };\n}\n\nconst showWorkspaceNameTransformer = createWorkspaceNameTransformer(\n \"workspaceName\",\n \"workspaceFolderName\",\n);\n\nexport const showCommand = defineAppCommand({\n name: \"show\",\n description: \"Show information about the deployed application.\",\n args: z.strictObject({\n ...deploymentArgs,\n }),\n run: async (args) => {\n // Execute show logic\n const appInfo = await show({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n });\n\n logger.out(appInfo, {\n display: { workspaceName: showWorkspaceNameTransformer, workspaceFolderName: null },\n });\n },\n});\n","import { setTimeout } from \"node:timers/promises\";\n\n/**\n * Create a simple progress reporter that writes updates to stderr.\n * @param label - Label to prefix progress output\n * @param total - Total number of steps\n * @returns Progress helpers\n */\nexport function createProgress(label: string, total: number) {\n let current = 0;\n\n const update = () => {\n current += 1;\n const percent = Math.round((current / total) * 100);\n process.stderr.write(`\\r${label} ${current}/${total} (${percent}%)`);\n };\n\n const finish = () => {\n process.stderr.write(\"\\n\");\n };\n\n return { update, finish };\n}\n\n/**\n * Wrap a promise with a timeout, rejecting if the timeout elapses first.\n * @template T\n * @param p - Promise to await\n * @param ms - Timeout in milliseconds\n * @param message - Error message on timeout\n * @returns Result of the original promise if it completes in time\n */\nexport async function withTimeout<T>(p: Promise<T>, ms: number, message: string): Promise<T> {\n return await Promise.race([\n p,\n setTimeout(ms).then(() => {\n throw new Error(message);\n }),\n ]);\n}\n","import * as fs from \"fs\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { lookup as mimeLookup } from \"mime-types\";\nimport pLimit from \"p-limit\";\nimport * as path from \"pathe\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient, type OperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { createProgress, withTimeout } from \"#/cli/shared/progress\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { UploadFileRequestSchema } from \"@tailor-platform/tailor-proto/staticwebsite_pb\";\n\nconst CHUNK_SIZE = 64 * 1024; // 64KB\nconst IGNORED_FILES = new Set([\".DS_Store\", \"thumbs.db\", \"desktop.ini\"]);\nfunction shouldIgnoreFile(filePath: string) {\n const fileName = path.basename(filePath).toLowerCase();\n return IGNORED_FILES.has(fileName);\n}\n\nexport type DeployResult = {\n url: string;\n skippedFiles: string[];\n};\n\n/**\n * Deploy a static website by creating a deployment, uploading files, and publishing it.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param name - Static website name\n * @param distDir - Directory containing static site files\n * @param showProgress - Whether to show upload progress\n * @returns Deployment result with URL and skipped files\n */\nexport async function deployStaticWebsite(\n client: OperatorClient,\n workspaceId: string,\n name: string,\n distDir: string,\n showProgress: boolean = true,\n): Promise<DeployResult> {\n const { deploymentId } = await client.createDeployment({\n workspaceId,\n name,\n });\n\n if (!deploymentId) {\n throw new Error(\"createDeployment returned empty deploymentId\");\n }\n\n const skippedFiles = await uploadDirectory(\n client,\n workspaceId,\n deploymentId,\n distDir,\n showProgress,\n );\n\n const { url } = await client.publishDeployment({\n workspaceId,\n deploymentId,\n });\n\n if (!url) {\n throw new Error(\"publishDeployment returned empty url\");\n }\n\n return { url, skippedFiles };\n}\n\nasync function uploadDirectory(\n client: OperatorClient,\n workspaceId: string,\n deploymentId: string,\n rootDir: string,\n showProgress: boolean,\n): Promise<string[]> {\n const files = await collectFiles(rootDir);\n if (files.length === 0) {\n logger.warn(`No files found under ${rootDir}`);\n return [];\n }\n\n const concurrency = 5;\n const limit = pLimit(concurrency);\n\n const total = files.length;\n const progress = showProgress ? createProgress(\"Uploading files\", total) : undefined;\n const skippedFiles: string[] = [];\n\n await Promise.all(\n files.map((relativePath) =>\n limit(async () => {\n await uploadSingleFile(\n client,\n workspaceId,\n deploymentId,\n rootDir,\n relativePath,\n skippedFiles,\n );\n if (progress) {\n progress.update();\n }\n }),\n ),\n );\n\n if (progress) {\n progress.finish();\n }\n\n return skippedFiles;\n}\n\n/**\n * Recursively collect all deployable files under the given directory.\n * @param rootDir - Root directory to scan\n * @param currentDir - Current relative directory (for recursion)\n * @returns List of file paths relative to rootDir\n */\nasync function collectFiles(rootDir: string, currentDir = \"\"): Promise<string[]> {\n const dirPath = path.join(rootDir, currentDir);\n\n const entries = await fs.promises.readdir(dirPath, {\n withFileTypes: true,\n });\n const files: string[] = [];\n\n for (const entry of entries) {\n const rel = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n const sub = await collectFiles(rootDir, rel);\n files.push(...sub);\n } else if (entry.isFile() && !entry.isSymbolicLink() && !shouldIgnoreFile(rel)) {\n files.push(rel);\n }\n }\n\n return files;\n}\n\nasync function uploadSingleFile(\n client: OperatorClient,\n workspaceId: string,\n deploymentId: string,\n rootDir: string,\n filePath: string,\n skippedFiles: string[],\n): Promise<void> {\n const absPath = path.join(rootDir, filePath);\n\n const mime = mimeLookup(filePath);\n\n if (!mime) {\n skippedFiles.push(`${filePath} (unsupported content type; no MIME mapping found)`);\n return;\n }\n\n const contentType = mime;\n\n const readStream = fs.createReadStream(absPath, {\n highWaterMark: CHUNK_SIZE,\n });\n\n async function* requestStream(): AsyncIterable<MessageInitShape<typeof UploadFileRequestSchema>> {\n yield {\n payload: {\n case: \"initialMetadata\",\n value: {\n workspaceId,\n deploymentId,\n filePath,\n contentType,\n },\n },\n };\n for await (const chunk of readStream) {\n yield {\n payload: {\n case: \"chunkData\",\n value: chunk as Buffer,\n },\n };\n }\n }\n\n async function uploadWithLogging() {\n try {\n await client.uploadFile(requestStream());\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.InvalidArgument) {\n skippedFiles.push(`${filePath} (server rejected file as invalid: ${error.message})`);\n return;\n }\n // For non-validation errors, fail the deployment as before.\n throw error;\n }\n }\n\n await withTimeout(\n uploadWithLogging(),\n // 2 minutes per file\n 2 * 60_000,\n `Upload timed out for \"${filePath}\"`,\n );\n}\n\n/**\n * Log skipped files after a deployment, including reasons for skipping.\n * @param skippedFiles - List of skipped file descriptions\n */\nexport function logSkippedFiles(skippedFiles: string[]) {\n if (skippedFiles.length === 0) {\n return;\n }\n logger.warn(\n \"Deployment completed, but some files failed to upload. These files may have unsupported content types or other validation issues. Please review the list below:\",\n );\n for (const file of skippedFiles) {\n logger.log(` - ${file}`);\n }\n}\n\nexport const deployCommand = defineAppCommand({\n name: \"deploy\",\n description: \"Deploy a static website from a local build directory.\",\n args: z.strictObject({\n ...workspaceArgs,\n name: arg(z.string(), {\n alias: \"n\",\n description: \"Static website name\",\n }),\n dir: arg(z.string(), {\n alias: \"d\",\n description: \"Path to the static website files\",\n completion: { type: \"directory\" },\n }),\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n logger.info(`Deploying static website \"${args.name}\" from directory: ${args.dir}`);\n const accessToken = await loadAccessToken({\n profile: args.profile,\n });\n const client = await initOperatorClient(accessToken);\n\n const name = args.name;\n const dir = path.resolve(process.cwd(), args.dir);\n const workspaceId = await loadWorkspaceId({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n\n if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) {\n throw new Error(`Directory not found or not a directory: ${dir}`);\n }\n\n const { url, skippedFiles } = await withTimeout(\n deployStaticWebsite(client, workspaceId, name, dir, !args.json),\n // 10 minutes\n 10 * 60_000,\n \"Deployment timed out after 10 minutes.\",\n );\n\n if (args.json) {\n logger.out({ name, workspaceId, url, skippedFiles });\n } else {\n logger.success(`Static website \"${name}\" deployed successfully. URL: ${url}`);\n logSkippedFiles(skippedFiles);\n }\n },\n});\n","import { spawn } from \"node:child_process\";\n\nconst DEFAULT_EDITOR = \"editor\";\n\nfunction normalizeEditorCommand(editor: string | undefined): string | undefined {\n const normalized = editor?.trim();\n return normalized && normalized.length > 0 ? normalized : undefined;\n}\n\n/**\n * Resolve an editor command only from explicit environment variables.\n * @returns Configured editor command, if any\n */\nexport function getConfiguredEditorCommand(): string | undefined {\n return normalizeEditorCommand(process.env.VISUAL) ?? normalizeEditorCommand(process.env.EDITOR);\n}\n\n/**\n * Resolve the editor command used for interactive file editing.\n * @returns Configured editor command or the system default fallback\n */\nexport function getEditorCommand(): string {\n return getConfiguredEditorCommand() ?? DEFAULT_EDITOR;\n}\n\nfunction parseEditorCommand(editor: string): {\n command: string;\n args: string[];\n} {\n const [command, ...args] = editor.trim().split(/\\s+/);\n\n if (!command) {\n throw new Error(\"Editor command is empty.\");\n }\n\n return {\n command,\n args,\n };\n}\n\n/**\n * Open a file in the resolved editor and wait for the process to exit.\n * @param filePath - File path to open\n * @param editor - Editor command string\n * @returns Whether an editor process was launched\n */\nexport async function openInEditor(\n filePath: string,\n editor = getEditorCommand(),\n): Promise<boolean> {\n const { command, args } = parseEditorCommand(editor);\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, [...args, filePath], {\n stdio: \"inherit\",\n detached: false,\n });\n\n child.once(\"error\", (error) => reject(error));\n child.once(\"close\", (code) => {\n if (code == null || code === 0) {\n resolve();\n return;\n }\n reject(new Error(`Editor exited with code ${code}.`));\n });\n });\n\n return true;\n}\n\n/**\n * Open a file only when an editor is explicitly configured in the environment.\n * @param filePath - File path to open\n * @returns Whether an editor process was launched\n */\nexport async function openInConfiguredEditor(filePath: string): Promise<boolean> {\n const editor = getConfiguredEditorCommand();\n if (!editor) {\n return false;\n }\n\n return await openInEditor(filePath, editor);\n}\n","/**\n * DB types generator for TailorDB migrations\n *\n * Generates db.ts file containing Kysely Transaction types\n * based on the schema snapshot at a specific migration point.\n */\n\nimport * as fs from \"node:fs/promises\";\nimport { assertDefined } from \"#/utils/assert\";\nimport {\n getMigrationFilePath,\n type SchemaSnapshot,\n type SnapshotFieldConfig,\n type TailorDBSnapshotType,\n} from \"./snapshot\";\nimport type { MigrationDiff } from \"./diff-calculator\";\n\n/**\n * Information about enum value changes\n */\ninterface EnumValueChange {\n /** Allowed values before the change */\n beforeValues: string[];\n /** Allowed values after the change */\n afterValues: string[];\n}\n\n/**\n * Information about breaking change fields that need special handling\n */\ninterface BreakingChangeFieldInfo {\n /** Map of typeName -> Set of fieldNames that are changing from optional to required */\n optionalToRequired: Map<string, Set<string>>;\n /** Map of typeName -> Map of fieldName -> SnapshotFieldConfig for newly added required fields */\n addedRequiredFields: Map<string, Map<string, SnapshotFieldConfig>>;\n /** Map of typeName -> Map of fieldName -> EnumValueChange for enum value changes */\n enumValueChanges: Map<string, Map<string, EnumValueChange>>;\n}\n\n/**\n * Extract breaking change field information from diff\n * @param {MigrationDiff} diff - Migration diff\n * @returns {BreakingChangeFieldInfo} Breaking change field information\n */\nfunction extractBreakingChangeFields(diff: MigrationDiff): BreakingChangeFieldInfo {\n const optionalToRequired = new Map<string, Set<string>>();\n const addedRequiredFields = new Map<string, Map<string, SnapshotFieldConfig>>();\n const enumValueChanges = new Map<string, Map<string, EnumValueChange>>();\n\n for (const change of diff.changes) {\n if (change.kind === \"field_modified\" || change.kind === \"field_type_modified\") {\n const { before, after } = change;\n\n // Check if this is an optional -> required change\n if (!before.required && after.required) {\n if (!optionalToRequired.has(change.typeName)) {\n optionalToRequired.set(change.typeName, new Set());\n }\n assertDefined(\n optionalToRequired.get(change.typeName),\n \"optionalToRequired entry missing\",\n ).add(change.fieldName);\n }\n\n // Check if this is an enum value change\n if (\n before.type === \"enum\" &&\n after.type === \"enum\" &&\n before.allowedValues &&\n after.allowedValues\n ) {\n // Check if there are any differences in allowed values\n const beforeValues = before.allowedValues.map((v) => v.value);\n const afterValues = after.allowedValues.map((v) => v.value);\n const beforeSet = new Set(beforeValues);\n const afterSet = new Set(afterValues);\n const hasChanges =\n beforeValues.some((v) => !afterSet.has(v)) || afterValues.some((v) => !beforeSet.has(v));\n\n if (hasChanges) {\n if (!enumValueChanges.has(change.typeName)) {\n enumValueChanges.set(change.typeName, new Map());\n }\n assertDefined(\n enumValueChanges.get(change.typeName),\n \"enumValueChanges entry missing\",\n ).set(change.fieldName, {\n beforeValues,\n afterValues,\n });\n }\n }\n } else if (change.kind === \"field_added\") {\n const { after } = change;\n\n // Required field added is a breaking change - add it as optional in db.ts\n // so migration script can set values for existing records\n if (after.required) {\n if (!addedRequiredFields.has(change.typeName)) {\n addedRequiredFields.set(change.typeName, new Map());\n }\n assertDefined(\n addedRequiredFields.get(change.typeName),\n \"addedRequiredFields entry missing\",\n ).set(change.fieldName, after);\n }\n }\n }\n\n return { optionalToRequired, addedRequiredFields, enumValueChanges };\n}\n\n/**\n * Generate the complete db.ts file content from a schema snapshot\n * @param {SchemaSnapshot} snapshot - Schema snapshot to generate types from\n * @param {MigrationDiff} [diff] - Optional migration diff for breaking change info\n * @returns {string} Generated db.ts file contents\n */\nfunction generateDbTypesFromSnapshot(snapshot: SchemaSnapshot, diff?: MigrationDiff): string {\n const types = Object.values(snapshot.types);\n if (types.length === 0) {\n return generateEmptyDbTypes(snapshot.namespace);\n }\n\n // Extract breaking change field information\n const breakingChangeFields = diff\n ? extractBreakingChangeFields(diff)\n : {\n optionalToRequired: new Map(),\n addedRequiredFields: new Map(),\n enumValueChanges: new Map(),\n };\n\n // Track which utility types are used\n const usedUtilityTypes = new Set<\"Timestamp\" | \"Serial\">();\n\n // Generate type definitions\n const typeDefinitions: string[] = [];\n for (const type of types) {\n const result = generateTableType(type, breakingChangeFields);\n if (result.usedTimestamp) usedUtilityTypes.add(\"Timestamp\");\n typeDefinitions.push(result.typeDef);\n }\n\n // Build imports\n // ColumnType is always needed for Generated and Timestamp utility types\n const imports: string[] = [\"type ColumnType\", \"type Transaction as KyselyTransaction\"];\n\n // Build utility type declarations\n const utilityTypeDeclarations: string[] = [];\n if (usedUtilityTypes.has(\"Timestamp\")) {\n utilityTypeDeclarations.push(\n \"type Timestamp = ColumnType<Date, Date | string, Date | string>;\",\n );\n }\n utilityTypeDeclarations.push(\n \"type Generated<T> = T extends ColumnType<infer S, infer I, infer U>\\n ? ColumnType<S, I | undefined, U>\\n : ColumnType<T, T | undefined, T>;\",\n );\n if (usedUtilityTypes.has(\"Serial\")) {\n utilityTypeDeclarations.push(\"type Serial<T = string | number> = ColumnType<T, never, never>;\");\n }\n\n // Build output\n const lines: string[] = [\n \"/**\",\n \" * Auto-generated Kysely types for migration script.\",\n \" * These types reflect the database schema state at this migration point.\",\n \" *\",\n \" * DO NOT EDIT - This file is auto-generated by the migration system.\",\n \" */\",\n \"\",\n `import { ${imports.join(\", \")} } from \"@tailor-platform/sdk/kysely\";`,\n 'import type { Env } from \"@tailor-platform/sdk\";',\n \"\",\n ...utilityTypeDeclarations,\n \"\",\n \"export interface Database {\",\n ...typeDefinitions,\n \"}\",\n \"\",\n \"export type Transaction = KyselyTransaction<Database>;\",\n \"\",\n \"/** Context passed as the second argument to the migration's `main` function. */\",\n \"export type MigrationContext = {\",\n \" env: keyof Env extends never ? Record<string, string | number | boolean> : Env;\",\n \"};\",\n ];\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Generate an empty db.ts file for migrations with no types\n * @param {string} namespace - Namespace name\n * @returns {string} Empty db.ts file contents\n */\nfunction generateEmptyDbTypes(namespace: string): string {\n return (\n [\n \"/**\",\n \" * Auto-generated Kysely types for migration script.\",\n ` * Namespace: ${namespace}`,\n \" *\",\n \" * DO NOT EDIT - This file is auto-generated by the migration system.\",\n \" */\",\n \"\",\n 'import { type Transaction as KyselyTransaction } from \"@tailor-platform/sdk/kysely\";',\n 'import type { Env } from \"@tailor-platform/sdk\";',\n \"\",\n \"// eslint-disable-next-line @typescript-eslint/no-empty-object-type\",\n \"export interface Database {}\",\n \"\",\n \"export type Transaction = KyselyTransaction<Database>;\",\n \"\",\n \"/** Context passed as the second argument to the migration's `main` function. */\",\n \"export type MigrationContext = {\",\n \" env: keyof Env extends never ? Record<string, string | number | boolean> : Env;\",\n \"};\",\n ].join(\"\\n\") + \"\\n\"\n );\n}\n\n/**\n * Generate table type definition from a snapshot type\n * @param {TailorDBSnapshotType} type - Snapshot type\n * @param {BreakingChangeFieldInfo} breakingChangeFields - Breaking change field info\n * @returns {{ typeDef: string; usedTimestamp: boolean; usedColumnType: boolean }} Generated type and utility type usage\n */\nfunction generateTableType(\n type: TailorDBSnapshotType,\n breakingChangeFields: BreakingChangeFieldInfo,\n): {\n typeDef: string;\n usedTimestamp: boolean;\n usedColumnType: boolean;\n} {\n const fieldLines: string[] = [];\n let usedTimestamp = false;\n let usedColumnType = false;\n\n // Add id field first\n fieldLines.push(\" id: Generated<string>;\");\n\n // Get fields that are changing from optional to required for this type\n const optionalToRequiredFields =\n breakingChangeFields.optionalToRequired.get(type.name) || new Set();\n\n // Get newly added required fields for this type\n const addedRequiredFields = breakingChangeFields.addedRequiredFields.get(type.name) || new Map();\n\n // Get enum value changes for this type\n const enumValueChangesForType = breakingChangeFields.enumValueChanges.get(type.name) || new Map();\n\n for (const [fieldName, fieldConfig] of Object.entries(type.fields)) {\n if (fieldName === \"id\") continue;\n\n const isOptionalToRequired = optionalToRequiredFields.has(fieldName);\n const enumValueChange = enumValueChangesForType.get(fieldName);\n const result = generateFieldType(fieldConfig, isOptionalToRequired, enumValueChange);\n fieldLines.push(` ${fieldName}: ${result.type};`);\n usedTimestamp = usedTimestamp || result.usedTimestamp;\n usedColumnType = usedColumnType || result.usedColumnType;\n }\n\n // Add newly added required fields with ColumnType (same as optional→required)\n // These fields are added as nullable in pre-migration, then become required in post-migration\n for (const [fieldName, fieldConfig] of addedRequiredFields) {\n // Treat as optional→required change (isOptionalToRequired: true)\n const result = generateFieldType(fieldConfig, true, undefined);\n fieldLines.push(` ${fieldName}: ${result.type};`);\n usedTimestamp = usedTimestamp || result.usedTimestamp;\n usedColumnType = usedColumnType || result.usedColumnType;\n }\n\n const typeDef = ` ${type.name}: {\\n${fieldLines.join(\"\\n\")}\\n }`;\n\n return { typeDef, usedTimestamp, usedColumnType };\n}\n\nfunction mapToTsType(fieldType: string): {\n type: string;\n usedTimestamp: boolean;\n} {\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n return { type: \"string\", usedTimestamp: false };\n case \"integer\":\n case \"float\":\n case \"number\":\n return { type: \"number\", usedTimestamp: false };\n case \"date\":\n return { type: \"string\", usedTimestamp: false };\n case \"datetime\":\n return { type: \"Timestamp\", usedTimestamp: true };\n case \"bool\":\n case \"boolean\":\n return { type: \"boolean\", usedTimestamp: false };\n default:\n return { type: \"string\", usedTimestamp: false };\n }\n}\n\nfunction formatEnumUnion(values: string[]): string {\n return values.map((v) => `\"${v}\"`).join(\" | \");\n}\n\nfunction generateEnumChangeColumnType(\n enumValueChange: EnumValueChange,\n config: SnapshotFieldConfig,\n): string {\n const allValues = [...new Set([...enumValueChange.beforeValues, ...enumValueChange.afterValues])];\n const selectType = formatEnumUnion(allValues);\n const afterType = formatEnumUnion(enumValueChange.afterValues);\n\n if (config.array && !config.required) {\n return `ColumnType<(${selectType})[] | null, (${afterType})[] | null, (${afterType})[] | null>`;\n }\n if (config.array) {\n return `ColumnType<(${selectType})[], (${afterType})[], (${afterType})[]>`;\n }\n if (!config.required) {\n return `ColumnType<(${selectType}) | null, (${afterType}) | null, (${afterType}) | null>`;\n }\n return `ColumnType<${selectType}, ${afterType}, ${afterType}>`;\n}\n\nfunction generateOptionalToRequiredDateColumnType(config: SnapshotFieldConfig): string | null {\n if (config.type !== \"date\" && config.type !== \"datetime\") return null;\n\n if (config.type === \"date\") {\n if (config.array) {\n return \"ColumnType<string[] | null, string[], string[]>\";\n }\n\n return \"ColumnType<string | null, string, string>\";\n }\n\n if (config.array) {\n return \"ColumnType<Date[] | null, (Date | string)[], (Date | string)[]>\";\n }\n\n return \"ColumnType<Date | null, Date | string, Date | string>\";\n}\n\n/**\n * Generate field type from snapshot field config\n * @param {SnapshotFieldConfig} config - Field configuration\n * @param {boolean} isOptionalToRequired - Whether this field is changing from optional to required\n * @param {EnumValueChange} [enumValueChange] - Enum value change info if applicable\n * @returns {{ type: string; usedTimestamp: boolean; usedColumnType: boolean }} Generated type string and utility type usage\n */\nfunction generateFieldType(\n config: SnapshotFieldConfig,\n isOptionalToRequired: boolean,\n enumValueChange?: EnumValueChange,\n): {\n type: string;\n usedTimestamp: boolean;\n usedColumnType: boolean;\n} {\n // Handle enum value changes specially\n if (enumValueChange) {\n return {\n type: generateEnumChangeColumnType(enumValueChange, config),\n usedTimestamp: false,\n usedColumnType: true,\n };\n }\n\n // Get base type\n let baseType: string;\n let usedTimestamp = false;\n\n if (config.type === \"enum\") {\n const enumValues = config.allowedValues?.map((v) => v.value) ?? [];\n baseType = enumValues.length > 0 ? formatEnumUnion(enumValues) : \"string\";\n } else {\n const mapped = mapToTsType(config.type);\n baseType = mapped.type;\n usedTimestamp = mapped.usedTimestamp;\n }\n\n // Apply array modifier\n let type = baseType;\n if (config.array) {\n const needsParens =\n config.type === \"enum\" && config.allowedValues && config.allowedValues.length > 0;\n type = needsParens ? `(${baseType})[]` : `${baseType}[]`;\n }\n\n // Handle nullable/required modifiers\n if (isOptionalToRequired) {\n const dateColumnType = generateOptionalToRequiredDateColumnType(config);\n if (dateColumnType) {\n return {\n type: dateColumnType,\n usedTimestamp: false,\n usedColumnType: true,\n };\n }\n\n // For fields changing from optional to required:\n // SELECT returns T | null (existing data might be null)\n // INSERT/UPDATE requires T (must provide a value)\n return {\n type: `ColumnType<${type} | null, ${type}, ${type}>`,\n usedTimestamp,\n usedColumnType: true,\n };\n }\n\n if (!config.required) {\n type = `${type} | null`;\n }\n\n return { type, usedTimestamp, usedColumnType: false };\n}\n\n/**\n * Write db.ts file for a migration\n * @param {SchemaSnapshot} snapshot - Schema snapshot to generate types from\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} migrationNumber - Migration number\n * @param {MigrationDiff} [diff] - Optional migration diff for breaking change info\n * @returns {Promise<string>} Path to the written file\n */\nexport async function writeDbTypesFile(\n snapshot: SchemaSnapshot,\n migrationsDir: string,\n migrationNumber: number,\n diff?: MigrationDiff,\n): Promise<string> {\n const content = generateDbTypesFromSnapshot(snapshot, diff);\n const filePath = getMigrationFilePath(migrationsDir, migrationNumber, \"db\");\n await fs.writeFile(filePath, content);\n return filePath;\n}\n","/**\n * Template generator for TailorDB migrations\n *\n * Generates migration files in directory structure:\n * - XXXX/schema.json - Full schema snapshot (initial migration 0000)\n * - XXXX/diff.json - Schema diff (subsequent migrations 0001+)\n * - XXXX/migrate.ts - Data migration script (when breaking changes exist)\n * - XXXX/db.ts - Generated types for migration script\n */\n\nimport * as fs from \"node:fs/promises\";\nimport { writeDbTypesFile } from \"./db-types-generator\";\nimport {\n DEFAULT_DECIMAL_SCALE,\n getMigrationDirPath,\n getMigrationFilePath,\n isBreakingIndexChange,\n type SchemaSnapshot,\n} from \"./snapshot\";\nimport type { MigrationDiff, DiffChange } from \"./diff-calculator\";\n\n/** Marker left in generated migration scripts until their normalization logic is reviewed. */\nexport const MIGRATION_REVIEW_REQUIRED_MARKER = \"TODO(tailor-migration-review)\";\n\n/**\n * Check if a file exists\n * @param {string} filePath - Path to check\n * @returns {Promise<boolean>} True if file exists\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Ensure a file does not already exist, throwing an error if it does\n * @param {string} filePath - Path to check\n * @throws {Error} If file already exists\n */\nasync function ensureFileNotExists(filePath: string): Promise<void> {\n if (await fileExists(filePath)) {\n throw new Error(`Migration file already exists: ${filePath}`);\n }\n}\n\ninterface GenerateSchemaResult {\n filePath: string;\n migrationNumber: number;\n}\n\ninterface GenerateDiffResult {\n diffFilePath: string;\n migrateFilePath?: string;\n dbTypesFilePath?: string;\n migrationNumber: number;\n}\n\n/**\n * Generate the initial schema snapshot file\n * @param {SchemaSnapshot} snapshot - Schema snapshot to save\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} migrationNumber - Migration number\n * @returns {Promise<GenerateSchemaResult>} Generated file info\n */\nexport async function generateSchemaFile(\n snapshot: SchemaSnapshot,\n migrationsDir: string,\n migrationNumber: number,\n): Promise<GenerateSchemaResult> {\n // Create migration directory\n const migrationDir = getMigrationDirPath(migrationsDir, migrationNumber);\n await fs.mkdir(migrationDir, { recursive: true });\n\n const filePath = getMigrationFilePath(migrationsDir, migrationNumber, \"schema\");\n\n // Check if file already exists to prevent accidental overwrite\n await ensureFileNotExists(filePath);\n\n await fs.writeFile(filePath, JSON.stringify(snapshot, null, 2));\n\n return {\n filePath,\n migrationNumber,\n };\n}\n\n/**\n * Generate diff and optional migration script files\n * @param {MigrationDiff} diff - Migration diff to save\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} migrationNumber - Migration number\n * @param {SchemaSnapshot} previousSnapshot - Previous schema snapshot (for db.ts generation)\n * @param {string} [description] - Optional description for the migration\n * @returns {Promise<GenerateDiffResult>} Generated file info\n */\nexport async function generateDiffFiles(\n diff: MigrationDiff,\n migrationsDir: string,\n migrationNumber: number,\n previousSnapshot: SchemaSnapshot,\n description?: string,\n): Promise<GenerateDiffResult> {\n // Create migration directory\n const migrationDir = getMigrationDirPath(migrationsDir, migrationNumber);\n await fs.mkdir(migrationDir, { recursive: true });\n\n // Build file paths\n const diffFilePath = getMigrationFilePath(migrationsDir, migrationNumber, \"diff\");\n const migrateFilePath = getMigrationFilePath(migrationsDir, migrationNumber, \"migrate\");\n const dbTypesFilePath = getMigrationFilePath(migrationsDir, migrationNumber, \"db\");\n\n // Check if files already exist to prevent accidental overwrite\n await ensureFileNotExists(diffFilePath);\n if (diff.requiresMigrationScript) {\n await ensureFileNotExists(migrateFilePath);\n await ensureFileNotExists(dbTypesFilePath);\n }\n\n // Add description if provided\n if (description) {\n diff = { ...diff, description };\n }\n\n // Write diff file\n await fs.writeFile(diffFilePath, JSON.stringify(diff, null, 2));\n\n const result: GenerateDiffResult = {\n diffFilePath,\n migrationNumber,\n };\n\n // Generate migration script and db types only if migration script is required\n if (diff.requiresMigrationScript) {\n const scriptContent = generateMigrationScript(diff);\n await fs.writeFile(migrateFilePath, scriptContent);\n result.migrateFilePath = migrateFilePath;\n\n // Generate db.ts with types based on the PREVIOUS schema state\n // (the state before this migration runs)\n // Pass diff to generate ColumnType for optional->required fields\n await writeDbTypesFile(previousSnapshot, migrationsDir, migrationNumber, diff);\n result.dbTypesFilePath = dbTypesFilePath;\n }\n\n return result;\n}\n\n/**\n * Generate migration script content based on diff\n * @param {MigrationDiff} diff - Migration diff\n * @returns {string} Migration script content\n */\nexport function generateMigrationScript(diff: MigrationDiff): string {\n const updates: string[] = [];\n\n for (const change of diff.changes) {\n const decimalScaleScript = generateDecimalScaleChangeScript(change);\n updates.push(...generateChangeScripts(change, decimalScaleScript !== null));\n if (decimalScaleScript) {\n updates.push(decimalScaleScript);\n\n const uniqueConstraintScript = generateUniqueConstraintScript(change);\n if (uniqueConstraintScript) {\n updates.push(uniqueConstraintScript);\n }\n }\n }\n\n if (updates.length === 0) {\n updates.push(` // No data migration needed for this schema change\n // Add custom data transformations if required`);\n }\n\n return `/**\n * Migration script for ${diff.namespace}\n *\n * This script runs between the Pre-migration and Post-migration phases of\n * 'tailor deploy'. Use it to transform existing data so that the schema\n * change can complete safely (for breaking changes, this is hard-required;\n * for warning-tier changes it is optional). Edit this file to implement\n * your data migration logic.\n *\n * The transaction is managed by the deploy command.\n * If any operation fails, all changes will be rolled back.\n */\n\nimport type { Transaction } from \"./db\";\n\nexport async function main(trx: Transaction): Promise<void> {\n${updates.join(\"\\n\\n\")}\n}\n`;\n}\n\n/**\n * Generate migration test file content\n * @param {MigrationDiff} diff - Migration diff\n * @returns {string} Migration test file content\n */\nexport function generateMigrationTestScript(diff: MigrationDiff): string {\n return `/**\n * Unit test for the ${diff.namespace} migration script.\n *\n * The mock compiles queries to the same SQL as the deployed migration, so the\n * test verifies the exact statements migrate.ts issues. Stage the rows each\n * query returns, run main() inside a transaction, then assert the executed\n * statements.\n */\n\nimport { createKyselyMock } from \"@tailor-platform/sdk/vitest\";\nimport { describe, expect, test } from \"vitest\";\nimport type { Database } from \"./db\";\nimport { main } from \"./migrate\";\n\ndescribe(${JSON.stringify(`${diff.namespace} migration`)}, () => {\n test(\"issues the intended statements\", async () => {\n const mock = createKyselyMock<Database>();\n\n // Stage the rows each query returns, in execution order:\n // mock.enqueueResult([{ id: \"record-1\" }]);\n\n // Pass a MigrationContext when your main uses env: main(trx, { env: { ... } })\n await mock.withTx((trx) => main(trx));\n\n // Replace with assertions on the statements the script must issue:\n // expect(mock.updates).toHaveLength(1);\n // expect(mock.updates[0]?.updateValues()).toEqual({ field: \"value\" });\n expect(\n mock.executedQueries.map((query) => ({ sql: query.sql, parameters: query.parameters })),\n ).toMatchSnapshot();\n });\n});\n`;\n}\n\n/**\n * Generate scripts for a single change\n * @param {DiffChange} change - Diff change to generate script for\n * @param {boolean} deferUniqueConstraint - Generate the unique check after decimal re-serialization\n * @returns {string[]} Script contents, or an empty array if no script is needed\n */\nfunction generateChangeScripts(change: DiffChange, deferUniqueConstraint = false): string[] {\n if (change.kind === \"index_added\" || change.kind === \"index_modified\") {\n const before = change.kind === \"index_modified\" ? change.before : undefined;\n if (!isBreakingIndexChange(change.typeName, change.indexName, before, change.after)) {\n return [];\n }\n const fields = change.after.fields;\n const fieldList = fields.map((f) => `\"${f}\"`).join(\", \");\n const whereClauses = fields.map((f) => `.where(\"${f}\", \"=\", dup.${f})`).join(\"\\n \");\n return [\n ` // Resolve duplicate (${fields.join(\", \")}) combinations before unique index \"${change.indexName}\" is enforced\n {\n const duplicates = await trx\n .selectFrom(\"${change.typeName}\")\n .select([${fieldList}])\n .groupBy([${fieldList}])\n .having((eb) => eb.fn.count(\"id\"), \">\", 1)\n .execute();\n for (const dup of duplicates) {\n const records = await trx\n .selectFrom(\"${change.typeName}\")\n .select([\"id\"])\n ${whereClauses}\n .execute();\n // Keep the first record; update or delete the others so the combination becomes unique\n for (let i = 1; i < records.length; i++) {\n await trx\n .updateTable(\"${change.typeName}\")\n .set({ ${fields[0]}: null }) // TODO: Set appropriate unique value\n .where(\"id\", \"=\", records[i].id)\n .execute();\n }\n }\n }`,\n ];\n }\n\n if (change.kind === \"field_added\") {\n const field = change.after;\n if (field.required) {\n return [\n ` // Populate ${change.fieldName} for existing ${change.typeName} records\n await trx\n .updateTable(\"${change.typeName}\")\n .set({\n ${change.fieldName}: null, // TODO: Set appropriate default value\n })\n .execute();`,\n ];\n }\n return [];\n }\n\n if (change.kind !== \"field_modified\" && change.kind !== \"field_type_modified\") {\n // No data migration needed for type_added, type_removed, or field_removed\n return [];\n }\n\n const { before, after } = change;\n const scripts: string[] = [];\n\n if (change.kind === \"field_type_modified\") {\n scripts.push(generateFieldTypeChangeScript(change));\n }\n\n // Optional to required\n if (!before.required && after.required) {\n scripts.push(` // Set ${change.fieldName} for ${change.typeName} records where it is null\n await trx\n .updateTable(\"${change.typeName}\")\n .set({\n ${change.fieldName}: null, // TODO: Set appropriate default value\n })\n .where(\"${change.fieldName}\", \"is\", null)\n .execute();`);\n }\n\n // Note: Array to single value change is rejected in generate.ts\n // No script generation needed here\n\n // Unique constraint added\n if (!deferUniqueConstraint) {\n const uniqueConstraintScript = generateUniqueConstraintScript(change);\n if (uniqueConstraintScript) {\n scripts.push(uniqueConstraintScript);\n }\n }\n\n // Enum values removed\n if (before.type === \"enum\" && after.type === \"enum\") {\n const beforeValues = (before.allowedValues ?? []).map((v) => v.value);\n const afterValues = (after.allowedValues ?? []).map((v) => v.value);\n const removedValues = beforeValues.filter((v) => !afterValues.includes(v));\n if (removedValues.length > 0) {\n const defaultValue = afterValues[0] ?? \"NEW_VALUE\";\n scripts.push(` // Migrate records with removed enum values: ${removedValues.join(\", \")}\n await trx\n .updateTable(\"${change.typeName}\")\n .set({ ${change.fieldName}: \"${defaultValue}\" }) // TODO: Set appropriate value\n .where(\"${change.fieldName}\", \"in\", [${removedValues.map((v) => `\"${v}\"`).join(\", \")}])\n .execute();`);\n }\n }\n\n // Foreign key relationship changed\n if (\n before.foreignKeyType &&\n after.foreignKeyType &&\n before.foreignKeyType !== after.foreignKeyType\n ) {\n scripts.push(` // Migrate ${change.fieldName} references from ${before.foreignKeyType} to ${after.foreignKeyType}\n // Find records that don't have a valid reference in the new target table\n {\n const orphanedRecords = await trx\n .selectFrom(\"${change.typeName}\")\n .leftJoin(\"${after.foreignKeyType}\", \"${change.typeName}.${change.fieldName}\", \"${after.foreignKeyType}.id\")\n .select([\"${change.typeName}.id\", \"${change.typeName}.${change.fieldName}\"])\n .where(\"${after.foreignKeyType}.id\", \"is\", null)\n .where(\"${change.typeName}.${change.fieldName}\", \"is not\", null)\n .execute();\n for (const record of orphanedRecords) {\n await trx\n .updateTable(\"${change.typeName}\")\n .set({ ${change.fieldName}: null }) // TODO: Set appropriate new reference\n .where(\"id\", \"=\", record.id)\n .execute();\n }\n }`);\n }\n\n return scripts;\n}\n\nfunction generateFieldTypeChangeScript(\n change: Extract<DiffChange, { kind: \"field_type_modified\" }>,\n): string {\n return ` // Normalize ${change.typeName}.${change.fieldName} from ${change.before.type} to ${change.after.type} while the previous type is still active\n {\n let lastId: string | undefined;\n while (true) {\n let query = trx\n .selectFrom(\"${change.typeName}\")\n .select([\"id\", \"${change.fieldName}\"])\n .where(\"${change.fieldName}\", \"is not\", null)\n .orderBy(\"id\", \"asc\")\n .limit(100);\n if (lastId) {\n query = query.where(\"id\", \">\", lastId);\n }\n const rows = await query.execute();\n if (rows.length === 0) break;\n\n for (const row of rows) {\n // ${MIGRATION_REVIEW_REQUIRED_MARKER}: Remove this marker and the \\`never\\` annotation after reviewing the normalization.\n // Keep the value accepted by the active ${change.before.type} type and castable to ${change.after.type}.\n const sourceValue = row.${change.fieldName};\n if (sourceValue === null) continue;\n const normalizedValue: never = sourceValue;\n if (Object.is(normalizedValue, sourceValue)) continue;\n await trx\n .updateTable(\"${change.typeName}\")\n .set({ [${JSON.stringify(change.fieldName)}]: normalizedValue })\n .where(\"id\", \"=\", row.id)\n .execute();\n }\n lastId = rows[rows.length - 1]!.id;\n }\n }`;\n}\n\nfunction generateUniqueConstraintScript(change: DiffChange): string | null {\n if (change.kind !== \"field_modified\" && change.kind !== \"field_type_modified\") return null;\n\n const { before, after } = change;\n if ((before.unique ?? false) || !(after.unique ?? false)) return null;\n\n const duplicateResolution =\n change.kind === \"field_type_modified\"\n ? ` if (records.length > 1) {\n throw new Error(\n \"TODO: Resolve duplicate ${change.typeName}.${change.fieldName} values before adding the unique constraint\",\n );\n }`\n : ` // Keep first record, add suffix to others\n for (let i = 1; i < records.length; i++) {\n await trx\n .updateTable(\"${change.typeName}\")\n .set({ ${change.fieldName}: \\`\\${records[i].${change.fieldName}}_\\${i}\\` }) // TODO: Set appropriate unique value\n .where(\"id\", \"=\", records[i].id)\n .execute();\n }`;\n\n return ` // Ensure ${change.fieldName} values are unique before adding constraint\n {\n const duplicates = await trx\n .selectFrom(\"${change.typeName}\")\n .select([\"${change.fieldName}\"])\n .groupBy(\"${change.fieldName}\")\n .having((eb) => eb.fn.count(\"id\"), \">\", 1)\n .execute();\n for (const dup of duplicates) {\n // Load every record in this duplicate group before resolving it\n const records = await trx\n .selectFrom(\"${change.typeName}\")\n .select([\"id\", \"${change.fieldName}\"])\n .where(\"${change.fieldName}\", \"=\", dup.${change.fieldName})\n .execute();\n${duplicateResolution}\n }\n }`;\n}\n\nfunction generateDecimalScaleChangeScript(change: DiffChange): string | null {\n if (change.kind !== \"field_modified\") return null;\n\n const { before, after } = change;\n if (before.type !== \"decimal\" || after.type !== \"decimal\" || before.scale === after.scale)\n return null;\n\n const valueExpression =\n !before.required && after.required ? `row.${change.fieldName}!` : `row.${change.fieldName}`;\n const beforeScale = before.scale ?? DEFAULT_DECIMAL_SCALE;\n const afterScale = after.scale ?? DEFAULT_DECIMAL_SCALE;\n const roundingWarning =\n afterScale < beforeScale\n ? `\n // Values that exceed the new scale may be rounded half-up, so review the\n // resulting precision before deploying.`\n : \"\";\n\n return ` // Re-save existing ${change.typeName} rows so ${change.fieldName} is stored under the new scale.\n // This is a workaround for a platform-side gap where rows written under the\n // previous scale could fail on later updates until re-saved. Keep it unless\n // your platform is confirmed to handle stored values across scale changes.${roundingWarning}\n {\n let lastId: string | undefined;\n while (true) {\n let query = trx\n .selectFrom(\"${change.typeName}\")\n .select([\"id\", \"${change.fieldName}\"])\n .where(\"${change.fieldName}\", \"is not\", null)\n .orderBy(\"id\", \"asc\")\n .limit(100);\n if (lastId) {\n query = query.where(\"id\", \">\", lastId);\n }\n const rows = await query.execute();\n if (rows.length === 0) break;\n\n for (const row of rows) {\n await trx\n .updateTable(\"${change.typeName}\")\n .set({ ${change.fieldName}: ${valueExpression} })\n .where(\"id\", \"=\", row.id)\n .where(\"${change.fieldName}\", \"=\", ${valueExpression})\n .execute();\n }\n lastId = rows[rows.length - 1]!.id;\n }\n }`;\n}\n\n/**\n * Check if a migration script exists for a given migration number\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} migrationNumber - Migration number\n * @returns {Promise<boolean>} True if script exists\n */\nexport async function migrationScriptExists(\n migrationsDir: string,\n migrationNumber: number,\n): Promise<boolean> {\n const filePath = getMigrationFilePath(migrationsDir, migrationNumber, \"migrate\");\n return fileExists(filePath);\n}\n\n/**\n * Get the migration script path for a given migration number\n * @param {string} migrationsDir - Migrations directory path\n * @param {number} migrationNumber - Migration number\n * @returns {string} Full path to migration script\n */\nexport function getMigrationScriptPath(migrationsDir: string, migrationNumber: number): string {\n return getMigrationFilePath(migrationsDir, migrationNumber, \"migrate\");\n}\n","/**\n * Script command for TailorDB migrations\n *\n * Adds a `migrate.ts` (and supporting `db.ts`) template to an existing\n * migration directory, optionally with a `migrate.test.ts` unit-test\n * scaffold. Useful for warning-tier changes where users may want to\n * write a custom data migration even though the change does not\n * automatically require one.\n */\n\nimport * as fs from \"node:fs\";\nimport * as fsPromises from \"node:fs/promises\";\nimport * as path from \"pathe\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { configArg } from \"#/cli/shared/args\";\nimport { logBetaWarning } from \"#/cli/shared/beta\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { getConfiguredEditorCommand, openInConfiguredEditor } from \"#/cli/shared/editor\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { getNamespacesWithMigrations, type NamespaceWithMigrations } from \"./config\";\nimport { writeDbTypesFile } from \"./db-types-generator\";\nimport { parseMigrationNumberArg } from \"./migration-number\";\nimport {\n formatMigrationNumber,\n getMigrationFilePath,\n loadDiff,\n reconstructSnapshotFromMigrations,\n INITIAL_SCHEMA_NUMBER,\n} from \"./snapshot\";\nimport { generateMigrationScript, generateMigrationTestScript } from \"./template-generator\";\nimport type { ScriptSkippedInfo } from \"./diff-calculator\";\n\nexport interface ScriptOptions {\n configPath?: string;\n number: string;\n namespace?: string;\n noScript?: boolean;\n reason?: string;\n withTest?: boolean;\n}\n\nexport interface MarkScriptSkippedOptions {\n migrationsDir: string;\n migrationNumber: number;\n reason: string;\n}\n\nexport interface AddMigrationScriptFilesOptions {\n migrationsDir: string;\n migrationNumber: number;\n withTest?: boolean;\n}\n\nexport interface AddMigrationScriptFilesResult {\n /** Created migrate.ts path; undefined when the script already existed. */\n migratePath?: string;\n /** Created db.ts path; undefined when the script already existed. */\n dbTypesPath?: string;\n /** Created migrate.test.ts path; undefined unless withTest was set. */\n testPath?: string;\n /** True when a stale --no-script acknowledgment was cleared because migrate.ts already exists. */\n clearedScriptSkip?: boolean;\n}\n\n/**\n * Record in diff.json that a migration requiring a script, or one with\n * data-loss warnings, intentionally has none.\n * @param {MarkScriptSkippedOptions} options - Target migration and skip reason\n * @returns {ScriptSkippedInfo} The recorded acknowledgment\n */\nexport function markMigrationScriptSkipped(options: MarkScriptSkippedOptions): ScriptSkippedInfo {\n const { migrationsDir, migrationNumber, reason } = options;\n const label = formatMigrationNumber(migrationNumber);\n const normalizedReason = reason.trim();\n if (!normalizedReason) {\n throw new Error(\"Migration script skip reason must not be empty.\");\n }\n\n const diffPath = getMigrationFilePath(migrationsDir, migrationNumber, \"diff\");\n if (!fs.existsSync(diffPath)) {\n throw new Error(`Migration ${label} not found in ${migrationsDir}. Expected ${diffPath}.`);\n }\n\n const diff = loadDiff(diffPath);\n if (!diff.requiresMigrationScript && !diff.hasWarnings) {\n throw new Error(\n `Migration ${label} does not require a migration script and has no data-loss warnings; nothing to skip.`,\n );\n }\n if (diff.scriptSkipped) {\n throw new Error(\n `Migration ${label} already has a script skip recorded ` +\n `(${diff.scriptSkipped.acknowledgedAt}: ${diff.scriptSkipped.reason}).`,\n );\n }\n\n const migratePath = getMigrationFilePath(migrationsDir, migrationNumber, \"migrate\");\n if (fs.existsSync(migratePath)) {\n throw new Error(\n `Migration script exists at ${migratePath}. ` +\n `Delete migrate.ts first if this migration should run without a script.`,\n );\n }\n\n const scriptSkipped: ScriptSkippedInfo = {\n reason: normalizedReason,\n acknowledgedAt: new Date().toISOString(),\n };\n\n // Edit the raw JSON so keys unknown to this SDK version survive the rewrite.\n const raw = JSON.parse(fs.readFileSync(diffPath, \"utf-8\")) as Record<string, unknown>;\n raw.scriptSkipped = scriptSkipped;\n fs.writeFileSync(diffPath, JSON.stringify(raw, null, 2));\n\n return scriptSkipped;\n}\n\n/**\n * Remove a script skip acknowledgment after a real migration script is created.\n * @param diffPath - Migration diff file to update\n */\nexport function clearMigrationScriptSkipped(diffPath: string): void {\n const raw = JSON.parse(fs.readFileSync(diffPath, \"utf-8\")) as Record<string, unknown>;\n if (!Object.hasOwn(raw, \"scriptSkipped\")) return;\n delete raw.scriptSkipped;\n fs.writeFileSync(diffPath, JSON.stringify(raw, null, 2));\n}\n\n/**\n * Create migration script files (migrate.ts, db.ts, and optionally migrate.test.ts)\n * in an existing migration directory. When migrate.ts already exists and withTest\n * is set, only the test file is added. An existing migrate.ts clears a stale\n * --no-script acknowledgment instead of failing.\n * @param {AddMigrationScriptFilesOptions} options - Target migration and file selection\n * @returns {Promise<AddMigrationScriptFilesResult>} Paths of the created files\n */\nexport async function addMigrationScriptFiles(\n options: AddMigrationScriptFilesOptions,\n): Promise<AddMigrationScriptFilesResult> {\n const { migrationsDir, migrationNumber, withTest = false } = options;\n const label = formatMigrationNumber(migrationNumber);\n\n const diffPath = getMigrationFilePath(migrationsDir, migrationNumber, \"diff\");\n if (!fs.existsSync(diffPath)) {\n throw new Error(`Migration ${label} not found in ${migrationsDir}. Expected ${diffPath}.`);\n }\n\n const diff = loadDiff(diffPath);\n const migratePath = getMigrationFilePath(migrationsDir, migrationNumber, \"migrate\");\n const migrateExists = fs.existsSync(migratePath);\n const result: AddMigrationScriptFilesResult = {};\n\n if (migrateExists && diff.scriptSkipped) {\n // A hand-placed migrate.ts takes precedence over an earlier --no-script\n // acknowledgment; clear the stale record instead of failing.\n clearMigrationScriptSkipped(diffPath);\n result.clearedScriptSkip = true;\n if (!withTest) return result;\n } else if (migrateExists && !withTest) {\n throw new Error(`Migration script already exists at ${migratePath}.`);\n }\n\n const testPath = getMigrationFilePath(migrationsDir, migrationNumber, \"test\");\n if (withTest && fs.existsSync(testPath)) {\n throw new Error(`Migration test already exists at ${testPath}.`);\n }\n\n if (migrateExists && withTest) {\n const dbTypesPath = getMigrationFilePath(migrationsDir, migrationNumber, \"db\");\n if (!fs.existsSync(dbTypesPath)) {\n throw new Error(\n `Generated types not found at ${dbTypesPath}. ` +\n `The test scaffold imports Database from ./db; restore db.ts before adding a test.`,\n );\n }\n }\n\n if (!migrateExists) {\n // Reconstruct the schema state immediately before this migration so that\n // db.ts has Kysely types for the previous shape of the data.\n const previousSnapshot = reconstructSnapshotFromMigrations(migrationsDir, migrationNumber - 1);\n if (!previousSnapshot) {\n throw new Error(\n `Could not reconstruct previous schema for migration ${label}. Make sure migration ${INITIAL_SCHEMA_NUMBER} exists.`,\n );\n }\n\n await fsPromises.writeFile(migratePath, generateMigrationScript(diff));\n result.migratePath = migratePath;\n result.dbTypesPath = await writeDbTypesFile(\n previousSnapshot,\n migrationsDir,\n migrationNumber,\n diff,\n );\n clearMigrationScriptSkipped(diffPath);\n }\n\n if (withTest) {\n await fsPromises.writeFile(testPath, generateMigrationTestScript(diff));\n result.testPath = testPath;\n }\n\n return result;\n}\n\n/**\n * Add a migrate.ts template to an existing migration directory.\n * @param {ScriptOptions} options - Command options\n */\nasync function script(options: ScriptOptions): Promise<void> {\n logBetaWarning(\"tailordb migration\");\n\n const migrationNumber = parseMigrationNumberArg(options.number);\n\n if (migrationNumber === INITIAL_SCHEMA_NUMBER) {\n throw new Error(\n `Migration ${options.number} is the initial schema snapshot and cannot have a migration script.`,\n );\n }\n\n const { config } = await loadConfig(options.configPath);\n const configDir = path.dirname(config.path);\n\n const namespacesWithMigrations = getNamespacesWithMigrations(config, configDir);\n if (namespacesWithMigrations.length === 0) {\n throw new Error(\"No TailorDB services with migrations configuration found\");\n }\n\n const targetNamespace = resolveTargetNamespace(namespacesWithMigrations, options.namespace);\n const { migrationsDir } = assertDefined(\n namespacesWithMigrations.find((ns) => ns.namespace === targetNamespace),\n \"namespace with migrations not found\",\n );\n\n if (options.noScript) {\n if (options.withTest) {\n throw new Error(\"--with-test cannot be used together with --no-script.\");\n }\n const reason = options.reason?.trim();\n if (!reason) {\n throw new Error(\"--reason is required with --no-script.\");\n }\n const scriptSkipped = markMigrationScriptSkipped({\n migrationsDir,\n migrationNumber,\n reason,\n });\n logger.success(\n `Recorded that migration ${styles.bold(options.number)} in namespace ${styles.bold(targetNamespace)} intentionally has no migration script`,\n );\n logger.info(` Reason: ${scriptSkipped.reason}`);\n logger.info(` Diff file: ${getMigrationFilePath(migrationsDir, migrationNumber, \"diff\")}`);\n return;\n }\n if (options.reason !== undefined) {\n throw new Error(\"--reason can only be used together with --no-script.\");\n }\n\n const result = await addMigrationScriptFiles({\n migrationsDir,\n migrationNumber,\n withTest: options.withTest,\n });\n\n if (result.clearedScriptSkip) {\n logger.success(\n `Cleared the stale script skip record for migration ${styles.bold(options.number)} in namespace ${styles.bold(targetNamespace)}`,\n );\n if (!result.testPath) {\n logger.info(\n ` Migration script: ${getMigrationFilePath(migrationsDir, migrationNumber, \"migrate\")}`,\n );\n return;\n }\n }\n\n const added = [result.migratePath && \"migration script\", result.testPath && \"migration test\"]\n .filter(Boolean)\n .join(\" and \");\n logger.success(\n `Added ${added} for migration ${styles.bold(options.number)} in namespace ${styles.bold(targetNamespace)}`,\n );\n if (result.migratePath) {\n logger.info(` Migration script: ${result.migratePath}`);\n logger.info(` DB types: ${result.dbTypesPath}`);\n }\n if (result.testPath) {\n logger.info(` Migration test: ${result.testPath}`);\n }\n\n logger.newline();\n if (result.migratePath) {\n logger.log(\"Edit the script to implement your data migration logic.\");\n logger.log(\"It will be executed by 'tailor deploy' between Pre and Post phases.\");\n }\n if (result.testPath) {\n logger.log(\"Fill in the test with the rows to stage and the statements to assert.\");\n }\n\n const fileToOpen = result.migratePath ?? result.testPath;\n if (!fileToOpen) return;\n\n const editor = getConfiguredEditorCommand();\n if (!editor) return;\n\n logger.newline();\n logger.info(`Opening ${path.basename(fileToOpen)} in ${editor}...`);\n try {\n await openInConfiguredEditor(fileToOpen);\n } catch {\n return;\n }\n}\n\nfunction resolveTargetNamespace(\n namespacesWithMigrations: NamespaceWithMigrations[],\n requested?: string,\n): string {\n if (requested) {\n if (!namespacesWithMigrations.some((ns) => ns.namespace === requested)) {\n throw new Error(`Namespace \"${requested}\" not found or does not have migrations configured`);\n }\n return requested;\n }\n if (namespacesWithMigrations.length === 1) {\n const [ns] = namespacesWithMigrations;\n return assertDefined(ns, \"namespace with migrations missing\").namespace;\n }\n throw new Error(\n `Multiple TailorDB services found. Please specify namespace with --namespace flag: ${namespacesWithMigrations.map((ns) => ns.namespace).join(\", \")}`,\n );\n}\n\nexport const scriptCommand = defineAppCommand({\n name: \"script\",\n description:\n \"Add a migration script (migrate.ts) template to an existing migration directory, or record with --no-script that a migration intentionally has none.\",\n notes: `When \\`migrate.ts\\` already exists, running the command clears a previously recorded \\`--no-script\\` acknowledgment.`,\n args: z.strictObject({\n ...configArg,\n number: arg(z.string(), {\n positional: true,\n description: \"Migration number to add a script to (e.g., 0001 or 1)\",\n }),\n namespace: arg(z.string().optional(), {\n alias: \"n\",\n description: \"Target TailorDB namespace (required if multiple namespaces exist)\",\n }),\n \"no-script\": arg(z.boolean().optional(), {\n description:\n \"Record that this migration intentionally runs without a migration script (requires --reason)\",\n }),\n reason: arg(z.string().optional(), {\n description: \"Reason why no migration script is needed (used with --no-script)\",\n }),\n \"with-test\": arg(z.boolean().optional(), {\n description:\n \"Also add a migrate.test.ts unit-test scaffold; when migrate.ts already exists, only the test is added\",\n }),\n }),\n run: async (args) => {\n await script({\n configPath: args.config,\n number: args.number,\n namespace: args.namespace,\n noScript: args[\"no-script\"],\n reason: args.reason,\n withTest: args[\"with-test\"],\n });\n },\n});\n","/**\n * Generate command for TailorDB migrations\n *\n * Generates migration files based on local schema snapshots:\n * - First run: Creates initial schema snapshot (0000/schema.json)\n * - Subsequent runs: Creates diff from previous snapshot (0001/diff.json, etc.)\n */\n\nimport * as fs from \"node:fs\";\nimport * as fsPromises from \"node:fs/promises\";\nimport * as path from \"pathe\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { configArg, confirmationArgs } from \"#/cli/shared/args\";\nimport { logBetaWarning } from \"#/cli/shared/beta\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { getConfiguredEditorCommand, openInConfiguredEditor } from \"#/cli/shared/editor\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { canPrompt, prompt } from \"#/cli/shared/prompt\";\nimport { PluginManager } from \"#/plugin/manager\";\nimport { getNamespacesWithMigrations, type NamespaceWithMigrations } from \"./config\";\nimport {\n formatMigrationDiff,\n formatBreakingChanges,\n formatDiffSummary,\n formatWarnings,\n hasChanges,\n} from \"./diff-calculator\";\nimport { formatMigrationScriptCommand } from \"./hints\";\nimport { markMigrationScriptSkipped } from \"./script\";\nimport {\n createSnapshotFromLocalTypes,\n reconstructSnapshotFromMigrations,\n compareSnapshots,\n getNextMigrationNumber,\n assertValidMigrationFiles,\n formatMigrationNumber,\n INITIAL_SCHEMA_NUMBER,\n type SchemaSnapshot,\n} from \"./snapshot\";\nimport { generateSchemaFile, generateDiffFiles } from \"./template-generator\";\n\nexport interface GenerateOptions {\n configPath?: string;\n name?: string;\n yes?: boolean;\n init?: boolean;\n}\n\n/**\n * Build the safety-critical manual migration guidance for unsupported changes.\n * @returns Lines to write through the CLI logger\n */\nexport function getUnsupportedMigrationHintLines(): string[] {\n return [\n \"These changes require a manual 3-step migration process:\",\n \" Migration 1: Add an optional temporary field with the desired structure\",\n \" If the old field is required, make the old field optional\",\n \" For each non-null old value, copy and convert it to the temporary field\",\n \" and set the old field to null in the same update\",\n \" Verify every old value is null before continuing\",\n \" Migration 2: Remove the old field\",\n \" Migration 3: Add the field with the original name and new structure,\",\n \" migrate data from the temporary field, then remove it\",\n \" Important: Reusing the name while stored old values remain can make subsequent reads fail\",\n ];\n}\n\n/**\n * Handle --init option: delete existing migrations directories\n * @param {NamespaceWithMigrations[]} namespaces - Namespaces with migrations\n * @param {boolean} skipConfirmation - Whether to skip confirmation prompt\n * @returns {Promise<void>}\n */\nasync function handleInitOption(\n namespaces: NamespaceWithMigrations[],\n skipConfirmation?: boolean,\n): Promise<void> {\n // Find directories that exist\n const existingDirs = namespaces.filter(({ migrationsDir }) => fs.existsSync(migrationsDir));\n\n if (existingDirs.length === 0) {\n logger.info(\"No existing migration directories found.\");\n return;\n }\n\n // Show warning\n logger.newline();\n logger.warn(\"This will DELETE all existing migration files:\");\n for (const { namespace, migrationsDir } of existingDirs) {\n logger.log(` - ${namespace}: ${migrationsDir}`);\n }\n logger.newline();\n\n // Confirmation prompt\n if (!skipConfirmation) {\n const confirmation = await prompt.confirm({\n message: \"Are you sure you want to delete these directories and start fresh?\",\n default: false,\n });\n\n if (!confirmation) {\n logger.info(\"Operation cancelled.\");\n process.exit(0);\n }\n logger.newline();\n }\n\n // Delete directories\n for (const { namespace, migrationsDir } of existingDirs) {\n try {\n await fsPromises.rm(migrationsDir, { recursive: true, force: true });\n logger.success(`Deleted migration directory for ${styles.bold(namespace)}`);\n } catch (error) {\n logger.error(`Failed to delete ${migrationsDir}: ${error}`);\n throw error;\n }\n }\n\n logger.newline();\n logger.info(\"Migration directories cleared. Generating initial snapshot...\");\n logger.newline();\n}\n\n/**\n * Generate migration files for TailorDB schema changes\n * @param {GenerateOptions} options - Generation options\n * @returns {Promise<void>} Promise that resolves when generation is complete\n */\nexport async function generate(options: GenerateOptions): Promise<void> {\n logBetaWarning(\"tailordb migration\");\n\n // Load configuration\n const { config, plugins } = await loadConfig(options.configPath);\n const configDir = path.dirname(config.path);\n\n // Get namespaces with migrations config\n const namespacesWithMigrations: NamespaceWithMigrations[] = getNamespacesWithMigrations(\n config,\n configDir,\n );\n\n if (namespacesWithMigrations.length === 0) {\n logger.warn(\"No TailorDB namespaces with migrations config found.\");\n logger.info(\n 'Add \"migration: { directory: \\\\\"./migrations\\\\\" }\" to your db config to enable migrations.',\n );\n return;\n }\n\n // Handle --init option: delete existing migrations directory\n if (options.init) {\n await handleInitOption(namespacesWithMigrations, options.yes);\n }\n\n // Initialize plugin manager if plugins are provided\n let pluginManager: PluginManager | undefined;\n if (plugins.length > 0) {\n pluginManager = new PluginManager(plugins);\n }\n\n // Load application and all types\n const { defineApplication } = await import(\"#/cli/services/application\");\n const application = defineApplication({ config, pluginManager });\n\n // Process each namespace\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n logger.info(`Processing namespace: ${styles.bold(namespace)}`);\n\n // Validate existing migration files before generating new ones\n assertValidMigrationFiles(migrationsDir, namespace);\n\n // Find the TailorDB service for this namespace\n const tailordbService = application.tailorDBServices.find((s) => s.namespace === namespace);\n if (!tailordbService) {\n logger.warn(`No TailorDB service found for namespace \"${namespace}\"`);\n continue;\n }\n\n // Load types for this service\n await tailordbService.loadTypes();\n await tailordbService.processNamespacePlugins();\n\n const localTypesObj = tailordbService.types;\n\n // Create snapshot from current local types\n const currentSnapshot = createSnapshotFromLocalTypes(localTypesObj, namespace);\n\n // Returns null when the migrations directory is missing or empty;\n // throws when existing migration files are invalid.\n const previousSnapshot: SchemaSnapshot | null =\n reconstructSnapshotFromMigrations(migrationsDir);\n\n if (!previousSnapshot) {\n // First migration - generate initial schema snapshot\n await generateInitialSnapshot(currentSnapshot, migrationsDir);\n } else {\n // Compare with previous snapshot and generate diff\n await generateDiffFromSnapshot(previousSnapshot, currentSnapshot, migrationsDir, options);\n }\n }\n}\n\n/**\n * Generate the initial schema snapshot\n * @param {SchemaSnapshot} snapshot - Schema snapshot to save\n * @param {string} migrationsDir - Migrations directory path\n * @returns {Promise<void>} Promise that resolves when snapshot is generated\n */\nasync function generateInitialSnapshot(\n snapshot: SchemaSnapshot,\n migrationsDir: string,\n): Promise<void> {\n const result = await generateSchemaFile(snapshot, migrationsDir, INITIAL_SCHEMA_NUMBER);\n\n logger.success(`Generated initial schema snapshot`);\n logger.info(` File: ${result.filePath}`);\n logger.info(` Types: ${Object.keys(snapshot.types).length}`);\n\n logger.log(\"\\nThis is the baseline schema. Future changes will be tracked as diffs.\");\n}\n\n/**\n * Generate diff from previous snapshot\n * @param {SchemaSnapshot} previousSnapshot - Previous schema snapshot\n * @param {SchemaSnapshot} currentSnapshot - Current schema snapshot\n * @param {string} migrationsDir - Migrations directory path\n * @param {GenerateOptions} options - Generate options\n * @returns {Promise<void>} Promise that resolves when diff is generated\n */\nasync function generateDiffFromSnapshot(\n previousSnapshot: SchemaSnapshot,\n currentSnapshot: SchemaSnapshot,\n migrationsDir: string,\n options: GenerateOptions,\n): Promise<void> {\n // Calculate diff\n const diff = compareSnapshots(previousSnapshot, currentSnapshot);\n\n // Check if there are any changes\n if (!hasChanges(diff)) {\n logger.info(\"No schema differences detected.\");\n return;\n }\n\n // Display diff\n logger.newline();\n logger.log(formatMigrationDiff(diff));\n logger.newline();\n logger.info(`Summary: ${formatDiffSummary(diff)}`);\n\n // Check for unsupported changes\n const unsupportedChanges = diff.breakingChanges.filter((change) => change.unsupported);\n if (unsupportedChanges.length > 0) {\n for (const change of unsupportedChanges) {\n logger.newline();\n logger.error(`Unsupported change: ${change.typeName}.${change.fieldName}`);\n logger.error(` ${change.reason}`);\n }\n\n // Show 3-step migration hint if any unsupported change requires it\n if (unsupportedChanges.some((change) => change.showThreeStepHint)) {\n logger.newline();\n for (const line of getUnsupportedMigrationHintLines()) {\n logger.info(line);\n }\n }\n\n const details = unsupportedChanges\n .map((c) => ` - ${c.typeName}.${c.fieldName}: ${c.reason}`)\n .join(\"\\n\");\n throw new Error(`Unsupported schema changes detected:\\n${details}`);\n }\n\n // Warn about breaking changes\n if (diff.hasBreakingChanges) {\n logger.newline();\n logger.warn(formatBreakingChanges(diff.breakingChanges));\n\n if (!options.yes) {\n const confirmation = await prompt.confirm({\n message: \"Continue generating migration?\",\n default: true,\n });\n\n if (!confirmation) {\n logger.info(\"Migration generation cancelled.\");\n return;\n }\n logger.newline();\n }\n }\n\n // Warn about non-breaking but data-loss-possible changes (e.g. field/type removal)\n if (diff.hasWarnings) {\n logger.newline();\n logger.warn(formatWarnings(diff.warnings));\n }\n\n // Get next migration number\n const migrationNumber = getNextMigrationNumber(migrationsDir);\n\n // Generate diff and optional migration script (pass previousSnapshot for db.ts generation)\n const result = await generateDiffFiles(\n diff,\n migrationsDir,\n migrationNumber,\n previousSnapshot,\n options.name,\n );\n\n logger.success(\n `Generated migration ${styles.bold(formatMigrationNumber(result.migrationNumber))}`,\n );\n logger.info(` Diff file: ${result.diffFilePath}`);\n\n if (result.migrateFilePath) {\n logger.info(` Migration script: ${result.migrateFilePath}`);\n if (result.dbTypesFilePath) {\n logger.info(` DB types: ${result.dbTypesFilePath}`);\n }\n logger.newline();\n logger.log(\"A migration script was generated for breaking changes.\");\n logger.log(\"Please review and edit the script before running 'tailor deploy'.\");\n\n const editor = getConfiguredEditorCommand();\n if (!editor) {\n return;\n }\n\n try {\n await fsPromises.access(result.migrateFilePath);\n } catch {\n return;\n }\n\n logger.newline();\n logger.info(`Opening ${path.basename(result.migrateFilePath)} in ${editor}...`);\n\n try {\n await openInConfiguredEditor(result.migrateFilePath);\n } catch {\n return;\n }\n } else if (diff.hasWarnings) {\n await acknowledgeWarnings({\n namespace: diff.namespace,\n migrationsDir,\n migrationNumber: result.migrationNumber,\n skipPrompt: options.yes,\n configPath: options.configPath,\n });\n }\n}\n\ninterface AcknowledgeWarningsOptions {\n namespace: string;\n migrationsDir: string;\n migrationNumber: number;\n skipPrompt?: boolean;\n configPath?: string;\n}\n\n/**\n * Offer to record a --no-script acknowledgment for a warning-only migration,\n * or print the follow-up commands when the session is non-interactive\n * @param {AcknowledgeWarningsOptions} options - Target migration and prompt behavior\n */\nasync function acknowledgeWarnings(options: AcknowledgeWarningsOptions): Promise<void> {\n const { namespace, migrationsDir, migrationNumber, skipPrompt, configPath } = options;\n const label = formatMigrationNumber(migrationNumber);\n\n logger.newline();\n logger.log(\"Data loss is possible for this migration but no script was generated.\");\n\n if (!skipPrompt && canPrompt()) {\n const record = await prompt.confirm({\n message: \"Record a reason acknowledging that this migration intentionally has no script?\",\n default: true,\n });\n if (record) {\n const reason = await prompt.text({\n message: \"Reason:\",\n validate: (value) => value.trim() !== \"\" || \"Reason must not be empty.\",\n });\n const scriptSkipped = markMigrationScriptSkipped({ migrationsDir, migrationNumber, reason });\n logger.success(\n `Recorded that migration ${styles.bold(label)} intentionally has no migration script`,\n );\n logger.info(` Reason: ${scriptSkipped.reason}`);\n return;\n }\n }\n\n const commandOptions = { migrationNumber, namespace, configPath };\n logger.log(\"To add a custom migrate.ts, run:\");\n logger.log(` ${styles.bold(formatMigrationScriptCommand(commandOptions))}`);\n logger.log(\"To record that this migration intentionally has no script, run:\");\n logger.log(\n ` ${styles.bold(formatMigrationScriptCommand({ ...commandOptions, noScript: true }))}`,\n );\n}\n\n/**\n * CLI command definition for generate\n */\nexport const generateCommand = defineAppCommand({\n name: \"generate\",\n description:\n \"Generate migration files by detecting schema differences between current local types and the previous migration snapshot.\",\n args: z.strictObject({\n ...confirmationArgs,\n ...configArg,\n name: arg(z.string().optional(), {\n alias: \"n\",\n description: \"Optional description for the migration\",\n }),\n init: arg(z.boolean().default(false), {\n description: \"Delete existing migrations and start fresh\",\n }),\n }),\n run: async (args) => {\n await generate({\n configPath: args.config,\n name: args.name,\n yes: args.yes,\n init: args.init,\n });\n },\n});\n","/**\n * Seed script bundler for TailorDB seed data\n *\n * Bundles seed scripts to be executed via TestExecScript API\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { resolveTSConfig } from \"pkg-types\";\nimport * as rolldown from \"rolldown\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { createTsconfigPathsPlugin } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createGeneratedEntryResolverPlugin } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\n\nexport type SeedBundleResult = {\n namespace: string;\n bundledCode: string;\n typesIncluded: string[];\n};\n\nconst BATCH_SIZE = 100;\n\n/**\n * Generate seed script content for server-side execution\n * @param namespace - TailorDB namespace\n * @returns Generated seed script content\n */\nfunction generateSeedScriptContent(namespace: string): string {\n return ml /* ts */ `\n import { Kysely, TailordbDialect } from \"@tailor-platform/sdk/kysely\";\n\n type SeedInput = {\n data: Record<string, Record<string, unknown>[]>;\n order: string[];\n selfRefTypes: string[];\n upsert?: boolean;\n };\n\n type SeedResult = {\n success: boolean;\n processed: Record<string, { inserted: number; updated: number; skipped: number }>;\n errors: string[];\n };\n\n function getDB(namespace: string) {\n const client = new tailordb.Client({ namespace });\n return new Kysely<Record<string, Record<string, unknown>>>({\n dialect: new TailordbDialect(client),\n });\n }\n\n export async function main(input: SeedInput): Promise<SeedResult> {\n const db = getDB(\"${namespace}\");\n const processed: Record<\n string,\n { inserted: number; updated: number; skipped: number }\n > = {};\n const errors: string[] = [];\n const BATCH_SIZE = ${String(BATCH_SIZE)};\n const upsert = input.upsert === true;\n\n for (const typeName of input.order) {\n const records = input.data[typeName];\n if (!records || records.length === 0) {\n console.log(\\`[${namespace}] \\${typeName}: skipped (no data)\\`);\n continue;\n }\n\n processed[typeName] = { inserted: 0, updated: 0, skipped: 0 };\n const hasSelfRef = (input.selfRefTypes || []).includes(typeName);\n\n try {\n let recordsToInsert = records;\n let recordsToUpdate: Record<string, unknown>[] = [];\n if (upsert) {\n const existing = await db\n .selectFrom(typeName)\n .select(\"id\")\n .where(\n \"id\",\n \"in\",\n records.map((record) => record.id),\n )\n .execute();\n const existingIds = new Set(existing.map((record) => record.id));\n recordsToInsert = records.filter((record) => !existingIds.has(record.id));\n recordsToUpdate = records.filter((record) => existingIds.has(record.id));\n }\n\n if (hasSelfRef) {\n // Insert one-by-one to respect self-referencing foreign key order\n for (const record of recordsToInsert) {\n await db.insertInto(typeName).values(record).execute();\n processed[typeName].inserted += 1;\n }\n if (!upsert) {\n console.log(\n \\`[${namespace}] \\${typeName}: \\${processed[typeName].inserted}/\\${records.length} (one-by-one)\\`,\n );\n }\n } else {\n for (let i = 0; i < recordsToInsert.length; i += BATCH_SIZE) {\n const batch = recordsToInsert.slice(i, i + BATCH_SIZE);\n await db.insertInto(typeName).values(batch).execute();\n processed[typeName].inserted += batch.length;\n if (!upsert) {\n console.log(\n \\`[${namespace}] \\${typeName}: \\${processed[typeName].inserted}/\\${records.length}\\`,\n );\n }\n }\n }\n\n for (const record of recordsToUpdate) {\n const { id, ...values } = record;\n if (Object.keys(values).length === 0) {\n processed[typeName].skipped += 1;\n continue;\n }\n await db.updateTable(typeName).set(values).where(\"id\", \"=\", id).execute();\n processed[typeName].updated += 1;\n }\n\n const counts = processed[typeName];\n if (upsert) {\n const skipped = counts.skipped > 0 ? \\`, \\${counts.skipped} skipped\\` : \"\";\n console.log(\n \\`[${namespace}] \\${typeName}: \\${counts.inserted} inserted, \\${counts.updated} updated\\${skipped}\\`,\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n errors.push(\\`\\${typeName}: \\${message}\\`);\n console.error(\\`[${namespace}] \\${typeName}: failed - \\${message}\\`);\n }\n }\n\n return {\n success: errors.length === 0,\n processed,\n errors,\n };\n }\n `;\n}\n\n/**\n * Bundle a seed script for server-side execution\n *\n * Creates an entry that:\n * 1. Defines getDB() function inline\n * 2. Processes data in batches using Kysely\n * 3. Reports progress via console.log\n * 4. Exports as main() for TestExecScript\n * @param namespace - TailorDB namespace\n * @param typeNames - List of type names to include in the seed\n * @param baseDir - Directory whose dependencies and tsconfig the generated entry uses\n * @returns Bundled seed script result\n */\nexport async function bundleSeedScript(\n namespace: string,\n typeNames: string[],\n baseDir: string = process.cwd(),\n): Promise<SeedBundleResult> {\n // Output directory in .tailor (relative to project root)\n const outputDir = path.resolve(getDistDir(), \"seed\");\n fs.mkdirSync(outputDir, { recursive: true });\n\n // Entry file in output directory\n const entryPath = path.join(outputDir, `seed_${namespace}.entry.ts`);\n\n // Generate seed script content\n const entryContent = generateSeedScriptContent(namespace);\n fs.writeFileSync(entryPath, entryContent);\n\n let tsconfig: string | undefined;\n try {\n tsconfig = await resolveTSConfig(baseDir);\n } catch {\n tsconfig = undefined;\n }\n\n // Bundle with tree-shaking (write: false to avoid unnecessary disk I/O)\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n plugins: [\n createGeneratedEntryResolverPlugin(entryPath, baseDir),\n createTsconfigPathsPlugin(),\n platformBundleDefinePlugin,\n ],\n input: entryPath,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: false,\n minify: false,\n codeSplitting: false,\n globals: {\n tailordb: \"tailordb\",\n },\n },\n external: [\"tailordb\"],\n resolve: {\n conditionNames: [\"node\", \"import\"],\n },\n tsconfig,\n treeshake: {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n },\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n\n return {\n namespace,\n bundledCode,\n typesIncluded: typeNames,\n };\n}\n","/**\n * Seed data chunker for splitting large seed data into manageable message sizes.\n *\n * When seed data exceeds the gRPC message size limit, this module splits the data\n * into multiple chunks at type boundaries (or record boundaries for large types).\n */\n\nimport { assertDefined } from \"#/utils/assert\";\nimport type { JsonObject } from \"type-fest\";\n\n/**\n * Seed data keyed by type name, with an array of records per type.\n */\nexport type SeedData = Record<string, JsonObject[]>;\n\n/**\n * A single chunk of seed data with metadata for ordered execution.\n */\nexport type SeedChunk = {\n data: SeedData;\n order: string[];\n index: number;\n total: number;\n};\n\n/**\n * Options for chunking seed data.\n */\nexport type ChunkSeedDataOptions = {\n /** Seed data keyed by type name */\n data: SeedData;\n /** Ordered list of type names (dependency order) */\n order: string[];\n /** Byte size of the bundled seed script code */\n codeByteSize: number;\n /** Maximum gRPC message size in bytes (default: 3.5MB) */\n maxMessageSize?: number;\n};\n\n/** Default maximum message size: 3.5MB (conservative limit for gRPC) */\nexport const DEFAULT_MAX_MESSAGE_SIZE = 3.5 * 1024 * 1024;\n\n/** Reserved bytes for message metadata overhead */\nconst METADATA_OVERHEAD = 1024;\n\n/**\n * Split seed data into chunks that fit within the gRPC message size limit.\n *\n * Algorithm:\n * 1. Calculate the available budget for the arg field (maxMessageSize - codeByteSize - overhead)\n * 2. If all data fits in one message, return a single chunk\n * 3. Otherwise, iterate through types in dependency order:\n * - If a type fits in the current chunk, add it\n * - If adding a type would exceed the budget, finalize the current chunk and start a new one\n * - If a single type exceeds the budget, split its records across multiple chunks\n * - If a single record exceeds the budget, throw an error\n * @param options - Chunking options\n * @returns Array of seed chunks\n */\nexport function chunkSeedData(options: ChunkSeedDataOptions): SeedChunk[] {\n const { data, order, codeByteSize, maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE } = options;\n\n const argBudget = maxMessageSize - codeByteSize - METADATA_OVERHEAD;\n if (argBudget <= 0) {\n throw new Error(\n `Code size (${codeByteSize} bytes) exceeds the message size limit (${maxMessageSize} bytes). ` +\n `No space left for seed data.`,\n );\n }\n\n // Filter to types that have data\n const typesWithData = order.filter((type) => (data[type]?.length ?? 0) > 0);\n\n if (typesWithData.length === 0) {\n return [];\n }\n\n // Check if all data fits in a single message\n const fullArg = JSON.stringify({ data, order });\n if (byteSize(fullArg) <= argBudget) {\n return [{ data, order, index: 0, total: 1 }];\n }\n\n // Split into multiple chunks\n const chunks: Omit<SeedChunk, \"total\">[] = [];\n let currentData: SeedData = {};\n let currentOrder: string[] = [];\n\n for (const type of typesWithData) {\n const typeRecords = assertDefined(data[type], `seed data missing for type: ${type}`);\n\n // Check if the type fits in the current chunk\n if (currentOrder.length > 0) {\n const testData = { ...currentData, [type]: typeRecords };\n const testOrder = [...currentOrder, type];\n if (byteSize(JSON.stringify({ data: testData, order: testOrder })) > argBudget) {\n // Finalize the current chunk\n chunks.push({ data: currentData, order: currentOrder, index: chunks.length });\n currentData = {};\n currentOrder = [];\n }\n }\n\n // Check if the entire type fits in an empty chunk\n if (byteSize(JSON.stringify({ data: { [type]: typeRecords }, order: [type] })) <= argBudget) {\n currentData[type] = typeRecords;\n currentOrder.push(type);\n continue;\n }\n\n // Type is too large — split by records\n if (currentOrder.length > 0) {\n chunks.push({ data: currentData, order: currentOrder, index: chunks.length });\n currentData = {};\n currentOrder = [];\n }\n\n let recordBatch: JsonObject[] = [];\n for (const record of typeRecords) {\n if (byteSize(JSON.stringify({ data: { [type]: [record] }, order: [type] })) > argBudget) {\n const singleRecordSize = byteSize(JSON.stringify(record));\n throw new Error(\n `A single record in type \"${type}\" (${singleRecordSize} bytes) exceeds the message size budget ` +\n `(${argBudget} bytes). Consider increasing maxMessageSize or reducing the record size.`,\n );\n }\n\n const testBatch = [...recordBatch, record];\n const testData = { ...currentData, [type]: testBatch };\n const testOrder = currentOrder.includes(type) ? currentOrder : [...currentOrder, type];\n const testSize = byteSize(JSON.stringify({ data: testData, order: testOrder }));\n\n if (testSize > argBudget && recordBatch.length > 0) {\n // Finalize current chunk with accumulated records\n currentData[type] = recordBatch;\n if (!currentOrder.includes(type)) {\n currentOrder.push(type);\n }\n chunks.push({ data: currentData, order: currentOrder, index: chunks.length });\n currentData = {};\n currentOrder = [];\n recordBatch = [record];\n } else {\n recordBatch = testBatch;\n }\n }\n\n // Add remaining records\n if (recordBatch.length > 0) {\n currentData[type] = recordBatch;\n if (!currentOrder.includes(type)) {\n currentOrder.push(type);\n }\n }\n }\n\n // Finalize the last chunk\n if (currentOrder.length > 0) {\n chunks.push({ data: currentData, order: currentOrder, index: chunks.length });\n }\n\n const total = chunks.length;\n return chunks.map((chunk) => ({ ...chunk, total }));\n}\n\nfunction byteSize(str: string): number {\n return new TextEncoder().encode(str).length;\n}\n","import { assertDefined } from \"#/utils/assert\";\nimport { processLinesDb } from \"./lines-db-processor\";\nimport type { TailorDBType } from \"#/parser/service/tailordb/types\";\nimport type { TailorDBNamespaceData } from \"#/plugin/types\";\nimport type { SeedTypeInfo } from \"./types\";\n\n/**\n * Processes TailorDB types to extract seed type information\n * @param type - Parsed TailorDB type\n * @param namespace - Namespace of the type\n * @returns Seed type information\n */\nexport function processSeedTypeInfo(type: TailorDBType, namespace: string): SeedTypeInfo {\n // Extract dependencies from relations (including keyOnly which only sets foreignKeyType)\n const dependencies: Set<string> = new Set();\n const selfRefFields: string[] = [];\n\n for (const [fieldName, field] of Object.entries(type.fields)) {\n const targetType = field.relation?.targetType ?? field.config.foreignKeyType;\n if (!targetType) continue;\n\n if (targetType === type.name) {\n selfRefFields.push(fieldName);\n } else {\n dependencies.add(targetType);\n }\n }\n\n return {\n name: type.name,\n namespace,\n dependencies: Array.from(dependencies),\n selfRefFields,\n dataFile: `data/${type.name}.jsonl`,\n };\n}\n\n/**\n * Seed ordering information for a TailorDB namespace.\n */\nexport interface SeedNamespaceConfig {\n /** TailorDB namespace name. */\n namespace: string;\n /** Type names in the namespace, in definition order. */\n types: string[];\n /** Seed dependencies (referenced type names) per type. */\n dependencies: Record<string, string[]>;\n /** Types with self-referencing fields, seeded in two passes. */\n selfRefTypes: string[];\n /** Field names a seed row must supply per type, enforced with `--upsert`. */\n requiredFields: Record<string, string[]>;\n}\n\n/**\n * Build per-namespace seed ordering information from TailorDB namespace data.\n * @param tailordb - TailorDB namespaces with their types\n * @returns Seed namespace configs, in namespace order\n */\nexport function buildSeedNamespaceConfigs(\n tailordb: TailorDBNamespaceData[],\n): SeedNamespaceConfig[] {\n return tailordb.map((ns) => {\n const types: string[] = [];\n const dependencies: Record<string, string[]> = {};\n const selfRefTypes: string[] = [];\n const requiredFields: Record<string, string[]> = {};\n\n for (const [typeName, type] of Object.entries(ns.types)) {\n const typeInfo = processSeedTypeInfo(type, ns.namespace);\n types.push(typeInfo.name);\n dependencies[typeInfo.name] = typeInfo.dependencies;\n if (typeInfo.selfRefFields.length > 0) {\n selfRefTypes.push(typeInfo.name);\n }\n\n const source = assertDefined(\n ns.sourceInfo.get(typeName),\n `source info missing for type: ${typeName}`,\n );\n const linesDb = processLinesDb(type, source);\n requiredFields[typeInfo.name] = Object.entries(type.fields)\n .filter(\n ([fieldName, field]) =>\n field.config.required !== false &&\n !linesDb.optionalFields.includes(fieldName) &&\n !linesDb.omitFields.includes(fieldName),\n )\n .map(([fieldName]) => fieldName);\n }\n\n return {\n namespace: ns.namespace,\n types,\n dependencies,\n selfRefTypes,\n requiredFields,\n };\n });\n}\n","import { defineApplication, type Application } from \"#/cli/services/application\";\nimport { PluginManager } from \"#/plugin/manager\";\nimport { loadConfig, type LoadedConfig } from \"./config-loader\";\nimport { generateUserTypes } from \"./type-generator\";\nimport type { Plugin, TailorDBNamespaceData } from \"#/plugin/types\";\n\n/**\n * Namespace selection for {@link loadTailorDBNamespaces}: explicit namespace\n * names, or a selector deriving them from the loaded config and its plugins.\n * Returning `undefined` (or omitting the option) loads all owned namespaces.\n */\nexport type TailorDBNamespaceSelector =\n | string[]\n | ((config: LoadedConfig, plugins: Plugin[]) => string[] | undefined);\n\n/**\n * Options for {@link loadTailorDBNamespaces}.\n */\nexport interface LoadTailorDBNamespacesOptions {\n /** Path to tailor.config.ts. Defaults to searching from the current directory. */\n configPath?: string;\n /** Namespaces to load. Omit to load all owned namespaces. */\n namespaces?: TailorDBNamespaceSelector;\n}\n\n/**\n * Result of {@link loadTailorDBNamespaces}.\n */\nexport interface LoadedTailorDBNamespaces {\n /** The loaded Tailor config. */\n config: LoadedConfig;\n /** Plugins collected from the config module's plugin-array exports (typically `definePlugins()`). */\n plugins: Plugin[];\n /** Loaded TailorDB namespace data, in config order. */\n namespaces: TailorDBNamespaceData[];\n}\n\n/**\n * Result of {@link loadApplicationNamespaces}: the loaded namespaces plus the\n * config plugins and application they were loaded through.\n */\nexport interface LoadedApplicationNamespaces extends LoadedTailorDBNamespaces {\n /** Application defined from the loaded config. */\n application: Application;\n}\n\n/**\n * Load local TailorDB namespaces along with the config plugins and the\n * defined application. Internal superset of {@link loadTailorDBNamespaces}.\n * @param options - Namespace loading options.\n * @returns The loaded config, plugins, application, and TailorDB namespace data.\n */\nexport async function loadApplicationNamespaces(\n options: LoadTailorDBNamespacesOptions = {},\n): Promise<LoadedApplicationNamespaces> {\n const { config, plugins } = await loadConfig(options.configPath);\n\n await generateUserTypes({ config, configPath: config.path });\n\n const pluginManager = plugins.length > 0 ? new PluginManager(plugins) : undefined;\n const application = defineApplication({\n config,\n pluginManager,\n });\n const namespaceNames =\n typeof options.namespaces === \"function\"\n ? options.namespaces(config, plugins)\n : options.namespaces;\n const namespaceFilter = namespaceNames ? new Set(namespaceNames) : undefined;\n const services = namespaceFilter\n ? application.tailorDBServices.filter((db) => namespaceFilter.has(db.namespace))\n : application.tailorDBServices;\n\n if (namespaceFilter && services.length !== namespaceFilter.size) {\n const found = new Set(services.map((db) => db.namespace));\n const missing = [...namespaceFilter].filter((ns) => !found.has(ns)).join(\", \");\n const available = application.tailorDBServices.map((db) => db.namespace).join(\", \");\n throw new Error(\n `TailorDB namespace \"${missing}\" not found in local config.db.` +\n (available ? ` Available owned namespaces: ${available}` : \"\"),\n );\n }\n\n const namespaces: TailorDBNamespaceData[] = [];\n\n for (const db of services) {\n await db.loadTypes();\n await db.processNamespacePlugins();\n namespaces.push({\n namespace: db.namespace,\n types: { ...db.types },\n sourceInfo: new Map(Object.entries(db.typeSourceInfo)),\n pluginAttachments: db.pluginAttachments,\n });\n }\n\n return { config, plugins, application, namespaces };\n}\n\n/**\n * Load local TailorDB namespaces exactly as SDK generation/deploy sees them:\n * the config is loaded, user types are generated, and each selected\n * namespace's types are loaded with namespace plugins applied.\n * @param options - Namespace loading options.\n * @returns The loaded config and TailorDB namespace data.\n */\nexport async function loadTailorDBNamespaces(\n options: LoadTailorDBNamespacesOptions = {},\n): Promise<LoadedTailorDBNamespaces> {\n const { config, plugins, namespaces } = await loadApplicationNamespaces(options);\n return { config, plugins, namespaces };\n}\n","import * as path from \"pathe\";\nimport { assertUniqueLocalTailorDBTypeNames } from \"#/cli/services/tailordb/type-name-validation\";\nimport {\n generateIdpSeedScriptCode,\n generateIdpTruncateScriptCode,\n processIdpUser,\n} from \"#/plugin/builtin/seed/idp-user-processor\";\nimport { SeedGeneratorID, type SeedPluginOptions } from \"#/plugin/builtin/seed/index\";\nimport {\n buildSeedNamespaceConfigs,\n type SeedNamespaceConfig,\n} from \"#/plugin/builtin/seed/seed-type-processor\";\nimport { getAuthInput } from \"./auth-input\";\nimport { loadApplicationNamespaces } from \"./tailordb-namespaces\";\nimport type { LoadedConfig } from \"./config-loader\";\n\nexport type { SeedNamespaceConfig };\n\n/**\n * IdP `_User` seeding context, present when the config uses the built-in IdP\n * with a user profile type.\n */\nexport interface SeedIdpUserContext {\n /** IdP namespace the `_User` records belong to. */\n idpNamespace: string;\n /** Server-side script that creates `_User` records from seed rows. */\n seedScriptCode: string;\n /** Server-side script that deletes all `_User` records. */\n truncateScriptCode: string;\n}\n\n/**\n * Everything a seed run needs from the local config: the seed data location,\n * per-namespace seeding order, and IdP user context.\n */\nexport interface SeedContext {\n /** The loaded Tailor config. */\n config: LoadedConfig;\n /** Absolute path to the seedPlugin output directory. */\n distPath: string;\n /** Default machine user name from seedPlugin options, if configured. */\n machineUserName?: string | undefined;\n /** Seed ordering information per TailorDB namespace. */\n namespaces: SeedNamespaceConfig[];\n /** IdP `_User` seeding context, or null when not applicable. */\n idpUser: SeedIdpUserContext | null;\n}\n\n/**\n * Options for {@link loadSeedContext}.\n */\nexport interface LoadSeedContextOptions {\n /** Path to tailor.config.ts. Defaults to searching from the current directory. */\n configPath?: string;\n}\n\n/**\n * Load the seed context from the local config. Requires `seedPlugin` to be\n * configured in the config's plugins. A relative `distPath` in the seedPlugin\n * options is resolved against the current working directory — the same base\n * `tailor generate` writes it to.\n * @param options - Seed context loading options.\n * @returns The seed context computed from the local config.\n */\nexport async function loadSeedContext(options: LoadSeedContextOptions = {}): Promise<SeedContext> {\n const { config, plugins, application, namespaces } = await loadApplicationNamespaces({\n configPath: options.configPath,\n });\n\n // Seed files and type filters identify types by bare name, so enforce the\n // same cross-namespace uniqueness that generation and deploy enforce.\n assertUniqueLocalTailorDBTypeNames({ tailorDBServices: application.tailorDBServices });\n\n const seedPlugin = plugins.find((plugin) => plugin.id === SeedGeneratorID);\n if (!seedPlugin) {\n throw new Error(\n `seedPlugin is not configured in ${config.path}. ` +\n 'Add seedPlugin({ distPath: \"./seed\" }) from \"@tailor-platform/sdk/plugin/seed\" to definePlugins().',\n );\n }\n const pluginOptions = seedPlugin.pluginConfig as SeedPluginOptions | undefined;\n if (typeof pluginOptions?.distPath !== \"string\" || pluginOptions.distPath === \"\") {\n throw new Error(\n `seedPlugin in ${config.path} has no distPath option. ` +\n 'Pass seedPlugin({ distPath: \"./seed\" }) so seed data has a location.',\n );\n }\n\n // userProfile is only populated once auth namespaces are resolved (the\n // generate flow does the same after loading TailorDB namespaces).\n await application.authService?.resolveNamespaces();\n const authInput = getAuthInput(application);\n const idpUserMeta = authInput ? processIdpUser(authInput) : undefined;\n const idpUser: SeedIdpUserContext | null = idpUserMeta\n ? {\n idpNamespace: idpUserMeta.idpNamespace,\n seedScriptCode: generateIdpSeedScriptCode(idpUserMeta.idpNamespace),\n truncateScriptCode: generateIdpTruncateScriptCode(idpUserMeta.idpNamespace),\n }\n : null;\n\n return {\n config,\n distPath: path.resolve(pluginOptions.distPath),\n machineUserName: pluginOptions.machineUserName,\n namespaces: buildSeedNamespaceConfigs(namespaces),\n idpUser,\n };\n}\n","type ListTailorDBTypesClient = {\n listTailorDBTypes(args: { workspaceId: string; namespaceName: string }): Promise<{\n tailordbTypes: Array<{ name: string }>;\n }>;\n};\n\ntype ResolveTypeNamespacesArgs = {\n workspaceId: string;\n namespaces: string[];\n typeNames: string[];\n client: ListTailorDBTypesClient;\n};\n\n/**\n * Resolve TailorDB type names to namespace names.\n * @param args - Resolution inputs\n * @returns Type to namespace map for found types\n */\nexport async function resolveTypeNamespaces(\n args: ResolveTypeNamespacesArgs,\n): Promise<Map<string, string>> {\n const requestedTypesByLowercase = new Map<string, string[]>();\n for (const typeName of args.typeNames) {\n const key = typeName.toLowerCase();\n const existing = requestedTypesByLowercase.get(key);\n if (existing) {\n existing.push(typeName);\n continue;\n }\n requestedTypesByLowercase.set(key, [typeName]);\n }\n\n const unresolvedTypes = new Set(args.typeNames);\n const typeNamespaceMap = new Map<string, string>();\n\n for (const namespace of args.namespaces) {\n if (unresolvedTypes.size === 0) {\n break;\n }\n\n try {\n const { tailordbTypes } = await args.client.listTailorDBTypes({\n workspaceId: args.workspaceId,\n namespaceName: namespace,\n });\n\n for (const type of tailordbTypes) {\n const matchedRequestedTypes = requestedTypesByLowercase.get(type.name.toLowerCase());\n if (!matchedRequestedTypes) {\n continue;\n }\n\n for (const requestedTypeName of matchedRequestedTypes) {\n if (typeNamespaceMap.has(requestedTypeName)) {\n continue;\n }\n typeNamespaceMap.set(requestedTypeName, namespace);\n unresolvedTypes.delete(requestedTypeName);\n }\n }\n } catch {\n continue;\n }\n }\n\n return typeNamespaceMap;\n}\n\ntype ResolveTypeNamespaceArgs = {\n workspaceId: string;\n namespaces: string[];\n typeName: string;\n client: ListTailorDBTypesClient;\n};\n\n/**\n * Resolve a single TailorDB type name to namespace.\n * @param args - Resolution inputs\n * @returns Namespace name if found\n */\nexport async function resolveTypeNamespace(args: ResolveTypeNamespaceArgs): Promise<string | null> {\n const typeNamespaceMap = await resolveTypeNamespaces({\n workspaceId: args.workspaceId,\n namespaces: args.namespaces,\n typeNames: [args.typeName],\n client: args.client,\n });\n\n return typeNamespaceMap.get(args.typeName) ?? null;\n}\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { confirmationArgs, deploymentArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { extractOwnedNamespaces } from \"#/cli/shared/config\";\nimport { loadConfig } from \"#/cli/shared/config-loader\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { resolveTypeNamespaces } from \"#/cli/shared/tailordb-namespace\";\nimport { assertDefined } from \"#/utils/assert\";\n\nexport interface TruncateOptions {\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n all?: boolean;\n namespace?: string;\n types?: string[];\n}\n\ninterface InternalTruncateOptions extends TruncateOptions {\n yes?: boolean;\n}\n\ninterface TruncateSingleTypeOptions {\n workspaceId: string;\n namespaceName: string;\n typeName: string;\n}\n\nasync function truncateSingleType(\n options: TruncateSingleTypeOptions,\n client: Awaited<ReturnType<typeof initOperatorClient>>,\n): Promise<void> {\n await client.truncateTailorDBType({\n workspaceId: options.workspaceId,\n namespaceName: options.namespaceName,\n tailordbTypeName: options.typeName,\n });\n\n logger.success(`Truncated type \"${options.typeName}\" in namespace \"${options.namespaceName}\"`);\n}\n\nasync function truncateNamespace(\n workspaceId: string,\n namespaceName: string,\n client: Awaited<ReturnType<typeof initOperatorClient>>,\n): Promise<void> {\n await client.truncateTailorDBTypes({\n workspaceId,\n namespaceName,\n });\n\n logger.success(`Truncated all types in namespace \"${namespaceName}\"`);\n}\n\n/**\n * Truncate TailorDB data based on the given options.\n * @param options - Truncate options (all, namespace, or types)\n * @returns Promise that resolves when truncation completes\n */\nexport async function truncate(options?: TruncateOptions): Promise<void> {\n return await $truncate({ ...options, yes: true });\n}\n\nasync function $truncate(options: InternalTruncateOptions = {}): Promise<void> {\n // Load and validate options\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n // Validate arguments\n const hasTypes = options.types && options.types.length > 0;\n const hasNamespace = !!options.namespace;\n const hasAll = !!options.all;\n\n // All options are mutually exclusive\n const optionCount = [hasAll, hasNamespace, hasTypes].filter(Boolean).length;\n if (optionCount === 0) {\n throw new Error(\"Please specify one of: --all, --namespace <name>, or type names\");\n }\n if (optionCount > 1) {\n throw new Error(\n \"Options --all, --namespace, and type names are mutually exclusive. Please specify only one.\",\n );\n }\n\n // Validate config and get namespaces before confirmation\n const { config } = await loadConfig(options.configPath);\n const namespaces = extractOwnedNamespaces(config);\n\n // Handle --all flag\n if (hasAll) {\n if (namespaces.length === 0) {\n logger.warn(\"No namespaces found in config file.\");\n return;\n }\n\n if (!options.yes) {\n const namespaceList = namespaces.join(\", \");\n const confirmation = await prompt.confirm({\n message: `This will truncate ALL tables in the following owned namespaces (external namespaces are excluded): ${namespaceList}. Continue?`,\n default: false,\n });\n if (!confirmation) {\n logger.info(\"Truncate cancelled.\");\n return;\n }\n }\n\n for (const namespace of namespaces) {\n await truncateNamespace(workspaceId, namespace, client);\n }\n logger.success(\"Truncated all tables in all owned namespaces\");\n return;\n }\n\n // Handle --namespace flag\n if (hasNamespace) {\n const namespace = assertDefined(options.namespace, \"namespace option missing\");\n\n // Validate namespace exists in config and is not external\n if (!namespaces.includes(namespace)) {\n const dbConfig = config.db?.[namespace];\n if (dbConfig && \"external\" in dbConfig) {\n throw new Error(\n `Namespace \"${namespace}\" is declared as external in this app's config and cannot be truncated from here. Run truncate from the app that owns it.`,\n );\n }\n throw new Error(\n `Namespace \"${namespace}\" not found in config. Available owned namespaces (external namespaces are excluded): ${namespaces.join(\", \")}`,\n );\n }\n\n if (!options.yes) {\n const confirmation = await prompt.confirm({\n message: `This will truncate ALL tables in namespace \"${namespace}\". Continue?`,\n default: false,\n });\n if (!confirmation) {\n logger.info(\"Truncate cancelled.\");\n return;\n }\n }\n\n await truncateNamespace(workspaceId, namespace, client);\n return;\n }\n\n // Handle specific types\n if (hasTypes) {\n const typeNames = assertDefined(options.types, \"types option missing\");\n\n // Validate all types exist and get their namespaces before confirmation\n const typeNamespaceMap = await resolveTypeNamespaces({\n workspaceId,\n namespaces,\n typeNames,\n client,\n });\n const notFoundTypes = typeNames.filter((typeName) => !typeNamespaceMap.has(typeName));\n\n if (notFoundTypes.length > 0) {\n throw new Error(\n `The following types were not found in any namespace: ${notFoundTypes.join(\", \")}`,\n );\n }\n\n if (!options.yes) {\n const typeList = typeNames.join(\", \");\n const confirmation = await prompt.confirm({\n message: `This will truncate the following types: ${typeList}. Continue?`,\n default: false,\n });\n if (!confirmation) {\n logger.info(\"Truncate cancelled.\");\n return;\n }\n }\n\n for (const typeName of typeNames) {\n const namespace = typeNamespaceMap.get(typeName);\n if (!namespace) {\n continue;\n }\n\n await truncateSingleType(\n {\n workspaceId,\n namespaceName: namespace,\n typeName,\n },\n client,\n );\n }\n }\n}\n\nexport const truncateCommand = defineAppCommand({\n name: \"truncate\",\n description: \"Truncate (delete all records from) TailorDB tables.\",\n args: z.strictObject({\n ...deploymentArgs,\n ...confirmationArgs,\n types: arg(z.string().array().optional(), {\n positional: true,\n description: \"Type names to truncate\",\n }),\n all: arg(z.boolean().default(false), {\n alias: \"a\",\n description: \"Truncate all tables in all owned namespaces (excludes external namespaces)\",\n }),\n namespace: arg(z.string().optional(), {\n alias: \"n\",\n description: \"Truncate all tables in specified namespace\",\n }),\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n const types = args.types && args.types.length > 0 ? args.types : undefined;\n await $truncate({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n all: args.all,\n namespace: args.namespace,\n types,\n yes: args.yes,\n });\n },\n});\n","import { z } from \"zod\";\nimport { type Order, paginationArgs, toPageDirection, workspaceArgs } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { type WorkflowListInfo, toWorkflowListInfo } from \"./transform\";\n\nexport interface ListWorkflowsOptions {\n workspaceId?: string;\n profile?: string;\n order?: Order;\n limit?: number;\n}\n\n/**\n * List workflows in the workspace and return CLI-friendly info.\n * @param options - Workflow listing options\n * @returns List of workflows\n */\nexport async function listWorkflows(options?: ListWorkflowsOptions): Promise<WorkflowListInfo[]> {\n const accessToken = await loadAccessToken({\n profile: options?.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options?.workspaceId,\n profile: options?.profile,\n });\n\n const pageDirection = toPageDirection(options?.order);\n const workflows = await fetchPaged(\n async (pageToken, pageSize) => {\n const { workflows, nextPageToken } = await client.listWorkflows({\n workspaceId,\n pageToken,\n pageSize,\n pageDirection,\n });\n return [workflows, nextPageToken];\n },\n { limit: options?.limit },\n );\n\n return workflows.map(toWorkflowListInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all workflows in the workspace.\",\n args: z.strictObject({\n ...workspaceArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode;\n const workflows = await listWorkflows({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n order: args.order,\n limit: args.limit,\n });\n\n if (workflows.length === 0) {\n logger.info(\"No workflows found.\");\n if (!jsonOutput) {\n return;\n }\n }\n logger.out(workflows);\n },\n});\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { parseDuration, workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { waitArgs } from \"./args\";\nimport { getWorkflowExecution, printExecutionWithLogs } from \"./executions\";\nimport { waitForExecution, type WaitOptions } from \"./start\";\nimport { getWorkflowWaitFailureMessage, type WorkflowWaitResult } from \"./waiter\";\n\nexport interface ResumeWorkflowOptions {\n executionId: string;\n workspaceId?: string;\n profile?: string;\n interval?: number;\n}\n\nexport interface ResumeWorkflowResultWithWait {\n executionId: string;\n wait: (options?: WaitOptions) => Promise<WorkflowWaitResult>;\n}\n\n/**\n * Resume a suspended workflow execution and return a handle to wait for completion.\n * @param options - Resume options\n * @returns Resume result with wait helper\n */\nexport async function resumeWorkflow(\n options: ResumeWorkflowOptions,\n): Promise<ResumeWorkflowResultWithWait> {\n const accessToken = await loadAccessToken({\n profile: options.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: options.workspaceId,\n profile: options.profile,\n });\n\n try {\n const { executionId } = await client.testResumeWorkflow({\n workspaceId,\n executionId: options.executionId,\n });\n\n return {\n executionId,\n wait: (waitOptions?: WaitOptions) =>\n waitForExecution({\n client,\n workspaceId,\n executionId,\n interval: options.interval ?? 3000,\n timeout: waitOptions?.timeout,\n until: waitOptions?.until,\n showProgress: waitOptions?.showProgress,\n }),\n };\n } catch (error) {\n if (error instanceof ConnectError) {\n if (error.code === Code.NotFound) {\n throw new Error(`Execution '${options.executionId}' not found.`, { cause: error });\n }\n if (error.code === Code.FailedPrecondition) {\n throw new Error(`Execution '${options.executionId}' is not in a resumable state.`, {\n cause: error,\n });\n }\n }\n throw error;\n }\n}\n\nexport const resumeCommand = defineAppCommand({\n name: \"resume\",\n description: \"Resume a failed or pending workflow execution.\",\n args: z.strictObject({\n ...workspaceArgs,\n \"execution-id\": arg(z.string(), {\n positional: true,\n description: \"Failed execution ID\",\n }),\n ...waitArgs,\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode || args.json;\n const { executionId, wait } = await resumeWorkflow({\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval: parseDuration(args.interval),\n });\n\n if (!jsonOutput) {\n logger.info(`Execution ID: ${executionId}`, { mode: \"stream\" });\n }\n\n if (args.wait) {\n const result = await wait({\n showProgress: !jsonOutput,\n timeout: parseDuration(args.timeout),\n until: args.until,\n });\n if (args.logs && !jsonOutput) {\n const { execution } = await getWorkflowExecution({\n executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n logs: true,\n });\n printExecutionWithLogs(execution);\n } else if (args.logs) {\n const { execution } = await getWorkflowExecution({\n executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n logs: true,\n });\n logger.out({ ...result, jobDetails: execution.jobDetails });\n } else {\n logger.out(result);\n }\n const failureMessage = getWorkflowWaitFailureMessage(result, args.until);\n if (failureMessage) {\n throw new Error(failureMessage);\n }\n } else {\n logger.out({ executionId });\n }\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { parseDuration, workspaceArgs } from \"#/cli/shared/args\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { workflowWaitControlArgs } from \"./args\";\nimport { getWorkflowExecution, printExecutionWithLogs } from \"./executions\";\nimport {\n getWorkflowWaitFailureMessage,\n waitForWorkflowExecutionById,\n type WaitWorkflowExecutionOptions,\n type WorkflowWaitResult,\n} from \"./waiter\";\n\nexport interface WorkflowWaitOutput extends WorkflowWaitResult {\n jobDetails?: Awaited<ReturnType<typeof getWorkflowExecution>>[\"execution\"][\"jobDetails\"];\n}\n\n/**\n * Wait for an existing workflow execution by ID.\n * @param options - Workflow wait options\n * @returns Workflow wait result\n */\nexport async function waitWorkflowExecution(\n options: WaitWorkflowExecutionOptions,\n): Promise<WorkflowWaitResult> {\n return await waitForWorkflowExecutionById({\n ...options,\n showProgress: options.showProgress ?? !logger.jsonMode,\n trackJobs: options.trackJobs ?? true,\n });\n}\n\n/**\n * Attach workflow job logs to a wait result when requested.\n * @param result - Workflow wait result\n * @param options - Workflow wait options\n * @returns Workflow wait result with optional job details\n */\nexport async function addWorkflowLogsToWaitResult(\n result: WorkflowWaitResult,\n options: WaitWorkflowExecutionOptions,\n): Promise<WorkflowWaitOutput> {\n const { execution } = await getWorkflowExecution({\n executionId: options.executionId,\n workspaceId: options.workspaceId,\n profile: options.profile,\n logs: true,\n });\n\n return {\n ...result,\n jobDetails: execution.jobDetails,\n };\n}\n\nexport const waitCommand = defineAppCommand({\n name: \"wait\",\n description: \"Wait for a workflow execution.\",\n examples: [\n {\n cmd: \"execution-id --until success --timeout 10m --json\",\n desc: \"Wait for workflow success\",\n },\n {\n cmd: \"execution-id --until suspended --timeout 6m --logs --json\",\n desc: \"Wait for a workflow wait point\",\n },\n {\n cmd: \"execution-id --until terminal\",\n desc: \"Wait for success, failure, or suspension\",\n },\n ],\n args: z.strictObject({\n ...workspaceArgs,\n \"execution-id\": arg(z.string(), {\n positional: true,\n description: \"Execution ID\",\n }),\n ...workflowWaitControlArgs,\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode || args.json;\n const result = await waitWorkflowExecution({\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval: parseDuration(args.interval),\n timeout: parseDuration(args.timeout),\n until: args.until,\n showProgress: !jsonOutput,\n });\n\n const output: WorkflowWaitOutput = args.logs\n ? await addWorkflowLogsToWaitResult(result, {\n executionId: args.executionId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n })\n : result;\n\n if (!jsonOutput && output.jobDetails) {\n printExecutionWithLogs({\n id: output.id,\n workflowName: output.workflowName,\n status: output.status,\n jobExecutions: output.jobExecutions,\n startedAt: output.startedAt,\n finishedAt: output.finishedAt,\n jobDetails: output.jobDetails,\n });\n } else {\n logger.out(output);\n }\n\n const failureMessage = getWorkflowWaitFailureMessage(result, args.until);\n if (failureMessage) {\n throw new Error(failureMessage);\n }\n },\n});\n","import {\n type GetApplicationSchemaHealthResponse,\n GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus,\n} from \"@tailor-platform/tailor-proto/application_pb\";\nimport { ApplicationSchemaUpdateAttemptStatus } from \"@tailor-platform/tailor-proto/application_resource_pb\";\nimport { formatTimestamp } from \"#/cli/shared/format\";\nimport type { Application } from \"@tailor-platform/tailor-proto/application_resource_pb\";\n\nexport interface AppInfo {\n name: string;\n domain: string;\n authNamespace: string;\n createdAt: Date | null;\n updatedAt: Date | null;\n}\n\nexport interface AppHealthInfo {\n name: string;\n status: string;\n currentServingSchemaUpdatedAt: Date | null;\n lastAttemptStatus: string;\n lastAttemptAt: Date | null;\n lastAttemptError: string;\n}\n\nconst statusToString = (\n status: GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus,\n): string => {\n switch (status) {\n case GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus.OK:\n return \"ok\";\n case GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus.COMPOSITION_ERROR:\n return \"composition_error\";\n default:\n return \"unknown\";\n }\n};\n\nconst attemptStatusToString = (status: ApplicationSchemaUpdateAttemptStatus): string => {\n switch (status) {\n case ApplicationSchemaUpdateAttemptStatus.SUCCEEDED:\n return \"success\";\n case ApplicationSchemaUpdateAttemptStatus.FAILED:\n return \"failure\";\n default:\n return \"unknown\";\n }\n};\n\nexport const appInfo = (app: Application): AppInfo => {\n return {\n name: app.name,\n domain: app.domain,\n authNamespace: app.authNamespace,\n createdAt: formatTimestamp(app.createTime),\n updatedAt: formatTimestamp(app.updateTime),\n };\n};\n\nexport const appHealthInfo = (\n name: string,\n health: GetApplicationSchemaHealthResponse,\n): AppHealthInfo => {\n const attempt = health.lastSchemaUpdateAttempt;\n return {\n name,\n status: statusToString(health.status),\n currentServingSchemaUpdatedAt: formatTimestamp(health.currentServingSchemaUpdateTime),\n lastAttemptStatus: attempt ? attemptStatusToString(attempt.status) : \"N/A\",\n lastAttemptAt: formatTimestamp(attempt?.attemptTime),\n lastAttemptError: attempt?.error ?? \"\",\n };\n};\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { appHealthInfo, type AppHealthInfo } from \"./transform\";\n\n// strip unknown keys\nconst healthOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n name: z.string().min(1, { message: \"name is required\" }),\n});\n\nexport type HealthOptions = z.input<typeof healthOptionsSchema>;\n\nasync function loadOptions(options: HealthOptions) {\n const result = healthOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n name: result.data.name,\n };\n}\n\n/**\n * Get application schema health status.\n * @param options - Health check options\n * @returns Application health information\n */\nexport async function getAppHealth(options: HealthOptions): Promise<AppHealthInfo> {\n const { client, workspaceId, name } = await loadOptions(options);\n\n const response = await client.getApplicationSchemaHealth({\n workspaceId,\n applicationName: name,\n });\n\n return appHealthInfo(name, response);\n}\n\nexport const healthCommand = defineAppCommand({\n name: \"health\",\n description: \"Check application schema health\",\n args: z.strictObject({\n ...workspaceArgs,\n name: arg(z.string(), {\n description: \"Application name\",\n alias: \"n\",\n }),\n }),\n run: async (args) => {\n const health = await getAppHealth({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n name: args.name,\n });\n\n const formattedHealth = args.json\n ? health\n : {\n ...health,\n currentServingSchemaUpdatedAt: humanizeRelativeTime(health.currentServingSchemaUpdatedAt),\n lastAttemptAt: humanizeRelativeTime(health.lastAttemptAt),\n };\n\n logger.out(formattedHealth);\n },\n});\n","import { z } from \"zod\";\nimport { orderArg, paginationArgs, toPageDirection, workspaceArgs } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { appInfo, type AppInfo } from \"./transform\";\n\n// strip unknown keys\nconst listAppsOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n order: orderArg.optional(),\n limit: z.coerce.number().int().nonnegative().optional(),\n});\n\nexport type ListAppsOptions = z.input<typeof listAppsOptionsSchema>;\n\nasync function loadOptions(options: ListAppsOptions) {\n const result = listAppsOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n order: result.data.order,\n limit: result.data.limit,\n };\n}\n\n/**\n * List applications in a workspace with an optional order and limit.\n * @param options - Application listing options\n * @returns List of applications\n */\nexport async function listApps(options: ListAppsOptions): Promise<AppInfo[]> {\n const { client, workspaceId, order, limit } = await loadOptions(options);\n\n const pageDirection = toPageDirection(order);\n const applications = await fetchPaged(\n async (pageToken, pageSize) => {\n const { applications, nextPageToken } = await client.listApplications({\n workspaceId,\n pageToken,\n pageSize,\n pageDirection,\n });\n return [applications, nextPageToken];\n },\n { limit },\n );\n\n return applications.map(appInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List applications in a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const jsonOutput = logger.jsonMode;\n const apps = await listApps({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n order: args.order,\n limit: args.limit,\n });\n\n const formattedApps = jsonOutput\n ? apps\n : apps.map(({ updatedAt: _, createdAt, ...rest }) => ({\n ...rest,\n createdAt: humanizeRelativeTime(createdAt),\n }));\n\n logger.out(formattedApps);\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { confirmationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, readPlatformConfig, writePlatformConfig } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { resolveWorkspaceFolderName, workspaceDisplayName } from \"./transform\";\n\n// strip unknown keys\nconst deleteWorkspaceOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }),\n});\n\nexport type DeleteWorkspaceOptions = z.input<typeof deleteWorkspaceOptionsSchema>;\n\nasync function loadOptions(options: DeleteWorkspaceOptions) {\n // Validate options with zod schema\n const result = deleteWorkspaceOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n return {\n client,\n workspaceId: result.data.workspaceId,\n };\n}\n\n/**\n * Delete a workspace by ID.\n * @param options - Workspace deletion options\n * @returns Promise that resolves when deletion completes\n */\nexport async function deleteWorkspace(options: DeleteWorkspaceOptions): Promise<void> {\n // Load and validate options\n const { client, workspaceId } = await loadOptions(options);\n\n // Delete workspace\n await client.deleteWorkspace({\n workspaceId,\n });\n}\n\nexport const deleteCommand = defineAppCommand({\n name: \"delete\",\n description: \"Delete a Tailor Platform workspace.\",\n args: z.strictObject({\n \"workspace-id\": arg(z.string(), {\n alias: \"w\",\n description: \"Workspace ID\",\n }),\n ...confirmationArgs,\n }),\n run: async (args) => {\n await assertWritable();\n // Load and validate options\n const { client, workspaceId } = await loadOptions({\n workspaceId: args[\"workspace-id\"],\n });\n\n // Check if workspace exists\n let workspace;\n try {\n workspace = await client.getWorkspace({\n workspaceId,\n });\n } catch {\n throw new Error(`Workspace \"${workspaceId}\" not found.`);\n }\n\n const workspaceResource = workspace.workspace;\n const workspaceName = workspaceResource?.name ?? workspaceId;\n const folderName = workspaceResource\n ? await resolveWorkspaceFolderName(client, workspaceResource)\n : \"\";\n const displayName = workspaceDisplayName({ name: workspaceName, folderName });\n\n // Confirm deletion if not forced\n if (!args.yes) {\n const confirmation = await prompt.text({\n message: `Enter the workspace name to confirm deletion (${displayName}):`,\n });\n if (confirmation !== workspaceName && confirmation !== displayName) {\n logger.info(\"Workspace deletion cancelled.\");\n return;\n }\n }\n\n // Delete workspace\n await client.deleteWorkspace({\n workspaceId,\n });\n\n // Remove profiles associated with the deleted workspace\n const pfConfig = await readPlatformConfig();\n const profilesToDelete = Object.entries(pfConfig.profiles).filter(\n ([, profile]) => profile?.workspace_id === workspaceId,\n );\n if (profilesToDelete.length > 0) {\n for (const [profileName] of profilesToDelete) {\n delete pfConfig.profiles[profileName];\n }\n writePlatformConfig(pfConfig);\n }\n\n // Show success message\n if (profilesToDelete.length > 0) {\n logger.success(\n `Workspace \"${displayName}\" and ${profilesToDelete.length} associated profile(s) deleted successfully.`,\n );\n } else {\n logger.success(`Workspace \"${displayName}\" deleted successfully.`);\n }\n },\n});\n","import { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { humanizeRelativeTime } from \"#/cli/shared/format\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport {\n workspaceDetailsWithFolderName,\n workspaceNameTransformer,\n type WorkspaceDetails,\n} from \"./transform\";\n\n// strip unknown keys\nconst getWorkspaceOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n});\n\nexport type GetWorkspaceOptions = z.input<typeof getWorkspaceOptionsSchema>;\n\nasync function loadOptions(options: GetWorkspaceOptions) {\n const result = getWorkspaceOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n };\n}\n\n/**\n * Get detailed information about a workspace.\n * @param options - Workspace get options\n * @returns Workspace details\n */\nexport async function getWorkspace(options: GetWorkspaceOptions): Promise<WorkspaceDetails> {\n const { client, workspaceId } = await loadOptions(options);\n\n const response = await client.getWorkspace({\n workspaceId,\n });\n\n if (!response.workspace) {\n throw new Error(`Workspace \"${workspaceId}\" not found.`);\n }\n\n return workspaceDetailsWithFolderName(client, response.workspace);\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Show detailed information about a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n }),\n run: async (args) => {\n const workspace = await getWorkspace({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n\n const formattedWorkspace = args.json\n ? workspace\n : {\n ...workspace,\n createdAt: humanizeRelativeTime(workspace.createdAt),\n updatedAt: humanizeRelativeTime(workspace.updatedAt),\n };\n\n logger.out(formattedWorkspace, {\n display: { name: workspaceNameTransformer, folderName: null },\n });\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { confirmationArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\n\n// strip unknown keys\nconst restoreWorkspaceOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }),\n});\n\nexport type RestoreWorkspaceOptions = z.input<typeof restoreWorkspaceOptionsSchema>;\n\nasync function loadOptions(options: RestoreWorkspaceOptions) {\n const result = restoreWorkspaceOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\n return {\n client,\n workspaceId: result.data.workspaceId,\n };\n}\n\n/**\n * Restore a deleted workspace by ID.\n * @param options - Workspace restore options\n * @returns Promise that resolves when restoration completes\n */\nexport async function restoreWorkspace(options: RestoreWorkspaceOptions): Promise<void> {\n const { client, workspaceId } = await loadOptions(options);\n\n await client.restoreWorkspace({\n workspaceId,\n });\n}\n\nexport const restoreCommand = defineAppCommand({\n name: \"restore\",\n description: \"Restore a deleted workspace\",\n args: z.strictObject({\n \"workspace-id\": arg(z.string(), {\n alias: \"w\",\n description: \"Workspace ID\",\n }),\n ...confirmationArgs,\n }),\n run: async (args) => {\n await assertWritable();\n const { client, workspaceId } = await loadOptions({\n workspaceId: args[\"workspace-id\"],\n });\n\n if (!args.yes) {\n const confirmation = await prompt.text({\n message: `Are you sure you want to restore workspace \"${workspaceId}\"? (yes/no):`,\n });\n if (confirmation !== \"yes\") {\n logger.info(\"Workspace restoration cancelled.\");\n return;\n }\n }\n\n await client.restoreWorkspace({\n workspaceId,\n });\n\n logger.success(`Workspace \"${workspaceId}\" restored successfully.`);\n },\n});\n","import { WorkspacePlatformUserRole } from \"@tailor-platform/tailor-proto/workspace_resource_pb\";\nimport type { WorkspacePlatformUser } from \"@tailor-platform/tailor-proto/workspace_resource_pb\";\n\nexport interface UserInfo {\n userId: string;\n email: string;\n role: string;\n}\n\nconst roleToString = (role: WorkspacePlatformUserRole): string => {\n switch (role) {\n case WorkspacePlatformUserRole.ADMIN:\n return \"admin\";\n case WorkspacePlatformUserRole.EDITOR:\n return \"editor\";\n case WorkspacePlatformUserRole.VIEWER:\n return \"viewer\";\n default:\n return \"unknown\";\n }\n};\n\nexport const stringToRole = (role: string): WorkspacePlatformUserRole => {\n switch (role.toLowerCase()) {\n case \"admin\":\n return WorkspacePlatformUserRole.ADMIN;\n case \"editor\":\n return WorkspacePlatformUserRole.EDITOR;\n case \"viewer\":\n return WorkspacePlatformUserRole.VIEWER;\n default:\n throw new Error(`Invalid role: ${role}. Valid roles: admin, editor, viewer`);\n }\n};\n\nexport const userInfo = (user: WorkspacePlatformUser): UserInfo => {\n return {\n userId: user.platformUser?.userId ?? \"\",\n email: user.platformUser?.email ?? \"\",\n role: roleToString(user.role),\n };\n};\n\nexport const validRoles = [\"admin\", \"editor\", \"viewer\"] as const;\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { stringToRole, validRoles } from \"./transform\";\n\n// strip unknown keys\nconst inviteUserOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n email: z.email({ message: \"email must be a valid email address\" }),\n role: z.enum(validRoles, { message: `role must be one of: ${validRoles.join(\", \")}` }),\n});\n\nexport type InviteUserOptions = z.input<typeof inviteUserOptionsSchema>;\n\nasync function loadOptions(options: InviteUserOptions) {\n const result = inviteUserOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n email: result.data.email,\n role: stringToRole(result.data.role),\n };\n}\n\n/**\n * Invite a user to a workspace.\n * @param options - User invite options\n * @returns Promise that resolves when invitation is sent\n */\nexport async function inviteUser(options: InviteUserOptions): Promise<void> {\n const { client, workspaceId, email, role } = await loadOptions(options);\n\n await client.inviteWorkspacePlatformUser({\n workspaceId,\n email,\n role,\n });\n}\n\nexport const inviteCommand = defineAppCommand({\n name: \"invite\",\n description: \"Invite a user to a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n email: arg(z.email(), {\n description: \"Email address of the user to invite\",\n }),\n role: arg(z.enum(validRoles), {\n description: `Role to assign (${validRoles.join(\", \")})`,\n alias: \"r\",\n }),\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n await inviteUser({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n email: args.email,\n role: args.role as (typeof validRoles)[number],\n });\n\n logger.success(`User \"${args.email}\" invited successfully with role \"${args.role}\".`);\n },\n});\n","import { z } from \"zod\";\nimport { orderArg, paginationArgs, toPageDirection, workspaceArgs } from \"#/cli/shared/args\";\nimport { fetchPaged, initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { userInfo, type UserInfo } from \"./transform\";\n\n// strip unknown keys\nconst listUsersOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n order: orderArg.optional(),\n limit: z.coerce.number().int().nonnegative().optional(),\n});\n\nexport type ListUsersOptions = z.input<typeof listUsersOptionsSchema>;\n\nasync function loadOptions(options: ListUsersOptions) {\n const result = listUsersOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n order: result.data.order,\n limit: result.data.limit,\n };\n}\n\n/**\n * List users in a workspace with an optional order and limit.\n * @param options - User listing options\n * @returns List of workspace users\n */\nexport async function listUsers(options: ListUsersOptions): Promise<UserInfo[]> {\n const { client, workspaceId, order, limit } = await loadOptions(options);\n\n const pageDirection = toPageDirection(order);\n const users = await fetchPaged(\n async (pageToken, pageSize) => {\n const { workspacePlatformUsers, nextPageToken } = await client.listWorkspacePlatformUsers({\n workspaceId,\n pageToken,\n pageSize,\n pageDirection,\n });\n return [workspacePlatformUsers, nextPageToken];\n },\n { limit },\n );\n\n return users.map(userInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List users in a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n ...paginationArgs(),\n }),\n run: async (args) => {\n const users = await listUsers({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n order: args.order,\n limit: args.limit,\n });\n\n logger.out(users);\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { confirmationArgs, workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { prompt } from \"#/cli/shared/prompt\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\n\n// strip unknown keys\nconst removeUserOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n email: z.string().email({ message: \"email must be a valid email address\" }),\n});\n\nexport type RemoveUserOptions = z.input<typeof removeUserOptionsSchema>;\n\nasync function loadOptions(options: RemoveUserOptions) {\n const result = removeUserOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n email: result.data.email,\n };\n}\n\n/**\n * Remove a user from a workspace.\n * @param options - User remove options\n * @returns Promise that resolves when removal completes\n */\nexport async function removeUser(options: RemoveUserOptions): Promise<void> {\n const { client, workspaceId, email } = await loadOptions(options);\n\n await client.removeWorkspacePlatformUser({\n workspaceId,\n email,\n });\n}\n\nexport const removeCommand = defineAppCommand({\n name: \"remove\",\n description: \"Remove a user from a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n email: arg(z.email(), {\n description: \"Email address of the user to remove\",\n }),\n ...confirmationArgs,\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n if (!args.yes) {\n const confirmation = await prompt.text({\n message: `Are you sure you want to remove user \"${args.email}\" from the workspace? (yes/no):`,\n });\n if (confirmation !== \"yes\") {\n logger.info(\"User removal cancelled.\");\n return;\n }\n }\n\n await removeUser({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n email: args.email,\n });\n\n logger.success(`User \"${args.email}\" removed from workspace.`);\n },\n});\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { workspaceArgs } from \"#/cli/shared/args\";\nimport { initOperatorClient } from \"#/cli/shared/client\";\nimport { defineAppCommand } from \"#/cli/shared/command\";\nimport { loadAccessToken, loadWorkspaceId } from \"#/cli/shared/context\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { assertWritable } from \"#/cli/shared/readonly-guard\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { stringToRole, validRoles } from \"./transform\";\n\n// strip unknown keys\nconst updateUserOptionsSchema = z.object({\n workspaceId: z.uuid({ message: \"workspace-id must be a valid UUID\" }).optional(),\n profile: z.string().optional(),\n email: z.string().email({ message: \"email must be a valid email address\" }),\n role: z.enum(validRoles, { message: `role must be one of: ${validRoles.join(\", \")}` }),\n});\n\nexport type UpdateUserOptions = z.input<typeof updateUserOptionsSchema>;\n\nasync function loadOptions(options: UpdateUserOptions) {\n const result = updateUserOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(assertDefined(result.error.issues[0], \"Zod returned no issues\").message);\n }\n\n const accessToken = await loadAccessToken({ profile: result.data.profile });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n\n return {\n client,\n workspaceId,\n email: result.data.email,\n role: stringToRole(result.data.role),\n };\n}\n\n/**\n * Update a user's role in a workspace.\n * @param options - User update options\n * @returns Promise that resolves when update completes\n */\nexport async function updateUser(options: UpdateUserOptions): Promise<void> {\n const { client, workspaceId, email, role } = await loadOptions(options);\n\n await client.updateWorkspacePlatformUser({\n workspaceId,\n email,\n role,\n });\n}\n\nexport const updateCommand = defineAppCommand({\n name: \"update\",\n description: \"Update a user's role in a workspace\",\n args: z.strictObject({\n ...workspaceArgs,\n email: arg(z.email(), {\n description: \"Email address of the user to update\",\n }),\n role: arg(z.enum(validRoles), {\n description: `New role to assign (${validRoles.join(\", \")})`,\n alias: \"r\",\n }),\n }),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n await updateUser({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n email: args.email,\n role: args.role as (typeof validRoles)[number],\n });\n\n logger.success(`User \"${args.email}\" updated to role \"${args.role}\".`);\n },\n});\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { createTsconfigPathsPlugin } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createGeneratedEntryResolverPlugin } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport type { QueryEngine } from \"#/cli/query/types\";\n\nfunction createSqlEntry(): string {\n return ml /* ts */ `\n import { Kysely, sql, TailordbDialect } from \"@tailor-platform/sdk/kysely\";\n\n type QueryInput = {\n namespace: string;\n queries: string[];\n };\n\n function getDB(namespace: string) {\n const client = new tailordb.Client({ namespace });\n return new Kysely<Record<string, Record<string, unknown>>>({\n dialect: new TailordbDialect(client),\n });\n }\n\n export async function main(input: QueryInput) {\n const db = getDB(input.namespace);\n const results = [];\n for (const query of input.queries) {\n const result = await sql.raw(query).execute(db);\n const rows = result.rows ?? [];\n results.push({ rows, rowCount: rows.length });\n }\n if (results.length === 1) {\n return results[0];\n }\n return results;\n }\n `;\n}\n\nfunction createGqlEntry(): string {\n return ml /* ts */ `\n type QueryInput = {\n endpoint: string;\n accessToken: string;\n query: string;\n };\n\n export async function main(input: QueryInput) {\n const response = await fetch(input.endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \\`Bearer \\${input.accessToken}\\`,\n },\n body: JSON.stringify({\n query: input.query,\n }),\n });\n if (!response.ok) {\n let message = \\`HTTP \\${response.status}\\`;\n try {\n const errorJson = await response.json();\n if (errorJson && typeof errorJson === \"object\" && \"message\" in errorJson) {\n message = String(errorJson.message);\n }\n } catch {\n // Keep default HTTP status message when response body is not JSON.\n }\n throw new Error(\\`GraphQL request failed: \\${message}\\`);\n }\n\n const json = await response.json();\n return json;\n }\n `;\n}\n\n/**\n * Bundle a query executor script for TestExecScript.\n * @param engine - Query engine type\n * @param baseDir - Directory to resolve the bundler's tsconfig against\n * @returns Bundled code\n */\nexport async function bundleQueryScript(engine: QueryEngine, baseDir: string): Promise<string> {\n const outputDir = path.resolve(getDistDir(), \"query\");\n fs.mkdirSync(outputDir, { recursive: true });\n\n const entryPath = path.join(outputDir, `query_${engine}.entry.ts`);\n const entryContent = engine === \"sql\" ? createSqlEntry() : createGqlEntry();\n fs.writeFileSync(entryPath, entryContent);\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n plugins: [\n createGeneratedEntryResolverPlugin(entryPath, baseDir),\n createTsconfigPathsPlugin(),\n platformBundleDefinePlugin,\n ],\n input: entryPath,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: false,\n minify: false,\n codeSplitting: false,\n globals: {\n tailordb: \"tailordb\",\n },\n },\n external: engine === \"sql\" ? [\"tailordb\"] : [],\n resolve: {\n conditionNames: [\"node\", \"import\"],\n },\n tsconfig,\n treeshake: {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n },\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n return result.output[0].code;\n}\n","import { CLIError } from \"../shared/errors\";\nimport type { QueryEngine } from \"./types\";\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\ntype MapQueryExecutionErrorArgs = {\n error: unknown;\n engine: QueryEngine;\n namespace: string | undefined;\n machineUser?: string;\n};\n\n/**\n * Maps errors from query execution to user-friendly CLI errors with suggestions when possible.\n * @param args - The error and context information for mapping\n * @returns A CLIError with a user-friendly message\n */\nexport function mapQueryExecutionError(args: MapQueryExecutionErrorArgs): Error {\n const message = toErrorMessage(args.error);\n\n if (message.includes(\"machine user does not exist\")) {\n return CLIError({\n code: \"not_found\",\n message: `Machine user '${args.machineUser ?? \"unknown\"}' was not found.`,\n suggestion: \"Run `tailor machineuser list` and use an existing name.\",\n });\n }\n\n if (\n args.engine === \"sql\" &&\n message.includes(\n \"sqlaccess error: failed to fetch schema: query returned an unexpected number of rows\",\n )\n ) {\n return CLIError({\n code: \"invalid_namespace\",\n message: `Failed to load TailorDB schema for namespace '${args.namespace}'.`,\n suggestion:\n \"Ensure the query references TailorDB types from a single namespace and re-apply if needed.\",\n });\n }\n\n if (args.engine === \"sql\" && message.includes(\"sqlaccess error: failed to parse:\")) {\n const parserReason = message\n .split(\"sqlaccess error: failed to parse:\")\n .at(1)\n ?.split(\"\\n\")\n .at(0)\n ?.trim();\n\n return CLIError({\n code: \"invalid_sql\",\n message: \"SQL parse error.\",\n suggestion: parserReason ?? \"The SQL query contains unsupported syntax.\",\n });\n }\n\n return args.error instanceof Error ? args.error : new Error(message);\n}\n","import { parse } from \"@0no-co/graphql.web\";\n\n/**\n * Return true when the buffered GraphQL input parses as a complete document.\n * @param input - Buffered GraphQL input\n * @returns True when the GraphQL document is complete and ready to execute\n */\nexport function isGraphQLInputComplete(input: string): boolean {\n if (input.trim().length === 0) {\n return false;\n }\n\n try {\n parse(input);\n return true;\n } catch {\n return false;\n }\n}\n","import { assertDefined } from \"#/utils/assert\";\n\n/**\n * Return true when the buffered SQL input ends with a real statement terminator.\n * @param input - Buffered SQL input\n * @returns True when the SQL statement is complete and ready to execute\n */\nexport function isSqlInputComplete(input: string): boolean {\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let inLineComment = false;\n let blockCommentDepth = 0;\n let dollarQuoteTag: string | null = null;\n let lastSignificantTokenWasSemicolon = false;\n\n for (let i = 0; i < input.length; i += 1) {\n const char = assertDefined(input[i], `character at index ${i} missing`);\n const next = input[i + 1];\n\n if (inLineComment) {\n if (char === \"\\n\") {\n inLineComment = false;\n }\n continue;\n }\n\n if (blockCommentDepth > 0) {\n if (char === \"/\" && next === \"*\") {\n blockCommentDepth += 1;\n i += 1;\n continue;\n }\n if (char === \"*\" && next === \"/\") {\n blockCommentDepth -= 1;\n i += 1;\n }\n continue;\n }\n\n if (dollarQuoteTag != null) {\n if (input.startsWith(dollarQuoteTag, i)) {\n i += dollarQuoteTag.length - 1;\n dollarQuoteTag = null;\n }\n continue;\n }\n\n if (inSingleQuote) {\n if (char === \"'\" && next === \"'\") {\n i += 1;\n continue;\n }\n if (char === \"'\") {\n inSingleQuote = false;\n }\n continue;\n }\n\n if (inDoubleQuote) {\n if (char === '\"' && next === '\"') {\n i += 1;\n continue;\n }\n if (char === '\"') {\n inDoubleQuote = false;\n }\n continue;\n }\n\n if (char === \"-\" && next === \"-\") {\n inLineComment = true;\n i += 1;\n continue;\n }\n\n if (char === \"/\" && next === \"*\") {\n blockCommentDepth = 1;\n i += 1;\n continue;\n }\n\n if (char === \"'\") {\n lastSignificantTokenWasSemicolon = false;\n inSingleQuote = true;\n continue;\n }\n\n if (char === '\"') {\n lastSignificantTokenWasSemicolon = false;\n inDoubleQuote = true;\n continue;\n }\n\n if (char === \"$\") {\n const rest = input.slice(i);\n const match = rest.match(/^\\$[A-Za-z_][A-Za-z0-9_]*\\$/) ?? rest.match(/^\\$\\$/);\n if (match != null) {\n lastSignificantTokenWasSemicolon = false;\n dollarQuoteTag = match[0];\n i += match[0].length - 1;\n continue;\n }\n }\n\n if (char === \";\") {\n lastSignificantTokenWasSemicolon = true;\n continue;\n }\n\n if (!/\\s/.test(char)) {\n lastSignificantTokenWasSemicolon = false;\n }\n }\n\n return (\n lastSignificantTokenWasSemicolon &&\n !inSingleQuote &&\n !inDoubleQuote &&\n blockCommentDepth === 0 &&\n dollarQuoteTag == null\n );\n}\n","import { astVisitor, parse, type From, type Statement } from \"pgsql-ast-parser\";\n\n/**\n * Extract TailorDB type names from SQL query.\n * @param query - SQL query\n * @returns Type names referenced by query\n */\nexport function extractTypeNamesFromSql(query: string): string[] {\n let statements: Statement[];\n try {\n statements = parse(query);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQL parse error: ${message}\\nIf your table name is a reserved keyword (e.g. User), wrap it in double quotes: SELECT * FROM \"User\"`,\n { cause: error },\n );\n }\n const typeNames = new Set<string>();\n\n const visitor = astVisitor((mapper) => ({\n tableRef: (tableRef) => {\n typeNames.add(tableRef.name);\n\n mapper.super().tableRef(tableRef);\n return tableRef;\n },\n }));\n\n for (const statement of statements) {\n visitor.statement(statement);\n }\n\n return [...typeNames];\n}\n\nfunction collectAliasMap(fromClauses: From[]): Map<string, string> {\n const aliasMap = new Map<string, string>();\n\n for (const from of fromClauses) {\n if (from.type === \"table\") {\n const tableName = from.name.name;\n const alias = from.name.alias ?? tableName;\n aliasMap.set(alias, tableName);\n }\n }\n\n return aliasMap;\n}\n\nexport type ColumnSlot =\n | { type: \"explicit\"; name: string }\n | { type: \"wildcard\"; typeNames: string[] };\n\n/**\n * Extract the column template from a SQL query's SELECT clause.\n * Returns an ordered list of column slots representing explicit columns\n * and wildcard expansions with their resolved type names.\n *\n * Only inspects the top-level SELECT statement, not subqueries.\n * TailorDB's sqlaccess does not currently support subqueries in FROM clauses,\n * but we intentionally avoid recursing into nested SELECTs to prevent\n * false positives if the parser accepts such queries.\n * @param query - SQL query\n * @returns Column slots if wildcards are present, null otherwise\n */\nexport function extractColumnTemplate(query: string): ColumnSlot[] | null {\n try {\n const statements = parse(query);\n\n for (const statement of statements) {\n if (statement.type !== \"select\" || !statement.columns) {\n continue;\n }\n\n const aliasMap = collectAliasMap(statement.from ?? []);\n const slots: ColumnSlot[] = [];\n let hasWildcard = false;\n\n for (const column of statement.columns) {\n if (column.expr.type === \"ref\" && column.expr.name === \"*\") {\n hasWildcard = true;\n if (column.expr.table) {\n const typeName = aliasMap.get(column.expr.table.name);\n slots.push({ type: \"wildcard\", typeNames: typeName ? [typeName] : [] });\n } else {\n slots.push({ type: \"wildcard\", typeNames: [...new Set(aliasMap.values())] });\n }\n } else {\n const name = column.alias?.name ?? (column.expr.type === \"ref\" ? column.expr.name : null);\n if (name) {\n slots.push({ type: \"explicit\", name });\n }\n }\n }\n\n return hasWildcard ? slots : null;\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","import { pathToFileURL } from \"node:url\";\nimport * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { stripTailorDBTypeBuilderHelpers } from \"#/parser/service/tailordb/builder-helpers\";\nimport { TailorDBTypeSchema } from \"#/parser/service/tailordb/index\";\nimport type { LoadedConfig } from \"#/cli/shared/config-loader\";\n\ntype TypeFieldOrderMap = Map<string, string[]>;\n\n/**\n * Load field definition order for all TailorDB types in a namespace.\n * @param config - Loaded application configuration\n * @param namespace - TailorDB namespace name\n * @returns Map of type name to field names in definition order\n */\nexport async function loadTypeFieldOrder(\n config: LoadedConfig,\n namespace: string,\n): Promise<TypeFieldOrderMap> {\n const fieldOrder: TypeFieldOrderMap = new Map();\n const dbConfig = config.db?.[namespace];\n\n if (!dbConfig || !(\"files\" in dbConfig) || dbConfig.files.length === 0) {\n return fieldOrder;\n }\n\n const baseDir = path.dirname(config.path);\n const typeFiles = loadFilesWithIgnores(dbConfig, baseDir);\n\n await Promise.all(\n typeFiles.map(async (typeFile) => {\n try {\n const module = await import(pathToFileURL(typeFile).href);\n\n for (const exportedValue of Object.values(module)) {\n const result = TailorDBTypeSchema.safeParse(\n stripTailorDBTypeBuilderHelpers(exportedValue),\n );\n if (!result.success) {\n continue;\n }\n\n fieldOrder.set(result.data.name, Object.keys(result.data.fields));\n }\n } catch {\n // Skip files that fail to load\n }\n }),\n );\n\n return fieldOrder;\n}\n","export const queryEngines = [\"sql\", \"gql\"] as const;\n\nexport type QueryEngine = (typeof queryEngines)[number];\n","import * as fs from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { create } from \"@bufbuild/protobuf\";\nimport {\n AuthInvokerSchema,\n type AuthInvoker,\n type MachineUser,\n} from \"@tailor-platform/tailor-proto/auth_resource_pb\";\nimport { createPrompt } from \"@toiroakr/read-multiline\";\nimport * as path from \"pathe\";\nimport { parse as parseSql } from \"pgsql-ast-parser\";\nimport { arg } from \"politty\";\nimport { xdgConfig } from \"xdg-basedir\";\nimport { z } from \"zod\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { bundleQueryScript } from \"../bundler/query/query-bundler\";\nimport { deploymentArgs, resolveMachineUserInputSource } from \"../shared/args\";\nimport { fetchMachineUserToken, initOperatorClient } from \"../shared/client\";\nimport { defineAppCommand } from \"../shared/command\";\nimport { extractAllNamespaces } from \"../shared/config\";\nimport { loadConfig, type LoadedConfig } from \"../shared/config-loader\";\nimport { loadAccessToken, loadMachineUserName, loadWorkspaceId } from \"../shared/context\";\nimport { getEditorCommand, openInEditor } from \"../shared/editor\";\nimport { isCLIError } from \"../shared/errors\";\nimport { logger } from \"../shared/logger\";\nimport { parseBoolean } from \"../shared/parse-boolean\";\nimport { executeScript } from \"../shared/script-executor\";\nimport { resolveTypeNamespaces } from \"../shared/tailordb-namespace\";\nimport { mapQueryExecutionError } from \"./errors\";\nimport { isGraphQLInputComplete } from \"./graphql-repl\";\nimport { isSqlInputComplete } from \"./sql-repl\";\nimport {\n extractColumnTemplate,\n extractTypeNamesFromSql,\n type ColumnSlot,\n} from \"./sql-type-extractor\";\nimport { loadTypeFieldOrder } from \"./type-field-order\";\nimport { queryEngines, type QueryEngine } from \"./types\";\nimport type { Application } from \"@tailor-platform/tailor-proto/application_resource_pb\";\n\nexport type { QueryEngine } from \"./types\";\n\nconst queryEngineSchema = z.enum(queryEngines);\n// strip unknown keys\nconst queryBaseOptionsSchema = z.object({\n workspaceId: z.string().optional(),\n profile: z.string().optional(),\n configPath: z.string().optional(),\n engine: queryEngineSchema,\n machineUser: z.string().optional(),\n machineUserSource: z.enum([\"option\", \"env\"]).optional(),\n});\nconst queryOptionsSchema = queryBaseOptionsSchema.extend({\n query: z.string(),\n});\n\ntype QueryOptions = z.input<typeof queryOptionsSchema>;\ntype QueryBaseOptions = z.input<typeof queryBaseOptionsSchema>;\ntype QuerySharedOptions = Omit<QueryOptions, \"engine\">;\ntype Client = Awaited<ReturnType<typeof initOperatorClient>>;\n\ntype SQLQueryDispatchResult = {\n engine: \"sql\";\n namespace: string;\n query: string;\n result: unknown;\n};\n\ntype GQLQueryDispatchResult = {\n engine: \"gql\";\n query: string;\n result: unknown;\n};\n\ntype QueryDispatchResult = SQLQueryDispatchResult | GQLQueryDispatchResult;\n\ntype SQLResultRow = Record<string, unknown>;\ntype SQLExecutionResult = {\n rows: SQLResultRow[];\n rowCount: number;\n};\n\ntype QueryCommandInput =\n | {\n mode: \"query\";\n query: string;\n }\n | {\n mode: \"repl\";\n }\n | {\n mode: \"abort\";\n };\n\ntype ReplCommand = \"quit\" | \"help\" | \"clear\" | \"unknown\";\n\nasync function getNamespaceFromSqlQuery(\n workspaceId: string,\n query: string,\n client: Client,\n namespaces: string[],\n): Promise<string> {\n if (namespaces.length === 0) {\n throw new Error(\"No namespaces found in configuration.\");\n }\n\n if (namespaces.length === 1) {\n return assertDefined(namespaces[0], \"namespace missing\");\n }\n\n const typeNames = extractTypeNamesFromSql(query);\n if (typeNames.length === 0) {\n throw new Error(\n `Could not infer namespace from query. Detected namespaces: ${namespaces.join(\", \")}.`,\n );\n }\n\n const typeNamespaceMap = await resolveTypeNamespaces({\n workspaceId,\n namespaces,\n typeNames,\n client,\n });\n\n const notFoundTypes = typeNames.filter((typeName) => !typeNamespaceMap.has(typeName));\n if (notFoundTypes.length > 0) {\n throw new Error(`Could not find namespace for types in query: ${notFoundTypes.join(\", \")}.`);\n }\n\n const namespacesFromTypes = new Set(typeNamespaceMap.values());\n if (namespacesFromTypes.size === 1) {\n return assertDefined([...namespacesFromTypes][0], \"namespace from types missing\");\n }\n\n throw new Error(\n `Query references types from multiple namespaces: ${[...namespacesFromTypes].join(\", \")}.`,\n );\n}\n\nasync function loadOptions(options: QueryBaseOptions) {\n const result = queryBaseOptionsSchema.safeParse(options);\n\n if (!result.success) {\n throw new Error(\n assertDefined(result.error.issues[0], \"validation error missing issues\").message,\n );\n }\n\n const machineUser = await loadMachineUserName({\n machineUser: result.data.machineUser,\n machineUserSource: result.data.machineUserSource,\n profile: result.data.profile,\n });\n if (!machineUser) {\n throw new Error(\n \"Machine user is required. Specify --machine-user, set TAILOR_PLATFORM_MACHINE_USER_NAME, or set a profile default with 'tailor profile update <profile> --machine-user <name>'.\",\n );\n }\n\n const accessToken = await loadAccessToken({\n profile: result.data.profile,\n });\n const client = await initOperatorClient(accessToken);\n const workspaceId = await loadWorkspaceId({\n workspaceId: result.data.workspaceId,\n profile: result.data.profile,\n });\n const { config } = await loadConfig(options.configPath);\n const namespaces = extractAllNamespaces(config);\n const { application } = await client.getApplication({\n workspaceId,\n applicationName: config.name,\n });\n\n if (!application?.authNamespace) {\n throw new Error(`Application ${config.name} does not have an auth configuration.`);\n }\n\n const { machineUser: machineUserResource } = await client.getAuthMachineUser({\n workspaceId: workspaceId,\n authNamespace: application.authNamespace,\n name: machineUser,\n });\n\n if (!machineUserResource) {\n throw new Error(`Machine user ${machineUser} not found.`);\n }\n\n return {\n engine: result.data.engine,\n client,\n workspaceId,\n config,\n application,\n machineUserResource,\n namespaces,\n };\n}\n\nasync function sqlQuery(\n client: Client,\n invoker: AuthInvoker,\n args: {\n workspaceId: string;\n namespace: string;\n bundledCode: string;\n query: string;\n },\n): Promise<SQLQueryDispatchResult> {\n const queries = splitSqlStatements(args.query);\n const executed = await executeScript({\n client,\n workspaceId: args.workspaceId,\n name: `query-sql-${args.namespace}.js`,\n code: args.bundledCode,\n arg: {\n namespace: args.namespace,\n queries,\n },\n invoker,\n });\n\n if (!executed.success) {\n throw new Error(executed.error);\n }\n\n return {\n engine: \"sql\" as const,\n namespace: args.namespace,\n query: args.query,\n result: parseExecutionResult(executed.result),\n };\n}\n\nasync function gqlQuery(\n client: Client,\n invoker: AuthInvoker,\n application: Application,\n machineUser: MachineUser,\n args: {\n workspaceId: string;\n bundledCode: string;\n query: string;\n },\n): Promise<GQLQueryDispatchResult> {\n const { access_token: accessToken } = await fetchMachineUserToken(\n application.url,\n machineUser.clientId,\n machineUser.clientSecret,\n );\n\n const executed = await executeScript({\n client,\n workspaceId: args.workspaceId,\n name: `query-gql.js`,\n code: args.bundledCode,\n arg: {\n endpoint: `${application.url}/query`,\n accessToken,\n query: args.query,\n },\n invoker,\n });\n\n if (!executed.success) {\n throw new Error(executed.error);\n }\n\n return {\n engine: \"gql\" as const,\n query: args.query,\n result: parseExecutionResult(executed.result),\n };\n}\n\nfunction parseExecutionResult(result: string): unknown {\n if (!result) {\n return null;\n }\n\n try {\n return JSON.parse(result);\n } catch {\n return result;\n }\n}\n\n/**\n * Resolve query input mode from CLI args.\n * @param args - Query input flags\n * @param args.query - Direct query string\n * @param args.file - File path containing query text\n * @param args.edit - Open a query editor instead of REPL\n * @param args.engine - Query engine used to choose temp file extension\n * @returns Normalized input mode\n */\nexport async function resolveQueryCommandInput(args: {\n query?: string;\n file?: string;\n edit?: boolean;\n engine: QueryEngine;\n}): Promise<QueryCommandInput> {\n if (args.query != null) {\n return {\n mode: \"query\",\n query: args.query,\n };\n }\n\n if (args.file != null) {\n return {\n mode: \"query\",\n query: await fs.readFile(args.file, \"utf-8\"),\n };\n }\n\n if (args.edit) {\n return await resolveEditedQueryInput(args.engine);\n }\n\n return {\n mode: \"repl\",\n };\n}\n\nasync function resolveEditedQueryInput(engine: QueryEngine): Promise<QueryCommandInput> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n throw new Error(\n \"Non-interactive terminals are not supported. Pass -q/--query or -f/--file to run a query.\",\n );\n }\n\n const editor = getEditorCommand();\n\n const tempDir = await fs.mkdtemp(path.join(tmpdir(), \"tailor-query-\"));\n const fileExtension = engine === \"sql\" ? \"sql\" : \"graphql\";\n const filePath = path.join(tempDir, `query.${fileExtension}`);\n const initialQuery = \"\";\n\n try {\n await fs.writeFile(filePath, initialQuery, \"utf-8\");\n try {\n await openInEditor(filePath, editor);\n } catch (error) {\n throw new Error(\n `Failed to open query editor \"${editor}\": ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n\n const editedQuery = await fs.readFile(filePath, \"utf-8\");\n if (editedQuery.trim().length === 0 || editedQuery === initialQuery) {\n return {\n mode: \"abort\",\n };\n }\n\n return {\n mode: \"query\",\n query: editedQuery,\n };\n } finally {\n await fs.rm(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Dispatch query execution.\n * @param options - Query command options\n * @returns Dispatch result\n */\nexport async function query(options: QueryOptions): Promise<QueryDispatchResult> {\n const result = queryOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(\n assertDefined(result.error.issues[0], \"validation error missing issues\").message,\n );\n }\n\n const executor = await prepareQueryExecutor(result.data);\n return await executor(result.data.query);\n}\n\nasync function prepareQueryExecutor(\n options: QueryBaseOptions,\n): Promise<(query: string) => Promise<QueryDispatchResult>> {\n const { client, workspaceId, config, application, machineUserResource, engine, namespaces } =\n await loadOptions(options);\n const bundledCode = await bundleQueryScript(engine, path.dirname(config.path));\n const invoker = create(AuthInvokerSchema, {\n namespace: application.authNamespace,\n machineUserName: machineUserResource.name,\n });\n\n return async (queryString: string) => {\n let namespace: string | undefined;\n\n try {\n switch (engine) {\n case \"sql\": {\n namespace = await getNamespaceFromSqlQuery(workspaceId, queryString, client, namespaces);\n const result = await sqlQuery(client, invoker, {\n workspaceId,\n namespace,\n bundledCode,\n query: queryString,\n });\n return reorderSqlColumns(result, config, namespace, queryString);\n }\n case \"gql\":\n return await gqlQuery(client, invoker, application, machineUserResource, {\n workspaceId,\n bundledCode,\n query: queryString,\n });\n default:\n throw new Error(`Unsupported query engine: ${engine satisfies never}`);\n }\n } catch (error) {\n throw mapQueryExecutionError({\n error,\n engine,\n namespace,\n machineUser: machineUserResource.name,\n });\n }\n };\n}\n\n/**\n * Resolve a backslash REPL command into its normalized action.\n * @param input - Raw user input\n * @returns Normalized REPL command, or null for non-command input\n */\nexport function resolveReplCommand(input: string): ReplCommand | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"\\\\\")) {\n return null;\n }\n\n if (trimmed === \"\\\\q\" || trimmed === \"\\\\quit\") {\n return \"quit\";\n }\n\n if (trimmed === \"\\\\help\" || trimmed === \"\\\\h\" || trimmed === \"\\\\?\") {\n return \"help\";\n }\n\n if (trimmed === \"\\\\clear\" || trimmed === \"\\\\c\") {\n return \"clear\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Clear the interactive terminal screen and move the cursor to the top-left.\n */\nfunction clearReplScreen(): void {\n process.stdout.write(\"\\u001Bc\");\n}\n\nfunction sanitizeHistoryScope(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n}\n\nexport function getReplHistoryPath(\n engine: QueryEngine,\n profile: string | undefined,\n workspaceId: string | undefined,\n): string | undefined {\n if (!xdgConfig) {\n return undefined;\n }\n const scope = [profile, workspaceId]\n .filter((value): value is string => Boolean(value))\n .map(sanitizeHistoryScope)\n .join(\"-\");\n const engineSlug = engine === \"sql\" ? \"sql\" : \"gql\";\n const suffix = scope ? `-${scope}` : \"\";\n return path.join(xdgConfig, \"tailor-platform\", `query-history-${engineSlug}${suffix}.json`);\n}\n\n// TODO: Empty input and REPL commands (e.g. \\help, \\q) are treated as valid by\n// the validator, so read-multiline saves them to history on submit. The library\n// does not expose a history filter hook; a clean fix requires upstream support.\nfunction createReplValidator(engine: QueryEngine): (value: string) => string | undefined {\n return (value: string) => {\n const trimmed = value.trim();\n if (trimmed === \"\") {\n return undefined;\n }\n if (resolveReplCommand(trimmed) !== null) {\n return undefined;\n }\n if (engine === \"sql\") {\n return isSqlInputComplete(value) ? undefined : \"SQL statement is incomplete (missing ';').\";\n }\n return isGraphQLInputComplete(value) ? undefined : \"GraphQL document is incomplete.\";\n };\n}\n\nasync function runRepl(\n options: QueryBaseOptions & {\n json?: boolean;\n newlineOnEnter: boolean;\n },\n): Promise<void> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n throw new Error(\n \"Non-interactive terminals are not supported. Pass -q/--query or -f/--file to run a query.\",\n );\n }\n\n const execute = await prepareQueryExecutor(options);\n const historyPath = getReplHistoryPath(options.engine, options.profile, options.workspaceId);\n const validate = createReplValidator(options.engine);\n // Lazy-load the editor module so the `graphql` and `sql-highlight` libs are\n // only pulled in when the REPL is actually entered, not on every CLI startup.\n const { highlightSqlLine, highlightGraphqlLine, replTransform } = await import(\"./repl-editor\");\n const highlight = options.engine === \"sql\" ? highlightSqlLine : highlightGraphqlLine;\n\n // NOTE: Each prompt() call reloads history from the file synchronously while the\n // previous call's async save may still be in-flight. In practice the race window\n // is only visible on fast paths (\\help, \\clear) whose entries are already non-ideal\n // for history (see createReplValidator TODO). Actual queries include network latency\n // that closes the window. A clean fix requires the library to export history utilities.\n const prompt = createPrompt({\n prefix: \"\",\n preferNewlineOnEnter: options.newlineOnEnter,\n validate,\n highlight,\n transform: replTransform,\n clearAfterSubmit: false,\n history: historyPath ? { filePath: historyPath, maxEntries: 100 } : [],\n helpFooter: { items: [\"submit\", \"newline\"], maxLines: 1 },\n });\n\n logger.info(`Entering ${options.engine.toUpperCase()} REPL mode.`);\n logger.info(\"Type \\\\help for usage, \\\\q to quit.\");\n\n // loop exits when the user types the quit command\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const [value, error] = await prompt(`${options.engine}> `);\n\n if (error?.kind === \"cancel\") {\n if (value.length === 0) {\n return;\n }\n continue;\n }\n\n if (error?.kind === \"eof\") {\n return;\n }\n\n const trimmed = value.trim();\n if (trimmed === \"\") {\n continue;\n }\n\n const command = resolveReplCommand(trimmed);\n if (command === \"quit\") {\n return;\n }\n if (command === \"help\") {\n printReplHelp(options.engine);\n continue;\n }\n if (command === \"clear\") {\n clearReplScreen();\n continue;\n }\n if (command === \"unknown\") {\n logger.warn(`Unknown command: ${trimmed}`);\n continue;\n }\n\n try {\n const result = await execute(trimmed);\n if (result.engine === \"sql\") {\n printSqlResult(result, { json: options.json });\n } else {\n printGqlResult(result, { json: options.json });\n }\n } catch (error) {\n if (isCLIError(error)) {\n logger.log(error.format());\n continue;\n }\n if (error instanceof Error) {\n logger.error(error.message);\n continue;\n }\n logger.error(String(error));\n }\n }\n}\n\nfunction printReplHelp(engine: QueryEngine): void {\n logger.log(\"REPL commands:\");\n logger.log(\" \\\\help, \\\\h, \\\\? Show this help\");\n logger.log(\" \\\\q, \\\\quit Exit REPL\");\n logger.log(\" \\\\clear, \\\\c Clear the screen\");\n logger.log(\"\");\n logger.log(\"Key bindings (see footer for terminal-specific submit/newline keys):\");\n logger.log(\" Ctrl+J Insert newline (always available)\");\n logger.log(\" Ctrl+C Cancel current input\");\n logger.log(\" Ctrl+D Exit REPL (on empty input)\");\n logger.log(\" Ctrl+Z / Ctrl+Y Undo / Redo\");\n logger.log(\" Up/Down (first/last line) Navigate history\");\n logger.log(\"\");\n logger.log(\"Editing aids:\");\n logger.log(\" Syntax highlighting Enabled for the current engine\");\n logger.log(\" ( [ { Auto-inserts the matching closing bracket\");\n logger.log(\" Enter after open bracket Adds one indent level and closes the block\");\n logger.log(\"\");\n logger.log(\n engine === \"sql\"\n ? \"Input must end with ';' to submit.\"\n : \"Input must be a complete GraphQL document to submit.\",\n );\n}\n\n/**\n * Execute SQL query directly.\n * @param options - Shared query options\n * @returns SQL query result\n */\nasync function querySql(options: QuerySharedOptions): Promise<SQLQueryDispatchResult> {\n const result = await query({\n ...options,\n engine: \"sql\",\n });\n\n if (result.engine !== \"sql\") {\n throw new Error(`Expected sql engine result but got: ${result.engine}`);\n }\n\n return result;\n}\n\n/**\n * Execute GraphQL query directly.\n * @param options - Shared query options\n * @returns GraphQL query result\n */\nasync function queryGql(options: QuerySharedOptions): Promise<GQLQueryDispatchResult> {\n const result = await query({\n ...options,\n engine: \"gql\",\n });\n\n if (result.engine !== \"gql\") {\n throw new Error(`Expected gql engine result but got: ${result.engine}`);\n }\n\n return result;\n}\n\nasync function reorderSqlColumns(\n result: SQLQueryDispatchResult,\n config: LoadedConfig,\n namespace: string,\n sqlQuery: string,\n): Promise<SQLQueryDispatchResult> {\n if (!isSQLExecutionResult(result.result) || result.result.rows.length === 0) {\n return result;\n }\n\n const template = extractColumnTemplate(sqlQuery);\n if (!template) {\n return result;\n }\n\n try {\n const fieldOrder = await loadTypeFieldOrder(config, namespace);\n const expectedOrder = buildExpectedColumnOrder(template, fieldOrder);\n if (expectedOrder.length === 0) {\n return result;\n }\n\n const orderedRows = result.result.rows.map((row) => reorderRowByTemplate(row, expectedOrder));\n\n return {\n ...result,\n result: {\n ...result.result,\n rows: orderedRows,\n },\n };\n } catch {\n return result;\n }\n}\n\nconst SYSTEM_FIELD_ORDER = [\"id\"];\n\nfunction buildExpectedColumnOrder(\n template: ColumnSlot[],\n fieldOrder: Map<string, string[]>,\n): string[] {\n const order: string[] = [];\n\n for (const slot of template) {\n if (slot.type === \"explicit\") {\n order.push(slot.name);\n } else {\n for (const typeName of slot.typeNames) {\n order.push(...SYSTEM_FIELD_ORDER);\n order.push(...(fieldOrder.get(typeName) ?? []));\n }\n }\n }\n\n return order;\n}\n\nfunction reorderRowByTemplate(row: SQLResultRow, expectedOrder: string[]): SQLResultRow {\n const ordered: SQLResultRow = {};\n const rowKeys = new Set(Object.keys(row));\n\n // Build case-insensitive lookup: lowercased key → original key in row.\n // pgsql-ast-parser lowercases unquoted identifiers (PostgreSQL standard),\n // but TailorDB preserves the original case, so we need case-insensitive matching.\n const lowerToOriginal = new Map<string, string>();\n for (const key of rowKeys) {\n lowerToOriginal.set(key.toLowerCase(), key);\n }\n\n for (const key of expectedOrder) {\n const original = lowerToOriginal.get(key.toLowerCase());\n if (original != null && rowKeys.has(original)) {\n ordered[original] = row[original];\n rowKeys.delete(original);\n lowerToOriginal.delete(key.toLowerCase());\n }\n }\n\n for (const key of rowKeys) {\n ordered[key] = row[key];\n }\n\n return ordered;\n}\n\nexport const queryCommand = defineAppCommand({\n name: \"query\",\n description: \"Run SQL/GraphQL query.\",\n args: z\n .strictObject({\n ...deploymentArgs,\n engine: arg(queryEngineSchema, {\n description: \"Query engine (sql or gql)\",\n }),\n query: arg(z.string().optional(), {\n alias: \"q\",\n description: \"Query string to execute directly; omit to start REPL mode\",\n }),\n file: arg(z.string().optional(), {\n alias: \"f\",\n description: \"Read query string from file; omit to start REPL mode\",\n }),\n edit: arg(z.boolean().default(false), {\n description: \"Open a temporary file in your editor; omit to start REPL mode\",\n }),\n \"machine-user\": arg(z.string().optional(), {\n alias: \"m\",\n description:\n \"Machine user name for query execution. Falls back to the active profile's default machine user.\",\n env: \"TAILOR_PLATFORM_MACHINE_USER_NAME\",\n }),\n \"newline-on-enter\": arg(z.boolean().optional(), {\n description:\n \"REPL: when true, Enter inserts a newline and Shift+Enter submits. Use --no-newline-on-enter to swap.\",\n }),\n })\n .superRefine((args, ctx) => {\n if (args.query != null && args.file != null) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"file\"],\n message: \"Pass either -q/--query or -f/--file, not both.\",\n });\n }\n\n if (args.edit && args.query != null) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"edit\"],\n message: \"Pass only one of --edit, -q/--query, or -f/--file.\",\n });\n }\n\n if (args.edit && args.file != null) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"edit\"],\n message: \"Pass only one of --edit, -q/--query, or -f/--file.\",\n });\n }\n }),\n run: async (args) => {\n const mode = await resolveQueryCommandInput({\n query: args.query,\n file: args.file,\n edit: args.edit,\n engine: args.engine,\n });\n\n const sharedOptions: QueryBaseOptions = {\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n configPath: args.config,\n engine: args.engine,\n machineUser: args[\"machine-user\"],\n machineUserSource: resolveMachineUserInputSource(args[\"machine-user\"]),\n };\n\n if (mode.mode === \"abort\") {\n logger.info(\"Editor closed without a query. Nothing was executed.\");\n return;\n }\n\n if (mode.mode === \"repl\") {\n const newlineOnEnter =\n args[\"newline-on-enter\"] ?? parseBoolean(process.env.TAILOR_QUERY_NEWLINE_ON_ENTER) ?? true;\n await runRepl({\n ...sharedOptions,\n json: args.json,\n newlineOnEnter,\n });\n return;\n }\n\n const directQuery = mode.query;\n\n if (args.engine === \"sql\") {\n const result = await querySql({\n ...sharedOptions,\n query: directQuery,\n });\n printSqlResult(result, { json: args.json });\n return;\n }\n\n const result = await queryGql({\n ...sharedOptions,\n query: directQuery,\n });\n printGqlResult(result, { json: args.json });\n },\n});\n\nfunction isSQLExecutionResult(value: unknown): value is SQLExecutionResult {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<SQLExecutionResult>;\n return Array.isArray(candidate.rows) && typeof candidate.rowCount === \"number\";\n}\n\nfunction printSingleSqlResult(\n execResult: SQLExecutionResult,\n options: { json?: boolean } = {},\n): void {\n if (execResult.rows.length === 0) {\n if (options.json) {\n logger.out({ results: [], rowCount: 0 });\n return;\n }\n logger.info(\"No rows returned.\");\n return;\n }\n\n if (options.json) {\n logger.out({ results: execResult.rows, rowCount: execResult.rowCount });\n return;\n }\n\n logger.out(execResult.rows, { showNull: true });\n logger.out(`rows: ${execResult.rowCount}`);\n}\n\nfunction splitSqlStatements(query: string): string[] {\n const statements = parseSql(query, { locationTracking: true });\n // Extract original SQL text using AST location info instead of re-serializing\n // to preserve the user's original casing and syntax.\n // _location.end is unreliable for INSERT/UPDATE statements (https://github.com/oguimbal/pgsql-ast-parser/issues/135),\n // so we use the next statement's start (or end of string) as the boundary.\n return statements.map((s, i) => {\n const start = assertDefined(s._location, \"SQL statement location missing\").start;\n const nextStmt = statements[i + 1];\n const end =\n nextStmt !== undefined\n ? assertDefined(nextStmt._location, \"SQL statement location missing\").start\n : query.length;\n return query.substring(start, end);\n });\n}\n\nfunction isSQLExecutionResultArray(value: unknown): value is SQLExecutionResult[] {\n return Array.isArray(value) && value.length > 0 && value.every(isSQLExecutionResult);\n}\n\nfunction printSqlResult(result: SQLQueryDispatchResult, options: { json?: boolean } = {}): void {\n if (isSQLExecutionResultArray(result.result)) {\n if (options.json) {\n logger.out(result.result.map((r) => ({ results: r.rows, rowCount: r.rowCount })));\n return;\n }\n const queries = splitSqlStatements(result.query);\n for (let i = 0; i < result.result.length; i++) {\n if (i > 0) logger.log(\"\");\n logger.info(queries[i] ?? `Statement ${i + 1}`);\n printSingleSqlResult(\n assertDefined(result.result[i], `SQL result at index ${i} missing`),\n options,\n );\n }\n return;\n }\n\n if (isSQLExecutionResult(result.result)) {\n printSingleSqlResult(result.result, options);\n return;\n }\n\n logger.out({\n engine: result.engine,\n query: result.query,\n result: result.result,\n });\n}\n\nfunction printGqlResult(result: GQLQueryDispatchResult, options: { json?: boolean } = {}): void {\n if (options.json) {\n logger.out({\n result: result.result,\n });\n return;\n }\n\n logger.out(JSON.stringify(result.result, null, 2));\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { isCLIError, type CLIErrorNextAction } from \"./errors\";\n\nexport interface ErrorToJsonOptions {\n /** Include the original stack trace in the error envelope. */\n includeStack?: boolean;\n}\n\n/**\n * Convert a CLI failure into the stable JSON error envelope.\n * @param error - Failure to serialize\n * @param options - JSON serialization options\n * @returns JSON-compatible error envelope\n */\nexport function errorToJson(\n error: unknown,\n options?: ErrorToJsonOptions,\n): { error: Readonly<Record<string, unknown>> } {\n if (isCLIError(error)) {\n return {\n error: {\n code: error.code ?? \"CLI_ERROR\",\n message: error.message,\n ...(error.details ? { details: error.details } : {}),\n ...(error.suggestion ? { suggestion: error.suggestion } : {}),\n ...(error.command\n ? {\n help: executableHelpAction(error.command),\n }\n : {}),\n ...(error.next ? { next: error.next } : {}),\n ...(error.context ? { context: error.context } : {}),\n ...(options?.includeStack && error.stack ? { stack: error.stack } : {}),\n },\n };\n }\n if (error instanceof ConnectError) {\n const codeName = Code[error.code];\n const stableCode =\n typeof codeName === \"string\"\n ? codeName.replaceAll(/([a-z0-9])([A-Z])/g, \"$1_$2\").toUpperCase()\n : `CODE_${error.code}`;\n return {\n error: {\n code: `RPC_${stableCode}`,\n message: error.message,\n ...(options?.includeStack && error.stack ? { stack: error.stack } : {}),\n },\n };\n }\n if (error instanceof Error) {\n return {\n error: {\n code: error.name === \"CIPromptError\" ? \"INTERACTIVE_PROMPT_REQUIRED\" : \"UNEXPECTED_ERROR\",\n message: error.message,\n ...(options?.includeStack && error.stack ? { stack: error.stack } : {}),\n },\n };\n }\n return { error: { code: \"UNKNOWN_ERROR\", message: String(error) } };\n}\n\n/**\n * Serialize a CLI failure into the stable JSON error envelope.\n * @param error - Failure to serialize\n * @param options - JSON serialization options\n * @returns Serialized JSON error envelope\n */\nexport function serializeError(error: unknown, options?: ErrorToJsonOptions): string {\n const envelope = errorToJson(error, options);\n try {\n return JSON.stringify(envelope);\n } catch {\n const fallbackError = { ...envelope.error };\n delete fallbackError.context;\n delete fallbackError.stack;\n return JSON.stringify({ error: fallbackError });\n }\n}\n\nfunction executableHelpAction(command: string): CLIErrorNextAction {\n return {\n command: \"tailor\",\n args: [...command.split(/\\s+/).filter(Boolean), \"--help\"],\n };\n}\n","/**\n * Check if the current runtime natively supports TypeScript execution.\n * Bun and Deno can execute TypeScript without tsx or other loaders.\n *\n * Note: Deno is detected here for correct loader/transport selection, but\n * the CLI is not fully tested on Deno yet. Other dependencies may fail.\n * @returns true if running on Bun or Deno\n */\nexport function isNativeTypeScriptRuntime(): boolean {\n return isBun() || isDeno();\n}\n\n/**\n * Check if the current runtime is Bun.\n * @returns true if running on Bun\n */\nexport function isBun(): boolean {\n return \"Bun\" in globalThis;\n}\n\n/**\n * Check if the current runtime is Deno.\n * @returns true if running on Deno\n */\nexport function isDeno(): boolean {\n return \"Deno\" in globalThis;\n}\n","import * as mod from \"node:module\";\nimport { isNativeTypeScriptRuntime } from \"./runtime\";\n\nexport async function registerTsHook(tsHookUrl: URL): Promise<void> {\n if (isNativeTypeScriptRuntime()) return;\n const { resolveSync, loadSync } = (await import(tsHookUrl.href)) as {\n resolveSync: Parameters<typeof mod.registerHooks>[0][\"resolve\"];\n loadSync: Parameters<typeof mod.registerHooks>[0][\"load\"];\n };\n mod.registerHooks({ resolve: resolveSync, load: loadSync });\n}\n"],"mappings":"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"}