@tailor-platform/sdk 1.60.1 → 1.60.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-C0_FZWdE.mjs","names":["fs","CLIError","CLIError","listCommand","listCommand","fs","crypto","planServices","planServices","fs","planServices","fs","waitForExecution","#indent","#stream","#isEnabled","#writeLine","#started","#renderFrame","#timer","#clearDrawn","#stopAndPersist","#frame","#linesDrawn","fs","fs","nameArgs","getCommand","sleep","formatTime","colorizeStatus","getCommand","formatTime","setTimeout","listCommand","loadOptions","getCommand","loadOptions","listCommand","fs","generate","listCommand","getCommand","listCommand","createCommand","deleteCommand","getCommand","listCommand","updateCommand","getCommand","listCommand","updateCommand","loadOptions","removeCommand","fs","fsPromises","listCommand","loadOptions","loadOptions","listCommand","loadOptions","loadOptions","listCommand","loadOptions","loadOptions","loadOptions","loadOptions","loadOptions","CLIError","parseSql"],"sources":["../src/cli/shared/args.ts","../src/cli/shared/command.ts","../src/cli/shared/readonly-guard.ts","../src/cli/commands/api/api-call.ts","../src/cli/commands/api/proto-reflect.ts","../src/cli/commands/api/render.ts","../src/cli/commands/api/inspect.ts","../src/cli/commands/api/list.ts","../src/cli/commands/api/index.ts","../src/cli/shared/prompt.ts","../src/cli/cache/types.ts","../src/cli/cache/store.ts","../src/cli/cache/manager.ts","../src/cli/shared/type-generator.ts","../src/types/plugin-generation.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/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/config-id-injector.ts","../src/cli/commands/deploy/confirm.ts","../src/cli/commands/deploy/auth-invoker.ts","../src/cli/commands/deploy/owned-resource.ts","../src/cli/commands/deploy/executor.ts","../src/cli/commands/deploy/resolver.ts","../src/cli/commands/deploy/secret-manager.ts","../src/cli/commands/deploy/staticwebsite.ts","../src/cli/commands/tailordb/migrate/config.ts","../src/cli/commands/tailordb/migrate/diff-calculator.ts","../src/cli/commands/tailordb/migrate/migration-number.ts","../src/cli/commands/tailordb/migrate/snapshot-types.ts","../src/cli/commands/tailordb/migrate/snapshot.ts","../src/cli/commands/tailordb/migrate/snapshot-manifest.ts","../src/cli/commands/tailordb/migrate/pre-migration-schema.ts","../src/cli/commands/tailordb/migrate/bundler.ts","../src/cli/commands/tailordb/migrate/types.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/deploy.ts","../src/cli/commands/executor/status.ts","../src/cli/commands/executor/transform.ts","../src/cli/commands/executor/get.ts","../src/cli/shared/format.ts","../src/cli/shared/function-execution.ts","../src/cli/commands/workflow/args.ts","../src/cli/commands/workflow/status.ts","../src/cli/commands/workflow/transform.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/commands/generate/types.ts","../src/cli/commands/generate/watch/index.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/commands/show.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/generate.ts","../src/cli/shared/config.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/workspace/app/transform.ts","../src/cli/commands/workspace/app/health.ts","../src/cli/commands/workspace/app/list.ts","../src/cli/commands/workspace/transform.ts","../src/cli/commands/workspace/create.ts","../src/cli/commands/workspace/delete.ts","../src/cli/commands/workspace/get.ts","../src/cli/commands/workspace/list.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/runtime.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport { parseEnv } from \"node:util\";\nimport { PageDirection } from \"@tailor-proto/tailor/v1/resource_pb\";\nimport * as path from \"pathe\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { logger } from \"./logger\";\n\ntype ArgsShape = Record<string, z.ZodType>;\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 return parseInt(match[1], 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 = duration.match(durationPattern)!;\n const value = parseInt(match[1], 10);\n const unit = match[2] 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\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 * Shared config arg for commands that accept a config file path\n */\nexport const configArg = {\n config: arg(z.string().default(\"tailor.config.ts\"), {\n alias: \"c\",\n description: \"Path to SDK config file\",\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 { 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-sdk profile update ${profileName} --permission write'.`,\n });\n}\n","import { platformBaseUrl, userAgent } from \"@/cli/shared/client\";\nimport { loadAccessToken } 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\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 useProfile: true,\n profile: options.profile,\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, platformBaseUrl);\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 { ScalarType } from \"@bufbuild/protobuf\";\nimport { OperatorService } from \"@tailor-proto/tailor/v1/service_pb\";\nimport type { DescField, DescMessage, DescMethodUnary } from \"@bufbuild/protobuf\";\n\n// `tailor-sdk api` issues a single JSON POST and reads one JSON response, so\n// only unary RPCs can be invoked. Streaming methods are filtered out of all\n// discovery surfaces (`api list`, `api inspect`). `OperatorService.methods`\n// is invariant at runtime, so we filter once and reuse — completion-script\n// generation walks every method and would otherwise re-filter per call.\nconst UNARY_METHODS: DescMethodUnary[] = OperatorService.methods.filter(\n (m): m is DescMethodUnary => m.methodKind === \"unary\",\n);\n\nexport function listMethodNames(): string[] {\n return UNARY_METHODS.map((m) => m.name).toSorted();\n}\n\n/**\n * Returns every accepted form of the `endpoint` positional — bare method name\n * and fully-qualified `service/Method`. politty's expand completion keys its\n * static table by the literal endpoint string, so both forms must appear in\n * `choices` or the user typing the fully-qualified name gets no `--field`\n * completion candidates back at TAB time.\n * @returns Sorted list of accepted endpoint values\n */\nexport function listMethodChoices(): string[] {\n return UNARY_METHODS.flatMap((m) => [m.name, `${OperatorService.typeName}/${m.name}`]).toSorted();\n}\n\nexport function getMethodDescriptor(methodName: string): DescMethodUnary | undefined {\n return UNARY_METHODS.find((m) => m.name === methodName);\n}\n\nexport function extractMethodName(endpoint: string): string {\n if (!endpoint.includes(\"/\")) return endpoint;\n return endpoint.split(\"/\").pop() ?? endpoint;\n}\n\n/**\n * Returns the nested message descriptor when the field is a message, a list of\n * messages, or a map with message values. Otherwise returns undefined.\n * @param field - The proto field descriptor to inspect\n * @returns The nested message descriptor, or undefined when the field isn't message-shaped\n */\nexport function nestedMessage(field: DescField): DescMessage | undefined {\n if (field.fieldKind === \"message\") return field.message;\n if (field.fieldKind === \"list\" && field.listKind === \"message\") return field.message;\n if (field.fieldKind === \"map\" && field.mapKind === \"message\") return field.message;\n return undefined;\n}\n\n/**\n * Most `google.protobuf.*` well-known types serialize as scalars in proto JSON\n * (Timestamp/Duration → RFC3339/duration string, FieldMask → comma-joined\n * string, *Value wrappers → underlying primitive, etc.), so we must not let\n * `--field` drill into their internal fields. Treating them as leaves keeps\n * the completion and the body shape consistent with what the server expects.\n * @param message - The proto message descriptor to inspect\n * @returns True when the message is a well-known type\n */\nfunction isWellKnownType(message: DescMessage): boolean {\n return message.typeName.startsWith(\"google.protobuf.\");\n}\n\n// Well-known types whose proto JSON shape is an object/array/null/arbitrary\n// value — they cannot be expressed by a single `--field key=value` string.\n// Drill-down would build the wrong shape, and a flat `key=foo` would send\n// \"foo\" where the server expects e.g. an object; we skip them entirely from\n// completion and from leaf resolution.\nconst UNREPRESENTABLE_WELL_KNOWN_TYPES = new Set([\n \"google.protobuf.Struct\",\n \"google.protobuf.Value\",\n \"google.protobuf.ListValue\",\n \"google.protobuf.NullValue\",\n \"google.protobuf.Any\",\n \"google.protobuf.Empty\",\n]);\n\n/**\n * @param message - The proto message descriptor to inspect\n * @returns True when the message is a well-known type that `--field` cannot represent\n */\nfunction isUnrepresentableWellKnownType(message: DescMessage): boolean {\n return UNREPRESENTABLE_WELL_KNOWN_TYPES.has(message.typeName);\n}\n\nexport interface FieldCompletionCandidate {\n value: string;\n description: string;\n}\n\n/**\n * Pre-enumerates every `--field` completion candidate for `methodName`,\n * walking the input message tree to produce a flat list that the shell can\n * prefix-filter at TAB time. Used by the `expand` completion variant so no\n * Node process is spawned per keystroke.\n *\n * For each leaf field, emits `key=` (key completion). Enum leaves additionally\n * emit `key=ENUM_VALUE` per value, bool leaves emit `key=true` and\n * `key=false`. For nested messages, emits `key.` (drill-down) and recurses.\n *\n * Returns an empty array when `methodName` is unknown so the `expand`\n * generator stays exception-free at script-generation time.\n * @param methodName - Name of the unary RPC whose input message is being walked\n * @returns Flat list of `{ value, description }` candidates\n */\nexport function enumerateAllFieldCompletions(methodName: string): FieldCompletionCandidate[] {\n const method = getMethodDescriptor(methodName);\n if (!method) return [];\n\n const candidates: FieldCompletionCandidate[] = [];\n const visited = new Set<DescMessage>();\n\n function walk(message: DescMessage, prefix: string): void {\n visited.add(message);\n for (const field of message.fields) {\n // `--field` uses `key=value` with dotted keys building nested objects;\n // it has no syntax for arrays or maps. Skip list/map fields so we don't\n // tab-complete a path that `setNestedPath` would silently turn into the\n // wrong shape (e.g. `subgraphs.name=x` → `{subgraphs:{name:\"x\"}}` when\n // the proto expects a repeated message).\n if (field.fieldKind === \"list\" || field.fieldKind === \"map\") continue;\n const fullKey = prefix + field.localName;\n if (field.fieldKind === \"message\") {\n if (isUnrepresentableWellKnownType(field.message)) continue;\n if (!isWellKnownType(field.message)) {\n const nested = field.message;\n candidates.push({ value: `${fullKey}.`, description: `${fullKey} (message)` });\n if (!visited.has(nested)) walk(nested, `${fullKey}.`);\n continue;\n }\n // Representable well-known types (Timestamp, Duration, FieldMask, …)\n // fall through to a single `key=` leaf since proto JSON serializes\n // them as a scalar string.\n }\n candidates.push({ value: `${fullKey}=`, description: `Set ${fullKey}` });\n if (field.fieldKind === \"enum\") {\n for (const v of field.enum.values) {\n candidates.push({ value: `${fullKey}=${v.name}`, description: v.name });\n }\n } else if (field.fieldKind === \"scalar\" && field.scalar === ScalarType.BOOL) {\n candidates.push({ value: `${fullKey}=true`, description: \"true\" });\n candidates.push({ value: `${fullKey}=false`, description: \"false\" });\n }\n }\n visited.delete(message);\n }\n\n walk(method.input, \"\");\n return candidates;\n}\n\n/**\n * Resolves the leaf `DescField` at a dotted `--field` path within an input\n * message tree. Returns undefined when any segment is missing or when a\n * non-leaf segment isn't a singular message — callers fall back to treating\n * the value as a string in that case.\n * @param input - The RPC input message descriptor\n * @param path - Dot-split path segments to follow (e.g. [\"application\", \"name\"])\n * @returns The leaf field descriptor, or undefined when the path doesn't resolve\n */\nexport function resolveLeafField(input: DescMessage, path: string[]): DescField | undefined {\n let message = input;\n for (let i = 0; i < path.length; i++) {\n const field = message.fields.find((f) => f.localName === path[i]);\n if (!field) return undefined;\n if (i === path.length - 1) {\n // Refuse to resolve a leaf inside an unrepresentable well-known type —\n // even if the user typed `payload=...` for a Struct field manually,\n // we don't want to claim a scalar shape we can't actually coerce.\n if (field.fieldKind === \"message\" && isUnrepresentableWellKnownType(field.message)) {\n return undefined;\n }\n return field;\n }\n // Mirror enumerateAllFieldCompletions: don't drill into list/map fields\n // or well-known types — `--field` cannot represent their internal shape.\n if (field.fieldKind !== \"message\") return undefined;\n if (isWellKnownType(field.message)) return undefined;\n message = field.message;\n }\n return undefined;\n}\n","import { ScalarType } from \"@bufbuild/protobuf\";\nimport { nestedMessage } from \"./proto-reflect\";\nimport type { DescEnum, DescField, DescMessage, DescMethodUnary } from \"@bufbuild/protobuf\";\n\nexport interface InspectMessageJson {\n typeName: string;\n fields: InspectFieldJson[];\n /** True when truncated to break a recursive type cycle. */\n recursive?: boolean;\n}\n\nexport interface InspectFieldJson {\n name: string;\n protoName: string;\n type: string;\n fieldKind: string;\n repeated: boolean;\n enumValues?: string[];\n /** Name of the proto `oneof` group this field belongs to, if any. */\n oneof?: string;\n message?: InspectMessageJson | undefined;\n}\n\nexport interface InspectMethodJson {\n method: string;\n input: {\n typeName: string;\n fields: InspectFieldJson[];\n };\n output: {\n typeName: string;\n };\n}\n\nconst SCALAR_LABEL: Partial<Record<number, string>> = {\n [ScalarType.DOUBLE]: \"double\",\n [ScalarType.FLOAT]: \"float\",\n [ScalarType.INT64]: \"int64\",\n [ScalarType.UINT64]: \"uint64\",\n [ScalarType.INT32]: \"int32\",\n [ScalarType.FIXED64]: \"fixed64\",\n [ScalarType.FIXED32]: \"fixed32\",\n [ScalarType.BOOL]: \"bool\",\n [ScalarType.STRING]: \"string\",\n [ScalarType.BYTES]: \"bytes\",\n [ScalarType.UINT32]: \"uint32\",\n [ScalarType.SFIXED32]: \"sfixed32\",\n [ScalarType.SFIXED64]: \"sfixed64\",\n [ScalarType.SINT32]: \"sint32\",\n [ScalarType.SINT64]: \"sint64\",\n};\n\nfunction shortName(typeName: string): string {\n const dot = typeName.lastIndexOf(\".\");\n return dot < 0 ? typeName : typeName.slice(dot + 1);\n}\n\nfunction scalarLabel(scalar: ScalarType): string {\n return SCALAR_LABEL[scalar] ?? `scalar(${scalar})`;\n}\n\nfunction enumLabel(enumDesc: DescEnum): string {\n return `enum ${shortName(enumDesc.typeName)}`;\n}\n\nfunction enumOf(field: DescField): DescEnum | undefined {\n if (field.fieldKind === \"enum\") return field.enum;\n if (field.fieldKind === \"list\" && field.listKind === \"enum\") return field.enum;\n return undefined;\n}\n\nexport function describeFieldType(field: DescField): string {\n switch (field.fieldKind) {\n case \"scalar\":\n return scalarLabel(field.scalar);\n case \"enum\":\n return enumLabel(field.enum);\n case \"message\":\n return shortName(field.message.typeName);\n case \"list\": {\n let inner: string;\n if (field.listKind === \"scalar\") {\n inner = scalarLabel(field.scalar);\n } else if (field.listKind === \"enum\") {\n inner = enumLabel(field.enum);\n } else {\n inner = shortName(field.message.typeName);\n }\n return `repeated ${inner}`;\n }\n case \"map\": {\n const keyType = scalarLabel(field.mapKey);\n let valType: string;\n if (field.mapKind === \"scalar\") valType = scalarLabel(field.scalar);\n else if (field.mapKind === \"enum\") valType = enumLabel(field.enum);\n else valType = shortName(field.message.typeName);\n return `map<${keyType}, ${valType}>`;\n }\n default:\n return \"<unknown>\";\n }\n}\n\nfunction fieldToJson(field: DescField, visited: Set<DescMessage>): InspectFieldJson {\n const json: InspectFieldJson = {\n name: field.localName,\n protoName: field.name,\n type: describeFieldType(field),\n fieldKind: field.fieldKind,\n repeated: field.fieldKind === \"list\",\n };\n\n if (field.oneof) json.oneof = field.oneof.name;\n\n const fieldEnum = enumOf(field);\n if (fieldEnum) {\n json.enumValues = fieldEnum.values.map((v) => v.name);\n }\n\n const nested = nestedMessage(field);\n if (nested && !visited.has(nested)) {\n visited.add(nested);\n json.message = {\n typeName: nested.typeName,\n fields: nested.fields.map((f) => fieldToJson(f, visited)),\n };\n visited.delete(nested);\n } else if (nested) {\n json.message = { typeName: nested.typeName, fields: [], recursive: true };\n }\n\n return json;\n}\n\nexport function renderInspectJson(method: DescMethodUnary): InspectMethodJson {\n const visited = new Set<DescMessage>([method.input]);\n return {\n method: method.name,\n input: {\n typeName: method.input.typeName,\n fields: method.input.fields.map((f) => fieldToJson(f, visited)),\n },\n output: { typeName: method.output.typeName },\n };\n}\n\nfunction renderFieldText(field: DescField, indent: string, visited: Set<DescMessage>): string[] {\n const lines: string[] = [];\n const oneofTag = field.oneof ? ` (oneof ${field.oneof.name})` : \"\";\n lines.push(`${indent}${field.localName}: ${describeFieldType(field)}${oneofTag}`);\n\n const fieldEnum = enumOf(field);\n if (fieldEnum) {\n const values = fieldEnum.values.map((v) => v.name).join(\", \");\n lines.push(`${indent} values: ${values}`);\n }\n\n const nested = nestedMessage(field);\n if (nested && !visited.has(nested)) {\n visited.add(nested);\n for (const sub of nested.fields) {\n lines.push(...renderFieldText(sub, `${indent} `, visited));\n }\n visited.delete(nested);\n } else if (nested) {\n lines.push(`${indent} …(recursive ${nested.typeName})`);\n }\n\n return lines;\n}\n\nexport function renderInspectText(method: DescMethodUnary): string {\n const lines: string[] = [];\n lines.push(`${method.name}`);\n lines.push(` request: ${method.input.typeName}`);\n const visited = new Set<DescMessage>([method.input]);\n for (const f of method.input.fields) {\n lines.push(...renderFieldText(f, \" \", visited));\n }\n lines.push(` response: ${method.output.typeName}`);\n return lines.join(\"\\n\");\n}\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { defineAppCommand } from \"@/cli/shared/command\";\nimport { CLIError } from \"@/cli/shared/errors\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { extractMethodName, getMethodDescriptor, listMethodNames } from \"./proto-reflect\";\nimport { renderInspectJson, renderInspectText } from \"./render\";\n\nexport const inspectCommand = defineAppCommand({\n name: \"inspect\",\n description: \"Print the input message tree of an OperatorService endpoint.\",\n notes:\n \"Combine with the global `--json` flag for a machine-readable descriptor. Recursive type references and `oneof` membership are annotated. Use `tailor-sdk api list` to discover endpoint names.\",\n examples: [\n { cmd: \"GetApplication\", desc: \"Show fields of GetApplicationRequest.\" },\n {\n cmd: \"CreateExecutorExecutor\",\n desc: \"Inspect a deeply nested input with `(oneof config)` annotations.\",\n },\n ],\n args: z\n .object({\n endpoint: arg(z.string(), {\n positional: true,\n description:\n \"API endpoint to inspect (e.g., 'GetApplication' or 'tailor.v1.OperatorService/GetApplication').\",\n completion: { custom: { choices: listMethodNames() } },\n }),\n })\n .strict(),\n run: (args) => {\n const methodName = extractMethodName(args.endpoint);\n const method = getMethodDescriptor(methodName);\n if (!method) {\n throw CLIError({\n message: `unknown method: ${methodName}`,\n suggestion: \"Run `tailor-sdk api list` to see available methods.\",\n command: \"api inspect\",\n });\n }\n if (logger.jsonMode) {\n logger.out(renderInspectJson(method));\n } else {\n logger.out(renderInspectText(method));\n }\n },\n});\n","import { z } from \"zod\";\nimport { defineAppCommand } from \"@/cli/shared/command\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { listMethodNames } from \"./proto-reflect\";\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all invocable OperatorService methods.\",\n notes:\n \"Only single-request (non-streaming) methods are listed, because the CLI issues a single JSON request and reads one JSON response.\",\n args: z.object({}).strict(),\n run: () => {\n const names = listMethodNames();\n if (logger.jsonMode) {\n logger.out(names);\n } else {\n for (const name of names) logger.out(name);\n }\n },\n});\n","import { ScalarType } from \"@bufbuild/protobuf\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { configArg, workspaceArgs } from \"@/cli/shared/args\";\nimport { defineAppCommand } from \"@/cli/shared/command\";\nimport { loadConfig } from \"@/cli/shared/config-loader\";\nimport { loadWorkspaceId } from \"@/cli/shared/context\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { assertWritable } from \"@/cli/shared/readonly-guard\";\nimport { apiCall } from \"./api-call\";\nimport { inspectCommand } from \"./inspect\";\nimport { listCommand } from \"./list\";\nimport {\n enumerateAllFieldCompletions,\n extractMethodName,\n getMethodDescriptor,\n listMethodChoices,\n resolveLeafField,\n} from \"./proto-reflect\";\nimport type { LoadedConfig } from \"@/cli/shared/config-loader\";\nimport type { DescField } from \"@bufbuild/protobuf\";\n\nexport { apiCall, type ApiCallOptions, type ApiCallResult } from \"./api-call\";\n\nfunction resolveNamespaceName(methodName: string, config: LoadedConfig): string | undefined {\n if (/Auth|Tenant|UserProfile/.test(methodName)) {\n return config.auth?.name;\n }\n if (/IdP/.test(methodName)) {\n if (config.idp?.length === 1) return config.idp[0].name;\n return undefined;\n }\n if (/TailorDB/.test(methodName)) {\n const keys = Object.keys(config.db ?? {});\n if (keys.length === 1) return keys[0];\n return undefined;\n }\n if (/Pipeline/.test(methodName)) {\n const keys = Object.keys(config.resolver ?? {});\n if (keys.length === 1) return keys[0];\n return undefined;\n }\n return undefined;\n}\n\n/**\n * Parse a JSON body string as a plain object for field injection.\n * Returns undefined for invalid JSON or non-object values (null, arrays, primitives),\n * so callers can fall back to sending the raw string unchanged.\n * @param body - Raw body string\n * @returns Parsed object or undefined\n */\nfunction parseBodyAsObject(body: string): Record<string, unknown> | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n return undefined;\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return undefined;\n }\n return parsed as Record<string, unknown>;\n}\n\n/**\n * Set a dotted path on a body object, replacing non-object intermediates as\n * needed. `--field` takes precedence over `--body`, so collisions overwrite.\n * @param obj - The body object to mutate\n * @param path - Dot-split path segments (e.g. [\"application\", \"name\"])\n * @param value - Value to assign at the leaf\n */\nfunction setNestedPath(obj: Record<string, unknown>, path: string[], value: unknown): void {\n let cursor: Record<string, unknown> = obj;\n for (let i = 0; i < path.length - 1; i++) {\n const key = path[i];\n const next = cursor[key];\n if (typeof next !== \"object\" || next === null || Array.isArray(next)) {\n cursor[key] = {};\n }\n cursor = cursor[key] as Record<string, unknown>;\n }\n cursor[path[path.length - 1]] = value;\n}\n\n/**\n * Coerces a raw `--field` string value to match the leaf proto type so the\n * JSON body sends a properly typed value. Today we only coerce bool — the\n * completion candidates explicitly suggest `=true`/`=false`, so sending the\n * literal string \"true\" would be a visible mismatch. Other scalars are left\n * as strings: proto JSON accepts string forms for ints/floats/int64/etc.,\n * and we'd rather pass through what the user typed than silently coerce.\n * @param field - The resolved leaf field descriptor, or undefined when the path didn't resolve\n * @param raw - The raw string value after `=`\n * @returns The value to write into the body object\n */\nfunction coerceFieldValue(field: DescField | undefined, raw: string): unknown {\n if (field && field.fieldKind === \"scalar\" && field.scalar === ScalarType.BOOL) {\n if (raw === \"true\") return true;\n if (raw === \"false\") return false;\n throw new Error(`Invalid value for bool field: '${raw}'. Expected 'true' or 'false'.`);\n }\n return raw;\n}\n\ninterface ParsedField {\n path: string[];\n value: string;\n}\n\n/**\n * Collapse top-level body keys that address a known input field by its\n * protobuf name (snake_case) or JSON name to the field's `localName`. protojson\n * accepts every alias, so converging them here lets the presence checks below\n * reason in a single namespace — otherwise a `--body` written as\n * `{\"workspace_id\": ...}` slips past the camelCase check and we inject a second\n * `workspaceId`, which the server rejects as a duplicate field. When both forms\n * are present the canonical key wins and the alias is dropped.\n * @param body - The parsed body object to mutate\n * @param fields - The target endpoint's input fields\n * @returns Whether any key was rewritten\n */\nexport function normalizeBodyFieldKeys(\n body: Record<string, unknown>,\n fields: readonly DescField[],\n): boolean {\n const aliasToLocal = new Map<string, string>();\n for (const f of fields) {\n aliasToLocal.set(f.name, f.localName);\n aliasToLocal.set(f.jsonName, f.localName);\n }\n let changed = false;\n for (const key of Object.keys(body)) {\n const local = aliasToLocal.get(key);\n if (!local || local === key) continue;\n if (!Object.hasOwn(body, local)) body[local] = body[key];\n delete body[key];\n changed = true;\n }\n return changed;\n}\n\n// Prototype-pollution sinks: `setNestedPath` walks `cursor[key]`, so a\n// segment that resolves on `Object.prototype` (e.g. `__proto__`) would let an\n// untrusted dotted key mutate the runtime prototype instead of the body.\nconst FORBIDDEN_SEGMENTS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nconst fieldArg = z.string().transform((val, ctx): ParsedField => {\n const eq = val.indexOf(\"=\");\n if (eq < 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid field format: '${val}'. Expected format: 'key=value' or 'a.b.c=value'`,\n });\n return z.NEVER;\n }\n const key = val.slice(0, eq);\n if (key.length === 0) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: \"Field key cannot be empty\" });\n return z.NEVER;\n }\n const segments = key.split(\".\");\n if (segments.some((seg) => seg.length === 0)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid field key: '${key}'. Dotted segments cannot be empty`,\n });\n return z.NEVER;\n }\n const forbidden = segments.find((seg) => FORBIDDEN_SEGMENTS.has(seg));\n if (forbidden) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid field key: '${key}'. Segment '${forbidden}' is not allowed.`,\n });\n return z.NEVER;\n }\n return { path: segments, value: val.slice(eq + 1) };\n});\n\nexport const apiCommand = defineAppCommand({\n name: \"api\",\n description: \"Call Tailor Platform API endpoints directly.\",\n notes: `Use \\`tailor-sdk api list\\` to enumerate invocable methods and \\`tailor-sdk api inspect <endpoint>\\` to print an endpoint's input message tree (combine with \\`--json\\` for machine-readable output).\n\nThe request body is inferred from the target endpoint's request schema, and commonly required fields are auto-injected so they can be omitted from \\`--body\\`:\n\n- \\`workspaceId\\` — resolved from \\`-w\\` / \\`TAILOR_PLATFORM_WORKSPACE_ID\\` / the selected profile.\n- \\`namespaceName\\` — resolved from \\`tailor.config.ts\\` based on the endpoint's service:\n - Auth / Tenant / UserProfile endpoints use \\`auth.name\\`.\n - IdP / TailorDB / Pipeline endpoints use the sole configured namespace when exactly one is defined.\n\nValues already present in \\`--body\\` are never overridden. If a value cannot be resolved (e.g. no config found), injection is silently skipped and the server-side validation error takes precedence.\n\nUse \\`--field key=value\\` (repeatable) to set request body fields without writing JSON. Dotted keys (e.g. \\`application.name=foo\\`) build nested objects. \\`--field\\` overrides matching fields in \\`--body\\` and tab-completes from the endpoint's request schema.`,\n examples: [\n {\n cmd: 'GetApplication -b \\'{\"applicationName\":\"app-1\"}\\'',\n desc: \"Call an endpoint; workspaceId is auto-injected.\",\n },\n {\n cmd: \"GetApplication -f applicationName=app-1\",\n desc: \"Same as above, using --field instead of --body.\",\n },\n {\n cmd: \"list\",\n desc: \"List all invocable OperatorService methods.\",\n },\n {\n cmd: \"inspect GetApplication\",\n desc: \"Show the input message tree for an endpoint.\",\n },\n ],\n subCommands: {\n list: listCommand,\n inspect: inspectCommand,\n },\n args: z\n .object({\n ...workspaceArgs,\n ...configArg,\n body: arg(z.string().default(\"{}\"), {\n alias: \"b\",\n description: \"Request body as JSON.\",\n }),\n field: arg(fieldArg.array().optional(), {\n alias: \"f\",\n description:\n \"Set a body field as `key=value` (repeatable; dotted keys nest). Overrides --body.\",\n completion: {\n custom: {\n expand: {\n dependsOn: [\"endpoint\"],\n enumerate: ({ endpoint }) =>\n enumerateAllFieldCompletions(extractMethodName(endpoint ?? \"\")),\n },\n },\n },\n }),\n endpoint: arg(z.string(), {\n positional: true,\n description:\n \"API endpoint to call (e.g., 'GetApplication' or 'tailor.v1.OperatorService/GetApplication').\",\n completion: { custom: { choices: listMethodChoices() } },\n }),\n })\n .strict(),\n run: async (args) => {\n // Direct API calls can target any OperatorService method, including\n // Create/Update/Delete. Block all of them under a readonly profile rather\n // than try to classify endpoints by name.\n await assertWritable({ profile: args.profile });\n const methodName = extractMethodName(args.endpoint);\n const method = getMethodDescriptor(methodName);\n\n const parsedBody = parseBodyAsObject(args.body);\n let mutated = false;\n\n if (args.field && args.field.length > 0) {\n if (!parsedBody) {\n throw new Error(\"--field requires --body to be a JSON object (or omitted).\");\n }\n for (const f of args.field) {\n const leaf = method ? resolveLeafField(method.input, f.path) : undefined;\n setNestedPath(parsedBody, f.path, coerceFieldValue(leaf, f.value));\n }\n mutated = true;\n }\n\n if (parsedBody && method) {\n // Converge any snake_case / JSON aliases to each field's localName first,\n // so the presence checks below operate in a single (camelCase) namespace.\n if (normalizeBodyFieldKeys(parsedBody, method.input.fields)) {\n mutated = true;\n }\n\n const fieldNames = method.input.fields.map((f) => f.localName);\n\n if (fieldNames.includes(\"workspaceId\") && !Object.hasOwn(parsedBody, \"workspaceId\")) {\n try {\n parsedBody.workspaceId = await loadWorkspaceId({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n mutated = true;\n } catch {\n // Cannot resolve workspace ID — skip\n }\n }\n\n if (fieldNames.includes(\"namespaceName\") && !Object.hasOwn(parsedBody, \"namespaceName\")) {\n try {\n const { config } = await loadConfig(args.config);\n const ns = resolveNamespaceName(methodName, config);\n if (ns) {\n parsedBody.namespaceName = ns;\n mutated = true;\n }\n } catch {\n // Config not available — skip\n }\n }\n }\n\n const result = await apiCall({\n profile: args.profile,\n endpoint: args.endpoint,\n body: mutated && parsedBody ? JSON.stringify(parsedBody) : args.body,\n });\n\n logger.out(JSON.stringify(result.data, null, 2));\n },\n});\n","import { ExitPromptError } from \"@inquirer/core\";\nimport { confirm, input, password } from \"@inquirer/prompts\";\nimport { isCI } from \"std-env\";\nimport { CIPromptError } from \"./logger\";\n\n/**\n * Wraps a prompt function with CI guard and cancellation handling.\n * @param fn - A prompt function from `@inquirer/prompts`\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): (...args: Args) => Promise<R> {\n return async (...args: Args): Promise<R> => {\n if (isCI) throw new CIPromptError();\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(confirm),\n text: withGuard(input),\n password: withGuard(password),\n};\n","import { z } from \"zod\";\n\nconst cacheOutputFileSchema = z.object({\n outputPath: z.string(),\n contentHash: z.string(),\n});\n\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\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 { 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(), `${cacheKey.replaceAll(\":\", \"_\")}.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 // Use in-memory manifest to preserve entries added during the session\n const manifest = store.getCurrentManifest() ?? {\n version: 1 as const,\n sdkVersion: options.sdkVersion,\n lockfileHash: options.lockfileHash,\n entries: {},\n };\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","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { logger } from \"@/cli/shared/logger\";\nimport ml from \"@/utils/multiline\";\nimport type { AppConfig } from \"@/types/app-config\";\n\nexport interface AttributeMapConfig {\n [key: string]: string;\n}\n\nexport type AttributeListConfig = readonly string[];\n\ninterface ExtractedAttributes {\n attributeMap?: AttributeMapConfig;\n attributeList?: AttributeListConfig;\n env?: Record<string, string | number | boolean>;\n machineUserNames?: string[];\n idpNames?: string[];\n}\n\ntype AttributeFieldLike = {\n type?: string;\n metadata?: {\n array?: boolean;\n allowedValues?: Array<{ value: string }>;\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 attribute map/list and env values\n * @internal\n */\nexport function extractAttributesFromConfig(config: AppConfig): ExtractedAttributes {\n return collectAttributesFromConfig(config);\n}\n\n/**\n * Generate the contents of the user-defined type definition file.\n * @param attributeMap - Attribute map configuration\n * @param attributeList - Attribute list configuration\n * @param env - Environment configuration\n * @param machineUserNames - Registered machine user names (used to narrow `authInvoker` strings)\n * @param idpNames - Registered IdP names (used to narrow `idpUser*Trigger({ idp })` strings)\n * @returns Generated type definition source\n */\nexport function generateTypeDefinition(\n attributeMap: AttributeMapConfig | undefined,\n attributeList: AttributeListConfig | undefined,\n env?: Record<string, string | number | boolean>,\n machineUserNames?: readonly string[],\n idpNames?: readonly string[],\n): string {\n // Generate AttributeMap interface\n // attributeMap values are type string representations (e.g., \"string\", \"boolean\", \"string[]\")\n const mapFields = attributeMap\n ? Object.entries(attributeMap)\n .map(([key, value]) => ` ${key}: ${value};`)\n .join(\"\\n\")\n : \"\";\n\n const mapBody =\n !attributeMap || Object.keys(attributeMap).length === 0\n ? \"{}\"\n : `{\n${mapFields}\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 const envFields = env\n ? Object.entries(env)\n .map(([key, value]) => {\n const valueType = typeof value === \"string\" ? `\"${value}\"` : String(value);\n return ` ${key}: ${valueType};`;\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 // Quote keys only when they aren't valid TypeScript identifiers — matches\n // the formatter (oxfmt) output so subsequent format passes are no-ops.\n const isValidIdentifier = (s: string): boolean => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(s);\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 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-sdk deploy' or 'tailor-sdk generate'\n\ndeclare module \"@tailor-platform/sdk\" {\n interface AttributeMap ${mapBody}\n interface AttributeList ${listBody}\n interface Env ${envBody}\n interface MachineUserNameRegistry ${machineUserBody}\n interface IdpNameRegistry ${idpNameBody}\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 const auth = config.auth;\n if (!auth || typeof auth !== \"object\") {\n return idpNames ? { idpNames } : {};\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 const inferAttributeType = (field?: AttributeFieldLike): string => {\n const type = field?.type;\n const metadata = field?.metadata;\n\n // Default to string if no metadata\n if (!metadata) {\n return \"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 += \"[]\";\n }\n\n return typeStr;\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 attributes = userProfile?.attributes;\n const fields = userProfile?.type?.fields;\n const attributeList = userProfile?.attributeList;\n\n // Convert attributes to AttributeMapConfig by inferring types from field metadata\n const attributeMap: AttributeMapConfig | undefined = attributes\n ? Object.keys(attributes).reduce((acc, key) => {\n acc[key] = inferAttributeType(fields?.[key]);\n return acc;\n }, {} as AttributeMapConfig)\n : undefined;\n\n return {\n attributeMap,\n attributeList,\n machineUserNames,\n idpNames,\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 };\n }\n\n const attributeMap = Object.entries(machineUserAttributes).reduce((acc, [key, field]) => {\n acc[key] = inferAttributeType(field);\n return acc;\n }, {} as AttributeMapConfig);\n\n return {\n attributeMap,\n machineUserNames,\n idpNames,\n };\n }\n\n return { machineUserNames, idpNames };\n}\n\n/**\n * Resolve the output path for the generated type definition file.\n *\n * When the `TAILOR_PLATFORM_SDK_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_PLATFORM_SDK_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 */\n config: AppConfig;\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 { attributeMap, attributeList, machineUserNames, idpNames } =\n extractAttributesFromConfig(config);\n if (!attributeMap && !attributeList) {\n logger.info(\"No attributes found in configuration\", { mode: \"plain\" });\n }\n\n if (attributeMap) {\n logger.debug(`Extracted AttributeMap: ${JSON.stringify(attributeMap)}`);\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\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 attributeMap,\n attributeList,\n env,\n machineUserNames,\n idpNames,\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 type { IdProvider as IdProviderConfig, OAuth2Client } from \"./auth.generated\";\nimport type { Executor } from \"./executor.generated\";\nimport type { DependencyKind } from \"./generator-config\";\nimport type { PluginAttachment } from \"./plugin-attachment\";\nimport type { Resolver } from \"./resolver.generated\";\nimport type { TailorDBType, TypeSourceInfoEntry } from \"./tailordb\";\n\n/**\n * A single generated file to write to disk.\n */\nexport interface GeneratedFile {\n path: string;\n content: string;\n skipIfExists?: boolean;\n executable?: boolean;\n}\n\n/**\n * Result returned by generation-time hooks.\n */\nexport interface GeneratorResult {\n files: GeneratedFile[];\n errors?: string[];\n}\n\n/**\n * Auth configuration available to generation-time hooks.\n */\nexport interface GeneratorAuthInput {\n name: string;\n userProfile?: {\n typeName: string;\n namespace: string;\n usernameField: string;\n };\n machineUsers?: Record<string, { attributes?: Record<string, unknown> }>;\n oauth2Clients?: Record<string, OAuth2Client>;\n idProvider?: IdProviderConfig;\n}\n\n/**\n * Namespace-level TailorDB data available to generation-time hooks.\n */\nexport interface TailorDBNamespaceData {\n /** Namespace name */\n namespace: string;\n /** All TailorDB types in this namespace, keyed by type name */\n types: Record<string, TailorDBType>;\n /** Source info for each type (file path, export name, plugin info) */\n sourceInfo: ReadonlyMap<string, TypeSourceInfoEntry>;\n /** Plugin attachments configured on each type via .plugin() method */\n pluginAttachments: ReadonlyMap<string, readonly PluginAttachment[]>;\n}\n\n/**\n * Namespace-level resolver data available to generation-time hooks.\n */\nexport interface ResolverNamespaceData {\n /** Namespace name */\n namespace: string;\n /** All resolvers in this namespace, keyed by resolver name */\n resolvers: Record<string, Resolver>;\n}\n\n/**\n * Context passed to plugin's onTailorDBReady hook.\n * @template PluginConfig - Plugin-level configuration type\n */\nexport interface TailorDBReadyContext<PluginConfig = unknown> {\n /** All TailorDB namespaces with their types and metadata */\n tailordb: TailorDBNamespaceData[];\n /** Auth configuration */\n auth?: GeneratorAuthInput;\n /** Base directory for generated files */\n baseDir: string;\n /** Path to tailor.config.ts */\n configPath: string;\n /** Plugin-level configuration passed via definePlugins() */\n pluginConfig: PluginConfig;\n}\n\n/**\n * Context passed to plugin's onResolverReady hook.\n * @template PluginConfig - Plugin-level configuration type\n */\nexport interface ResolverReadyContext<PluginConfig = unknown> {\n /** All TailorDB namespaces with their types and metadata */\n tailordb: TailorDBNamespaceData[];\n /** All resolver namespaces with their resolvers */\n resolvers: ResolverNamespaceData[];\n /** Auth configuration */\n auth?: GeneratorAuthInput;\n /** Base directory for generated files */\n baseDir: string;\n /** Path to tailor.config.ts */\n configPath: string;\n /** Plugin-level configuration passed via definePlugins() */\n pluginConfig: PluginConfig;\n}\n\n/**\n * Context passed to plugin's onExecutorReady hook.\n * @template PluginConfig - Plugin-level configuration type\n */\nexport interface ExecutorReadyContext<PluginConfig = unknown> {\n /** All TailorDB namespaces with their types and metadata */\n tailordb: TailorDBNamespaceData[];\n /** All resolver namespaces with their resolvers */\n resolvers: ResolverNamespaceData[];\n /** All executors, keyed by executor name */\n executors: Record<string, Executor>;\n /** Auth configuration */\n auth?: GeneratorAuthInput;\n /** Base directory for generated files */\n baseDir: string;\n /** Path to tailor.config.ts */\n configPath: string;\n /** Plugin-level configuration passed via definePlugins() */\n pluginConfig: PluginConfig;\n}\n\n/**\n * Derives generation-time dependency set from hook presence on a plugin.\n * @param plugin - The plugin object to inspect.\n * @param plugin.onTailorDBReady - Hook for TailorDB readiness.\n * @param plugin.onResolverReady - Hook for resolver readiness.\n * @param plugin.onExecutorReady - Hook for executor readiness.\n * @returns Set of dependency kinds required by the plugin.\n */\nexport function getPluginGenerationDependencies(plugin: {\n onTailorDBReady?: unknown;\n onResolverReady?: unknown;\n onExecutorReady?: unknown;\n}): Set<DependencyKind> {\n const deps = new Set<DependencyKind>();\n if (plugin.onTailorDBReady) {\n deps.add(\"tailordb\");\n }\n if (plugin.onResolverReady) {\n deps.add(\"resolver\");\n }\n if (plugin.onExecutorReady) {\n deps.add(\"executor\");\n }\n return deps;\n}\n\n/**\n * Checks if a plugin has any generation-time hooks.\n * @param plugin - The plugin object to inspect.\n * @param plugin.onTailorDBReady - Hook for TailorDB readiness.\n * @param plugin.onResolverReady - Hook for resolver readiness.\n * @param plugin.onExecutorReady - Hook for executor readiness.\n * @returns True if the plugin has at least one generation hook.\n */\nexport function hasGenerationHooks(plugin: {\n onTailorDBReady?: unknown;\n onResolverReady?: unknown;\n onExecutorReady?: unknown;\n}): boolean {\n return !!(plugin.onTailorDBReady || plugin.onResolverReady || plugin.onExecutorReady);\n}\n","import { db, type TailorAnyDBType } from \"@/configure/services/tailordb\";\nimport { hasGenerationHooks, getPluginGenerationDependencies } from \"@/types/plugin-generation\";\nimport type {\n TailorTypePermission,\n TailorTypeGqlPermission,\n} from \"@/configure/services/tailordb/permission\";\nimport type { DependencyKind } from \"@/parser/generator-config/schema\";\nimport type {\n Plugin,\n PluginAttachment,\n PluginGeneratedExecutor,\n PluginGeneratedType,\n PluginNamespaceProcessContext,\n PluginOutput,\n TypePluginOutput,\n} from \"@/types/plugin\";\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 = plugin.importPath!;\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 = plugin.importPath!;\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.type()` 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.type(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-sdk/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 (metadata.files && 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 && 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 { logger, 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.print()` (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 print: () => void;\n};\n\nexport interface PlanSummary {\n create: number;\n update: number;\n delete: number;\n replace: number;\n unchanged: 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 print() 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 print: () => {\n if (isEmpty()) {\n return;\n }\n logger.log(styles.bold(`${title}:`));\n const printItem = (symbol: string, item: HasName) => {\n logger.log(` ${symbol} ${item.name}`);\n for (const detail of item.details ?? []) {\n logger.log(` ${detail}`);\n }\n };\n creates.forEach((item) => printItem(symbols.create, item));\n deletes.forEach((item) => printItem(symbols.delete, item));\n updates.forEach((item) => printItem(symbols.update, item));\n replaces.forEach((item) => printItem(symbols.replace, item));\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\" | \"unchanged\"\n >\n >,\n): PlanSummary {\n const summary: PlanSummary = {\n create: 0,\n update: 0,\n delete: 0,\n replace: 0,\n unchanged: 0,\n };\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 summary.unchanged += changeSet.unchanged.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","/**\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 { readPackageJson } from \"@/cli/shared/package-json\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/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 | \"staticwebsite\"\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\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\nexport interface BuildMetaRequestParams {\n trn: string;\n appName: string;\n appId?: string;\n existingLabels?: Record<string, string>;\n}\n\n/**\n * Build metadata request with SDK labels.\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 * @param params.existingLabels - Existing labels to preserve (optional)\n * @returns Metadata request\n */\nexport async function buildMetaRequest(\n params: BuildMetaRequestParams,\n): Promise<MessageInitShape<typeof SetMetadataRequestSchema>> {\n const { trn, appName, appId, existingLabels } = 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 ...existingLabels,\n [sdkNameLabelKey]: appName,\n [sdkVersionLabelKey]: sdkVersion,\n ...(appId ? { [sdkAppIdLabelKey]: toAppIdLabelValue(appId) } : {}),\n },\n };\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n type Application as ProtoApplication,\n Subgraph_ServiceType,\n type SubgraphSchema,\n} from \"@tailor-proto/tailor/v1/application_resource_pb\";\nimport { fetchAll, resolveStaticWebsiteUrls, type OperatorClient } from \"@/cli/shared/client\";\nimport { symbols } from \"@/cli/shared/logger\";\nimport { HTTP_METHODS } from \"@/parser/service/http-adapter\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport { buildMetaRequest, hasMatchingSdkVersion, isOwnedByApp, resourceTrn } from \"./label\";\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 {\n DeleteApplicationRequestSchema,\n CreateApplicationRequestSchema,\n UpdateApplicationRequestSchema,\n} from \"@tailor-proto/tailor/v1/application_pb\";\nimport type { HttpAdapterSchema } from \"@tailor-proto/tailor/v1/http_adapter_resource_pb\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_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 create.request.workspaceId!,\n create.request.cors,\n \"CORS\",\n );\n await client.createApplication(create.request);\n await client.setMetadata(create.metaRequest);\n }),\n ...updates.map(async (update) => {\n update.request.cors = await resolveStaticWebsiteUrls(\n client,\n update.request.workspaceId!,\n update.request.cors,\n \"CORS\",\n );\n await client.updateApplication(update.request);\n await client.setMetadata(update.metaRequest);\n }),\n ]);\n } else if (phase === \"delete\") {\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: MessageInitShape<typeof SetMetadataRequestSchema>;\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: MessageInitShape<typeof SetMetadataRequestSchema>;\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: subgraph.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 changeSet = createChangeSet<\n CreateApplication,\n UpdateApplication,\n DeleteApplication,\n never,\n UpdateApplication\n >(\"Applications\");\n\n const existingApplications = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { applications, nextPageToken } = await client.listApplications({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [applications, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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 isOwnedByApp(labels, application.name, application.id) ? app.name : 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 changeSet;\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 changeSet;\n }\n\n let authNamespace: string | undefined;\n let authIdpConfigName: string | undefined;\n if (application.authService && application.authService.config) {\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 // Retrieve idpConfig from remote when auth references an external namespace\n authNamespace = application.config.auth.name;\n const idpConfigs = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { idpConfigs, nextPageToken } = await client.listAuthIDPConfigs({\n workspaceId,\n namespaceName: authNamespace!,\n pageToken,\n pageSize: maxPageSize,\n });\n return [idpConfigs, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n if (idpConfigs.length > 0) {\n authIdpConfigName = idpConfigs[0].name;\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 expectedLocalWebsites = new Set(\n application.staticWebsiteServices.map((website) => website.name),\n );\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 labels = await fetchAppLabels(client, workspaceId, application.name);\n const update: UpdateApplication = {\n name: application.name,\n request,\n metaRequest,\n };\n if (\n isOwnedByApp(labels, application.name, application.id) &&\n hasMatchingSdkVersion(labels, 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 changeSet;\n}\n\nasync function fetchAppLabels(\n client: OperatorClient,\n workspaceId: string,\n appName: string,\n): Promise<Record<string, string> | undefined> {\n try {\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"application\", appName),\n });\n return metadata?.labels;\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return undefined;\n }\n throw error;\n }\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 } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport * as path from \"pathe\";\nimport { z } from \"zod\";\nimport { getDistDir } from \"@/cli/shared/dist-dir\";\n\nconst SecretsStateSchema = z.object({\n vaults: z.record(z.string(), z.record(z.string(), z.string())),\n connections: z.record(z.string(), z.string()).optional(),\n});\n\nexport type SecretsState = z.infer<typeof SecretsStateSchema>;\n\n/**\n * Get the file path for the secrets state JSON.\n * @returns Absolute path to secrets-state.json\n */\nexport function getSecretsStatePath(): string {\n return path.join(getDistDir(), \"secrets-state.json\");\n}\n\n/**\n * Load secrets hash state from disk.\n * @returns Persisted state, or empty state if file is missing or corrupted\n */\nexport function loadSecretsState(): SecretsState {\n const filePath = getSecretsStatePath();\n if (!existsSync(filePath)) {\n return { vaults: {} };\n }\n try {\n const raw = readFileSync(filePath, \"utf-8\");\n return SecretsStateSchema.parse(JSON.parse(raw));\n } catch {\n return { vaults: {} };\n }\n}\n\n/**\n * Save secrets hash state to disk.\n * @param state - The secrets state to persist\n */\nexport function saveSecretsState(state: SecretsState): void {\n const filePath = getSecretsStatePath();\n const dir = path.dirname(filePath);\n mkdirSync(dir, { recursive: true });\n writeFileSync(filePath, JSON.stringify(state, null, 2), \"utf-8\");\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","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { AuthConnection_Type } from \"@tailor-proto/tailor/v1/auth_resource_pb\";\nimport { type AuthService } from \"@/cli/services/auth/service\";\nimport { fetchAll, type OperatorClient } from \"@/cli/shared/client\";\nimport { createChangeSet } from \"./change-set\";\nimport {\n buildMetaRequest,\n isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"./label\";\nimport { hashValue, loadSecretsState, saveSecretsState } from \"./secrets-state\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase } from \"./phase\";\nimport type { AuthConnectionConfig } from \"@/types/auth-connection.generated\";\nimport type {\n CreateAuthConnectionRequestSchema,\n DeleteAuthConnectionRequestSchema,\n} from \"@tailor-proto/tailor/v1/auth_pb\";\nimport type { AuthConnection } from \"@tailor-proto/tailor/v1/auth_resource_pb\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\n\ntype CreateConnection = {\n name: string;\n request: MessageInitShape<typeof CreateAuthConnectionRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateConnection = {\n name: string;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype ReplaceConnection = {\n name: string;\n deleteRequest: MessageInitShape<typeof DeleteAuthConnectionRequestSchema>;\n createRequest: MessageInitShape<typeof CreateAuthConnectionRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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 hashConnectionConfig(config: AuthConnectionConfig): string {\n const serialized = JSON.stringify({\n type: config.type,\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 return hashValue(serialized);\n}\n\nfunction hasNonSecretFieldChanged(\n existing: AuthConnection,\n desired: AuthConnectionConfig,\n): boolean {\n if (existing.config.case !== \"oauth2\") {\n return true;\n }\n const oauth2 = existing.config.value;\n return (\n oauth2.providerUrl !== desired.providerUrl ||\n oauth2.issuerUrl !== desired.issuerUrl ||\n oauth2.clientId !== desired.clientId ||\n oauth2.authUrl !== (desired.authUrl ?? \"\") ||\n oauth2.tokenUrl !== (desired.tokenUrl ?? \"\")\n );\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 changeSet = createChangeSet<\n CreateConnection,\n UpdateConnection,\n DeleteConnection,\n ReplaceConnection\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 if (auth.connections) {\n for (const [name, config] of Object.entries(auth.connections)) {\n desiredConnections[name] = config;\n }\n }\n }\n\n const existingList = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { connections, nextPageToken } = await client.listAuthConnections({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [connections, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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();\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 = isOwnedByApp(existing.allLabels, appName, appId);\n if (!owned) {\n if (existing.label) {\n conflicts.push({\n resourceType: \"Auth connection\",\n resourceName: name,\n currentOwner: existing.label,\n });\n } else {\n unmanaged.push({\n resourceType: \"Auth connection\",\n resourceName: name,\n });\n }\n }\n\n const currentHash = hashConnectionConfig(config);\n const storedHash = state.connections?.[name];\n const nonSecretChanged = hasNonSecretFieldChanged(existing.resource, config);\n const secretChanged = currentHash !== storedHash;\n\n if (nonSecretChanged || secretChanged) {\n changeSet.replaces.push({\n name,\n deleteRequest: { workspaceId, connectionName: name },\n createRequest: buildConnectionRequest(workspaceId, name, config),\n metaRequest,\n });\n } else if (!existing.label) {\n // The connection itself is unchanged, but it carries no SDK label\n // (e.g. it was just adopted via the unmanaged-resource confirmation,\n // or created by an older SDK that predates ownership labels). Write\n // the label now so the next deploy recognizes it as owned.\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 = isOwnedByApp(entry.allLabels, appName, appId);\n if (entry.label && !owned) {\n resourceOwners.add(entry.label);\n continue;\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 };\n}\n\nfunction extractOAuth2Config(\n connection: MessageInitShape<typeof CreateAuthConnectionRequestSchema>[\"connection\"],\n): AuthConnectionConfig | undefined {\n if (!connection) return undefined;\n const config = connection.config;\n if (!config || config.case !== \"oauth2\" || !config.value) return undefined;\n const v = config.value;\n return {\n type: \"oauth2\",\n providerUrl: (v.providerUrl as string) ?? \"\",\n issuerUrl: (v.issuerUrl as string) ?? \"\",\n clientId: (v.clientId as string) ?? \"\",\n clientSecret: (v.clientSecret as string) ?? \"\",\n authUrl: (v.authUrl as string) || undefined,\n tokenUrl: (v.tokenUrl as string) || undefined,\n };\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: Awaited<ReturnType<typeof planAuthConnections>>,\n phase: Exclude<ApplyPhase, \"delete-services\">,\n) {\n const { changeSet } = result;\n\n if (phase === \"create-update\") {\n await Promise.all(\n changeSet.creates.map(async (create) => {\n await client.createAuthConnection(create.request);\n await client.setMetadata(create.metaRequest);\n }),\n );\n\n for (const replace of changeSet.replaces) {\n await client.deleteAuthConnection(replace.deleteRequest);\n await client.createAuthConnection(replace.createRequest);\n await client.setMetadata(replace.metaRequest);\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 client.setMetadata(update.metaRequest);\n }),\n );\n\n const state = loadSecretsState();\n if (!state.connections) {\n state.connections = {};\n }\n for (const create of changeSet.creates) {\n const oauth2 = extractOAuth2Config(create.request.connection);\n if (oauth2) {\n state.connections[create.name] = hashConnectionConfig(oauth2);\n }\n }\n for (const replace of changeSet.replaces) {\n const oauth2 = extractOAuth2Config(replace.createRequest.connection);\n if (oauth2) {\n state.connections[replace.name] = hashConnectionConfig(oauth2);\n }\n }\n saveSecretsState(state);\n } else if (phase === \"delete-resources\" || phase === \"delete\") {\n await Promise.all(\n changeSet.deletes.map(async (del) => {\n await client.deleteAuthConnection(del.request);\n }),\n );\n\n if (changeSet.deletes.length > 0) {\n const state = loadSecretsState();\n if (state.connections) {\n for (const del of changeSet.deletes) {\n delete state.connections[del.name];\n }\n saveSecretsState(state);\n }\n }\n }\n}\n","import * as crypto from \"node:crypto\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { fetchAll, type OperatorClient } from \"@/cli/shared/client\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { createChangeSet, type ChangeSet, type HasName } from \"./change-set\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"./label\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { BundledScripts, FunctionEntry } from \"./function-registry-types\";\nimport type { ApplyPhase } from \"./phase\";\nimport type { Application } from \"@/cli/services/application\";\nimport type { CollectedJob } from \"@/cli/services/workflow/service\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type {\n CreateFunctionRegistryRequestSchema,\n UpdateFunctionRegistryRequestSchema,\n} from \"@tailor-proto/tailor/v1/function_registry_pb\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateFunction = {\n name: string;\n entry: FunctionEntry;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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(resolver.name);\n if (!content) {\n logger.warn(`Bundled code not found for resolver: ${resolver.name}`);\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 // Fetch existing function registry entries\n const existingFunctions = await fetchAll(async (pageToken, maxPageSize) => {\n try {\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 } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n\n // Build map of existing functions with their labels\n const existingMap: WithLabel<ExistingFunction> = {};\n await Promise.all(\n existingFunctions.map(async (func) => {\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"function_registry\", func.name),\n });\n existingMap[func.name] = {\n resource: func,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\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 = isOwnedByApp(existing.allLabels, appName, appId);\n if (!owned) {\n if (!existing.label) {\n unmanaged.push({\n resourceType: \"Function registry\",\n resourceName: entry.name,\n });\n } else {\n conflicts.push({\n resourceType: \"Function registry\",\n resourceName: entry.name,\n currentOwner: existing.label,\n });\n }\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 label = existing.label;\n const owned = isOwnedByApp(existing.allLabels, appName, appId);\n if (label && !owned) {\n resourceOwners.add(label);\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 // Upload new functions\n for (const create of changeSet.creates) {\n await uploadFunctionScript(client, workspaceId, create.entry, true);\n await client.setMetadata(create.metaRequest);\n }\n\n // Update existing functions (server deduplicates content by hash)\n for (const update of changeSet.updates) {\n await uploadFunctionScript(client, workspaceId, update.entry, false);\n await client.setMetadata(update.metaRequest);\n }\n } else if (phase === \"delete\") {\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 { logger, styles, symbols } from \"@/cli/shared/logger\";\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 * Print a titled section of grouped display 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 print (should NOT include service entries)\n * @param serviceActions - Optional service-level actions to merge into namespace headers\n */\nexport function printGroupedDisplaySection(\n title: string,\n entries: ReadonlyArray<GroupedDisplayEntry>,\n serviceActions?: ReadonlyArray<NamespaceAction>,\n) {\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 logger.log(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 byNamespace.get(ns)!.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 = byNamespace.get(ns)!;\n if (ns) {\n const svcAction = serviceMap.get(ns);\n const prefix = svcAction ? `${ACTION_SYMBOLS[svcAction]} ` : \"\";\n logger.log(` ${prefix}${styles.bold(`${ns}:`)}`);\n printedServices.add(ns);\n for (const entry of group) {\n logger.log(` ${formatGroupedDisplayLine(entry)}`);\n }\n } else {\n for (const entry of group) {\n logger.log(` ${formatGroupedDisplayLine(entry)}`);\n }\n }\n }\n\n // Print services without child entries as flat entries\n for (const [name, action] of serviceMap) {\n if (!printedServices.has(name)) {\n logger.log(` ${ACTION_SYMBOLS[action]} ${name}`);\n }\n }\n}\n","import type {\n StandardIdPPermission,\n StandardIdPActionPermission,\n StandardIdPPermissionCondition,\n IdPPermissionOperand,\n IdPUserField,\n} from \"@/types/idp\";\nimport type { IdPPermission as RawIdPPermission } from \"@/types/idp.generated\";\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 } 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 { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n type CreateIdPClientRequestSchema,\n type CreateIdPServiceRequestSchema,\n type DeleteIdPClientRequestSchema,\n type DeleteIdPServiceRequestSchema,\n type UpdateIdPServiceRequestSchema,\n} from \"@tailor-proto/tailor/v1/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-proto/tailor/v1/idp_resource_pb\";\nimport { fetchAll, type OperatorClient } from \"@/cli/shared/client\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { findOmittedPermitRules, parseIdPPermission } from \"@/parser/service/idp/permission\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"./label\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase, PlanContext } from \"@/cli/commands/deploy/types\";\nimport type {\n IdPPermissionOperand,\n StandardIdPActionPermission,\n StandardIdPPermission,\n StandardIdPPermissionCondition,\n} from \"@/types/idp\";\nimport type { IdP, IdPLang as IdPLangInput } from \"@/types/idp.generated\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\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\n await Promise.all([\n ...changeSet.service.creates.map(async (create) => {\n await client.createIdPService(create.request);\n await client.setMetadata(create.metaRequest);\n }),\n ...changeSet.service.updates.map(async (update) => {\n await client.updateIdPService(update.request);\n await client.setMetadata(update.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 create.request.namespaceName!,\n create.request.client?.name || \"\",\n );\n const secretName = idpClientSecretName(\n create.request.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 try {\n await client.getSecretManagerVault({\n workspaceId: update.workspaceId,\n secretmanagerVaultName: vaultName,\n });\n return;\n } catch (error) {\n if (!(error instanceof ConnectError && error.code === Code.NotFound)) {\n throw error;\n }\n }\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 if (phase === \"delete-services\") {\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 } = context;\n const idps = forRemoval ? [] : application.idpServices;\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 );\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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateService = {\n name: string;\n request: MessageInitShape<typeof UpdateIdPServiceRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype DeleteService = {\n name: string;\n request: MessageInitShape<typeof DeleteIdPServiceRequestSchema>;\n};\n\ntype ComparableIdPService = {\n authorization: string | undefined;\n lang: IdPLang;\n userAuthPolicy: Record<string, unknown> | undefined;\n publishUserEvents: 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 passwordMinLength: policy?.passwordMinLength ?? 0,\n passwordMaxLength: policy?.passwordMaxLength ?? 0,\n allowedEmailDomains: (policy?.allowedEmailDomains ?? []).toSorted(),\n allowGoogleOauth: policy?.allowGoogleOauth ?? false,\n disablePasswordAuth: policy?.disablePasswordAuth ?? false,\n allowMicrosoftOauth: policy?.allowMicrosoftOauth ?? false,\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 };\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 | \"publishUserEvents\"\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 publishUserEvents: input.publishUserEvents,\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 ) {\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 };\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 publishUserEvents: 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) {\n const changeSet = createChangeSet<CreateService, UpdateService, DeleteService>(\"IdP services\");\n const conflicts: OwnerConflict[] = [];\n const unmanaged: UnmanagedResource[] = [];\n const resourceOwners = new Set<string>();\n\n const withoutLabel = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { idpServices, nextPageToken } = await client.listIdPServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [idpServices, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n const existingServices: WithLabel<(typeof withoutLabel)[number]> = {};\n await Promise.all(\n withoutLabel.map(async (resource) => {\n if (!resource.namespace?.name) {\n return;\n }\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"idp\", resource.namespace.name),\n });\n existingServices[resource.namespace.name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\n );\n\n for (const idp of idps) {\n const namespaceName = idp.name;\n const existing = existingServices[namespaceName];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"idp\", namespaceName),\n appName,\n appId,\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 isIdpUserTriggerTarget = idpUserTriggerTargets.has(namespaceName);\n if (isIdpUserTriggerTarget && idp.publishUserEvents === false) {\n throw new Error(\n `IdP service \"${namespaceName}\" has \"publishUserEvents: false\", but executors with idpUser triggers subscribe to it. ` +\n `Either remove \"publishUserEvents: false\" or remove the matching executor triggers.`,\n );\n }\n const publishUserEvents = idp.publishUserEvents ?? isIdpUserTriggerTarget;\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 desired = normalizeComparableIdPService({\n authorization,\n lang,\n userAuthPolicy: normalizeComparableUserAuthPolicy(userAuthPolicy),\n publishUserEvents,\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,\n disableGqlOperations: convertGqlOperationsToDisable(idp.gqlOperations),\n emailConfig,\n permission: protoPermission,\n };\n\n if (existing) {\n const owned = isOwnedByApp(existing.allLabels, appName, appId);\n if (!owned) {\n if (!existing.label) {\n unmanaged.push({\n resourceType: \"IdP service\",\n resourceName: idp.name,\n });\n } else {\n conflicts.push({\n resourceType: \"IdP service\",\n resourceName: idp.name,\n currentOwner: existing.label,\n });\n }\n }\n if (\n owned &&\n hasMatchingSdkVersion(existing.allLabels, metaRequest.labels) &&\n areIdPServicesEqual(existing.resource, desired)\n ) {\n changeSet.unchanged.push({ name: namespaceName });\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 label = entry?.label;\n const owned = isOwnedByApp(entry?.allLabels, appName, appId);\n if (label && !owned) {\n resourceOwners.add(label);\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 fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { clients, nextPageToken } = await client.listIdPClients({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [clients, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n };\n\n const clientsByIdp = await Promise.all(idps.map((idp) => fetchClients(idp.name)));\n for (let i = 0; i < idps.length; i++) {\n const idp = idps[i];\n const namespaceName = idp.name;\n const existingClients = clientsByIdp[i];\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 (let i = 0; i < deletedServices.length; i++) {\n const namespaceName = deletedServices[i];\n deletedClientsByService[i].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 };\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 };\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 { Code, ConnectError } from \"@connectrpc/connect\";\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-proto/tailor/v1/auth_resource_pb\";\nimport { type AuthService } from \"@/cli/services/auth/service\";\nimport { fetchAll, resolveStaticWebsiteUrls, type OperatorClient } from \"@/cli/shared/client\";\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 isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"./label\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase, PlanContext } from \"@/cli/commands/deploy/types\";\nimport type { AuthAttributeValue } from \"@/types/auth\";\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 {\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-proto/tailor/v1/auth_pb\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\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: 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.createAuthService(create.request);\n await client.setMetadata(create.metaRequest);\n }),\n ...changeSet.service.updates.map(async (update) => {\n await client.updateAuthService(update.request);\n await client.setMetadata(update.metaRequest);\n }),\n ]);\n\n // Auth Connections\n if (changeSet.connection) {\n await applyAuthConnections(\n client,\n { changeSet: changeSet.connection } as Awaited<ReturnType<typeof planAuthConnections>>,\n \"create-update\",\n );\n }\n\n // IdPConfigs\n await Promise.all([\n ...changeSet.idpConfig.creates.map(async (create) => {\n if (create.idpConfig.kind === \"BuiltInIdP\") {\n create.request.idpConfig!.config = await protoBuiltinIdPConfig(\n client,\n create.request.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 update.request.idpConfig!.config = await protoBuiltinIdPConfig(\n client,\n update.request.workspaceId!,\n update.idpConfig,\n );\n }\n return client.updateAuthIDPConfig(update.request);\n }),\n ]);\n\n // UserProfileConfigs\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 // TenantConfigs\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 // MachineUsers\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 // AuthHooks (after machine users, since hooks reference invokers)\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 // OAuth2Clients\n await Promise.all([\n ...changeSet.oauth2Client.creates.map(async (create) => {\n create.request.oauth2Client!.redirectUris = await resolveStaticWebsiteUrls(\n client,\n create.request.workspaceId!,\n create.request.oauth2Client!.redirectUris,\n \"OAuth2 redirect URIs\",\n );\n return client.createAuthOAuth2Client(create.request);\n }),\n ...changeSet.oauth2Client.updates.map(async (update) => {\n update.request.oauth2Client!.redirectUris = await resolveStaticWebsiteUrls(\n client,\n update.request.workspaceId!,\n update.request.oauth2Client!.redirectUris,\n \"OAuth2 redirect URIs\",\n );\n return client.updateAuthOAuth2Client(update.request);\n }),\n ]);\n\n // OAuth2Clients replaces (client type changed): delete then create sequentially\n for (const replace of changeSet.oauth2Client.replaces) {\n await client.deleteAuthOAuth2Client(replace.deleteRequest);\n replace.createRequest.oauth2Client!.redirectUris = await resolveStaticWebsiteUrls(\n client,\n replace.createRequest.workspaceId!,\n replace.createRequest.oauth2Client!.redirectUris,\n \"OAuth2 redirect URIs\",\n );\n await client.createAuthOAuth2Client(replace.createRequest);\n }\n\n // SCIMConfigs\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 // SCIMResources\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 } else 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 Promise.all(\n changeSet.userProfileConfig.deletes.map((del) => client.deleteUserProfileConfig(del.request)),\n );\n\n // IdPConfigs\n await Promise.all(\n changeSet.idpConfig.deletes.map((del) => client.deleteAuthIDPConfig(del.request)),\n );\n\n // Auth Connections\n if (changeSet.connection) {\n await applyAuthConnections(\n client,\n { changeSet: changeSet.connection } as Awaited<ReturnType<typeof planAuthConnections>>,\n \"delete-resources\",\n );\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 = new Set(\n application.staticWebsiteServices.map((website) => website.name),\n );\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\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 };\n}\n\ntype CreateService = {\n name: string;\n request: MessageInitShape<typeof CreateAuthServiceRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateService = {\n name: string;\n request: MessageInitShape<typeof UpdateAuthServiceRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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 withoutLabel = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { authServices, nextPageToken } = await client.listAuthServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [authServices, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n const existingServices: WithLabel<(typeof withoutLabel)[number]> = {};\n await Promise.all(\n withoutLabel.map(async (resource) => {\n if (!resource.namespace?.name) {\n return;\n }\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"auth\", resource.namespace.name),\n });\n existingServices[resource.namespace.name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\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 = isOwnedByApp(existing.allLabels, appName, appId);\n if (!owned) {\n if (!existing.label) {\n unmanaged.push({\n resourceType: \"Auth service\",\n resourceName: config.name,\n });\n } else {\n conflicts.push({\n resourceType: \"Auth service\",\n resourceName: config.name,\n currentOwner: existing.label,\n });\n }\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 label = entry?.label;\n const owned = isOwnedByApp(entry?.allLabels, appName, appId);\n if (label && !owned) {\n resourceOwners.add(label);\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 fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { idpConfigs, nextPageToken } = await client.listAuthIDPConfigs({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [idpConfigs, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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 : { rawMetadata: idpConfig.rawMetadata! }),\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 let idpService;\n try {\n idpService = await client.getIdPService({\n workspaceId,\n namespaceName: builtinIdPConfig.namespace,\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return undefined;\n }\n throw error;\n }\n let idpClient;\n try {\n idpClient = await client.getIdPClient({\n workspaceId,\n namespaceName: builtinIdPConfig.namespace,\n name: builtinIdPConfig.clientName,\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return undefined;\n }\n throw error;\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 try {\n const { userProfileProviderConfig } = await client.getUserProfileConfig({\n workspaceId,\n namespaceName: config.name,\n });\n const userProfileForUpdate = auth.userProfile;\n if (userProfileForUpdate) {\n const desired = protoUserProfileConfig(userProfileForUpdate);\n if (\n !forceApplyAll &&\n areUserProfileConfigsEqual(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 } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n const userProfileForCreate = auth.userProfile;\n if (userProfileForCreate) {\n changeSet.creates.push({\n name,\n request: {\n workspaceId,\n namespaceName: config.name,\n userProfileProviderConfig: protoUserProfileConfig(userProfileForCreate),\n },\n });\n }\n continue;\n }\n throw error;\n }\n }\n\n for (const namespaceName of deletedServices) {\n try {\n await client.getUserProfileConfig({\n workspaceId,\n namespaceName,\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n continue;\n }\n throw error;\n }\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 try {\n const { tenantProviderConfig } = await client.getTenantConfig({\n workspaceId,\n namespaceName: config.name,\n });\n if (config.tenantProvider) {\n const desired = protoTenantConfig(config.tenantProvider);\n if (!forceApplyAll && areTenantProviderConfigsEqual(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 } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\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 throw error;\n }\n }\n\n for (const namespaceName of deletedServices) {\n try {\n await client.getTenantConfig({\n workspaceId,\n namespaceName,\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n continue;\n }\n throw error;\n }\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 fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { machineUsers, nextPageToken } = await client.listAuthMachineUsers({\n workspaceId,\n authNamespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [machineUsers, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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 fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { oauth2Clients, nextPageToken } = await client.listAuthOAuth2Clients({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [oauth2Clients, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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 = existingClientsMap.get(oauth2ClientName)!;\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 try {\n await client.getAuthSCIMConfig({\n workspaceId,\n namespaceName: config.name,\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\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 continue;\n }\n throw error;\n }\n 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 try {\n await client.getAuthSCIMConfig({\n workspaceId,\n namespaceName,\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n continue;\n }\n throw error;\n }\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 try {\n const { scimResources } = await client.getAuthSCIMResources({\n workspaceId,\n namespaceName,\n });\n return scimResources;\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [];\n }\n throw error;\n }\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 let existingHook:\n | {\n scriptRef?: string;\n invoker?: {\n namespace?: string;\n machineUserName?: string;\n };\n }\n | undefined;\n try {\n const { hook } = await client.getAuthHook({\n workspaceId,\n namespaceName: config.name,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n });\n existingHook = hook;\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n existingHook = undefined;\n } else {\n throw error;\n }\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 try {\n await client.getAuthHook({\n workspaceId,\n namespaceName,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n });\n changeSet.deletes.push({\n name: `${namespaceName}/before-login`,\n request: {\n workspaceId,\n namespaceName,\n hookPoint: AuthHookPoint.BEFORE_LOGIN,\n },\n });\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n // No existing hook to delete\n } else {\n throw error;\n }\n }\n }\n\n return changeSet;\n}\n","import * as fs from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport { logger } from \"@/cli/shared/logger\";\nimport type { CallExpression, ObjectExpression, ObjectProperty } from \"@oxc-project/types\";\n\nexport interface EnsureConfigIdResult {\n id: string;\n injected: boolean;\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 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 } = calls[0];\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\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 = configObj.properties[0];\n const lineStart = source.lastIndexOf(\"\\n\", firstProp.start - 1) + 1;\n const indent = source.slice(lineStart, firstProp.start);\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 { styles, logger } from \"@/cli/shared/logger\";\nimport { prompt } from \"@/cli/shared/prompt\";\nimport ml from \"@/utils/multiline\";\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\n/**\n * Confirm reassignment of resources when owner conflicts are detected.\n * Splits into two scenarios: id regeneration (same sdk-name, different\n * sdk-app-id) and name mismatch (different sdk-name). Each gets its own\n * prompt because the user-facing meaning is different.\n * @param conflicts - Detected owner conflicts\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 confirmOwnerConflict(\n conflicts: OwnerConflict[],\n appName: string,\n yes: boolean,\n): Promise<void> {\n if (conflicts.length === 0) return;\n\n // Same sdk-name as the target app -> the app's id was regenerated\n // (typically because the user deleted the id from tailor.config.ts).\n const idRegenerated = conflicts.filter((c) => c.currentOwner === appName);\n const nameMismatches = conflicts.filter((c) => c.currentOwner !== appName);\n\n if (idRegenerated.length > 0) {\n await confirmIdRegeneration(idRegenerated, 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 logger.warn(`Application id was regenerated for \"${appName}\":`);\n logger.log(\" These resources still carry the previous id.\");\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(\"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\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-sdk 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-sdk 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-sdk 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-sdk 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","import type { AuthInvoker } from \"@/types/auth.generated\";\n\n/**\n * Normalize an authInvoker 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 object `{ namespace, machineUserName }` — returned as-is\n * @param authInvoker - String machine user name or object form\n * @param authNamespace - Auth service namespace (required when authInvoker is a string)\n * @param context - Contextual label used in error messages (e.g. `resolver \"foo\"`)\n * @returns Object form of auth invoker, or undefined\n */\nexport function normalizeAuthInvoker(\n authInvoker: string | AuthInvoker | undefined,\n authNamespace: string | undefined,\n context: string,\n): { namespace: string; machineUserName: string } | undefined {\n if (authInvoker === undefined) return undefined;\n if (typeof authInvoker === \"string\") {\n if (!authNamespace) {\n throw new Error(\n `${context} uses a string authInvoker (\"${authInvoker}\"), but no Auth service is configured. ` +\n `Configure an Auth service or use the object form { namespace, machineUserName }.`,\n );\n }\n return { namespace: authNamespace, machineUserName: authInvoker };\n }\n return authInvoker;\n}\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { fetchAll, 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 workspaceId: string;\n fetchPage: ResourcePageFetcher<T>;\n getName: (resource: T) => string | undefined;\n getTrn: (workspaceId: string, 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.workspaceId - Workspace ID\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, workspaceId, fetchPage, getName, getTrn } = params;\n const withoutLabel = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n return await fetchPage(pageToken, maxPageSize);\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\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(workspaceId, 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 CreateExecutorExecutorRequestSchema,\n type DeleteExecutorExecutorRequestSchema,\n type UpdateExecutorExecutorRequestSchema,\n} from \"@tailor-proto/tailor/v1/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-proto/tailor/v1/executor_resource_pb\";\nimport { type OperatorClient } from \"@/cli/shared/client\";\nimport { buildExecutorArgsExpr } from \"@/cli/shared/runtime-exprs\";\nimport { stringifyFunction } from \"@/parser/service/tailordb\";\nimport { normalizeAuthInvoker } from \"./auth-invoker\";\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 { buildMetaRequest, hasMatchingSdkVersion, resourceTrn } from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\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 { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\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 client.setMetadata(create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n await client.updateExecutorExecutor(update.request);\n await client.setMetadata(update.metaRequest);\n }),\n ]);\n } else if (phase === \"delete\") {\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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateExecutor = {\n name: string;\n request: MessageInitShape<typeof UpdateExecutorExecutorRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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 workspaceId,\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: (workspaceId, 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(application, 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\nfunction resolveTailorDBNamespace(application: Readonly<Application>, typeName: string): string {\n for (const service of application.tailorDBServices) {\n if (service.types[typeName]) {\n return service.namespace;\n }\n }\n throw new Error(\n `TailorDB type \"${typeName}\" not found in any namespace. Available namespaces: ${application.tailorDBServices.map((s) => s.namespace).join(\", \")}`,\n );\n}\n\nfunction resolveResolverNamespace(\n application: Readonly<Application>,\n resolverName: string,\n): string {\n for (const service of application.resolverServices) {\n if (Object.values(service.resolvers).some((r) => r.name === resolverName)) {\n return service.namespace;\n }\n }\n throw new Error(\n `Resolver \"${resolverName}\" not found in any namespace. Available namespaces: ${application.resolverServices.map((s) => s.namespace).join(\", \")}`,\n );\n}\n\nfunction resolveIdpNamespace(\n application: Readonly<Application>,\n executorName: string,\n idpName: string | undefined,\n): string {\n if (application.idpServices.length === 0) {\n throw new Error(`Executor \"${executorName}\" uses an idpUser trigger but no IdP is configured.`);\n }\n if (idpName !== undefined) {\n const found = application.idpServices.find((idp) => idp.name === idpName);\n if (!found) {\n const available = application.idpServices.map((idp) => idp.name).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 found.name;\n }\n if (application.idpServices.length > 1) {\n const available = application.idpServices.map((idp) => idp.name).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 application.idpServices[0].name;\n}\n\nfunction resolveAuthNamespace(application: Readonly<Application>): string {\n if (!application.authService) {\n throw new Error(\"No Auth service configured\");\n }\n return application.authService.config.name;\n}\n\nfunction protoExecutor(\n application: Readonly<Application>,\n executor: Executor,\n): MessageInitShape<typeof ExecutorExecutorSchema> {\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(application, trigger.typeName),\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(application, trigger.resolverName),\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(application, executor.name, trigger.idp),\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 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 = application.authService?.config.name;\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: normalizeAuthInvoker(target.authInvoker, 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: normalizeAuthInvoker(target.authInvoker, 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: target.args\n ? typeof target.args === \"function\"\n ? { expr: `(${stringifyFunction(target.args)})(${argsExpr})` }\n : { expr: JSON.stringify(target.args) }\n : undefined,\n invoker: normalizeAuthInvoker(target.authInvoker, 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 { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n type CreatePipelineResolverRequestSchema,\n type CreatePipelineServiceRequestSchema,\n type DeletePipelineResolverRequestSchema,\n type DeletePipelineServiceRequestSchema,\n type UpdatePipelineResolverRequestSchema,\n type UpdatePipelineServiceRequestSchema,\n} from \"@tailor-proto/tailor/v1/pipeline_pb\";\nimport {\n type PipelineResolver_FieldSchema,\n PipelineResolver_OperationType,\n type PipelineResolver_PipelineSchema,\n type PipelineResolver_TypeSchema,\n type PipelineResolverSchema,\n} from \"@tailor-proto/tailor/v1/pipeline_resource_pb\";\nimport * as inflection from \"inflection\";\nimport { type ResolverService } from \"@/cli/services/resolver/service\";\nimport { fetchAll, type OperatorClient } from \"@/cli/shared/client\";\nimport { buildResolverOperationHookExpr } from \"@/cli/shared/runtime-exprs\";\nimport { normalizeAuthInvoker } from \"./auth-invoker\";\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 {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"./label\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\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 { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\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 client.setMetadata(create.metaRequest);\n }),\n ...changeSet.service.updates.map(async (update) => {\n await client.updatePipelineService(update.request);\n await client.setMetadata(update.metaRequest);\n }),\n ]);\n\n // Resolvers\n await Promise.all([\n ...changeSet.resolver.creates.map((create) => client.createPipelineResolver(create.request)),\n ...changeSet.resolver.updates.map((update) => client.updatePipelineResolver(update.request)),\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 if (phase === \"delete-services\") {\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 deletedServices,\n application.env,\n application.authService?.config.name,\n forceApplyAll,\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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateService = {\n name: string;\n request: MessageInitShape<typeof UpdatePipelineServiceRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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 withoutLabel = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { pipelineServices, nextPageToken } = await client.listPipelineServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [pipelineServices, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n const existingServices: WithLabel<(typeof withoutLabel)[number]> = {};\n await Promise.all(\n withoutLabel.map(async (resource) => {\n if (!resource.namespace?.name) {\n return;\n }\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"pipeline\", resource.namespace.name),\n });\n existingServices[resource.namespace.name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\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 = isOwnedByApp(existing.allLabels, appName, appId);\n if (!owned) {\n if (!existing.label) {\n unmanaged.push({\n resourceType: \"Pipeline service\",\n resourceName: pipeline.namespace,\n });\n } else {\n conflicts.push({\n resourceType: \"Pipeline service\",\n resourceName: pipeline.namespace,\n currentOwner: existing.label,\n });\n }\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 label = entry?.label;\n const owned = isOwnedByApp(entry?.allLabels, appName, appId);\n if (label && !owned) {\n resourceOwners.add(label);\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};\n\ntype UpdateResolver = {\n name: string;\n request: MessageInitShape<typeof UpdatePipelineResolverRequestSchema>;\n};\n\ntype DeleteResolver = {\n name: string;\n request: MessageInitShape<typeof DeletePipelineResolverRequestSchema>;\n};\n\nasync function planResolvers(\n client: OperatorClient,\n workspaceId: string,\n pipelines: ReadonlyArray<Readonly<ResolverService>>,\n executors: ReadonlyArray<Executor>,\n deletedServices: ReadonlyArray<string>,\n env: Record<string, string | number | boolean>,\n authNamespace: string | undefined,\n forceApplyAll = false,\n) {\n const changeSet = createChangeSet<CreateResolver, UpdateResolver, DeleteResolver>(\n \"Pipeline resolvers\",\n );\n\n const fetchResolvers = (namespaceName: string) => {\n return fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { pipelineResolvers, nextPageToken } = await client.listPipelineResolvers({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [pipelineResolvers, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n };\n\n const executorUsedResolvers = new Set<string>();\n for (const executor of executors) {\n if (executor.trigger.kind === \"resolverExecuted\") {\n executorUsedResolvers.add(executor.trigger.resolverName);\n }\n }\n\n // Validate that resolvers used by executors don't have publishEvents explicitly set to false\n for (const pipeline of pipelines) {\n for (const resolver of Object.values(pipeline.resolvers)) {\n if (executorUsedResolvers.has(resolver.name) && resolver.publishEvents === false) {\n throw new Error(\n `Resolver \"${resolver.name}\" has publishEvents set to false, but it is used by an executor with a resolverExecuted trigger. ` +\n `Either remove the publishEvents: false setting or remove the executor trigger for this resolver.`,\n );\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 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 changeSet.unchanged.push({ name: resolver.name });\n } else {\n changeSet.updates.push({\n name: resolver.name,\n request: {\n workspaceId,\n namespaceName: pipeline.namespace,\n pipelineResolver: desiredResolver,\n },\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 });\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: normalizeAuthInvoker(\n resolver.authInvoker,\n authNamespace,\n `Resolver \"${resolver.name}\"`,\n ),\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> = protoFields(\n { \"\": resolver.output },\n `${typeBaseName}Output`,\n false,\n )[0];\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 // Determine publishExecutionEvents (user-facing name: publishEvents):\n // - If user explicitly sets a value (true or false), respect that (validation already ensures no executor conflict)\n // - If not set, use executor detection (true if executor uses this resolver)\n let publishExecutionEvents = false;\n if (resolver.publishEvents !== undefined) {\n publishExecutionEvents = resolver.publishEvents;\n } else if (executorUsedResolvers.has(resolver.name)) {\n publishExecutionEvents = true;\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 if (!fields) {\n return [];\n }\n\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 { Code, ConnectError } from \"@connectrpc/connect\";\nimport { fetchAll, type OperatorClient } from \"@/cli/shared/client\";\nimport { createChangeSet } from \"./change-set\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"./label\";\nimport { hashValue, loadSecretsState, saveSecretsState } from \"./secrets-state\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase, PlanContext } from \"@/cli/commands/deploy/types\";\nimport type { Application } from \"@/cli/services/application\";\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 * 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 existingVaultList = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { vaults, nextPageToken } = await client.listSecretManagerVaults({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [vaults, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n\n const existingVaults: WithLabel<(typeof existingVaultList)[number]> = {};\n await Promise.all(\n existingVaultList.map(async (resource) => {\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"vault\", resource.name),\n });\n existingVaults[resource.name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\n );\n\n const state = loadSecretsState();\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 = isOwnedByApp(existing.allLabels, application.name, application.id);\n if (!owned) {\n if (!existing.label) {\n unmanaged.push({\n resourceType: \"Secret Manager vault\",\n resourceName: vaultName,\n });\n } else {\n conflicts.push({\n resourceType: \"Secret Manager vault\",\n resourceName: vaultName,\n currentOwner: existing.label,\n });\n }\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 let existingSecrets: string[] = [];\n if (existing) {\n const secrets = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { secrets, nextPageToken } = await client.listSecretManagerSecrets({\n workspaceId,\n secretmanagerVaultName: vaultName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [secrets, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n existingSecrets = secrets.map((s) => s.name);\n }\n\n const existingSet = new Set(existingSecrets);\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 currentHash = hashValue(secret.value);\n const storedHash = state.vaults[vaultName]?.[secret.name];\n if (forceApplyAll || currentHash !== storedHash) {\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 label = entry.label;\n const owned = isOwnedByApp(entry.allLabels, application.name, application.id);\n if (label && !owned) {\n resourceOwners.add(label);\n }\n if (owned) {\n // Delete secrets inside the vault before deleting the vault itself\n const secrets = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { secrets, nextPageToken } = await client.listSecretManagerSecrets({\n workspaceId,\n secretmanagerVaultName: name,\n pageToken,\n pageSize: maxPageSize,\n });\n return [secrets, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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 { vaultChangeSet, secretChangeSet, skippedSecrets, conflicts, unmanaged, resourceOwners };\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 to read secrets from for 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 } = 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({\n workspaceId: create.workspaceId,\n secretmanagerVaultName: create.name,\n });\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 client.setMetadata(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 client.setMetadata(metaRequest);\n }),\n );\n }\n\n // Create new secrets\n await Promise.all(\n secretChangeSet.creates.map((create) =>\n client.createSecretManagerSecret({\n workspaceId: create.workspaceId,\n secretmanagerVaultName: create.vaultName,\n secretmanagerSecretName: create.secretName,\n secretmanagerSecretValue: create.value,\n }),\n ),\n );\n\n // Update existing secrets\n await Promise.all(\n secretChangeSet.updates.map((update) =>\n client.updateSecretManagerSecret({\n workspaceId: update.workspaceId,\n secretmanagerVaultName: update.vaultName,\n secretmanagerSecretName: update.secretName,\n secretmanagerSecretValue: update.value,\n }),\n ),\n );\n\n // Persist hash state for all secrets after successful apply\n if (application) {\n const state = loadSecretsState();\n for (const vault of application.secrets) {\n if (!state.vaults[vault.vaultName]) {\n state.vaults[vault.vaultName] = {};\n }\n for (const secret of vault.secrets) {\n if (secret.value != null) {\n state.vaults[vault.vaultName][secret.name] = hashValue(secret.value);\n }\n }\n }\n saveSecretsState(state);\n }\n } else if (phase === \"delete\") {\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 if (secretChangeSet.deletes.length > 0 || vaultChangeSet.deletes.length > 0) {\n const state = loadSecretsState();\n for (const del of secretChangeSet.deletes) {\n if (state.vaults[del.vaultName]) {\n delete state.vaults[del.vaultName][del.secretName];\n if (Object.keys(state.vaults[del.vaultName]).length === 0) {\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(state);\n }\n }\n}\n","import { type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport {\n type AddCustomDomainRequestSchema,\n type CreateStaticWebsiteRequestSchema,\n type DeleteStaticWebsiteRequestSchema,\n type RemoveCustomDomainRequestSchema,\n type UpdateStaticWebsiteRequestSchema,\n} from \"@tailor-proto/tailor/v1/staticwebsite_pb\";\nimport { type OperatorClient } from \"@/cli/shared/client\";\nimport { createChangeSet } from \"./change-set\";\nimport { areNormalizedEqual } from \"./compare\";\nimport { buildMetaRequest, hasMatchingSdkVersion, isOwnedByApp, resourceTrn } from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase, PlanContext } from \"@/cli/commands/deploy/types\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\nimport type { StaticWebsite as ProtoStaticWebsite } from \"@tailor-proto/tailor/v1/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 client.setMetadata(create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n await client.updateStaticWebsite(update.request);\n await client.setMetadata(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 client.setMetadata(add.metaRequest);\n }),\n ...customDomainChangeSet.deletes.map((del) => client.removeCustomDomain(del.request)),\n ]);\n } else if (phase === \"delete\") {\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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateStaticWebsite = {\n name: string;\n request: MessageInitShape<typeof UpdateStaticWebsiteRequestSchema>;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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: MessageInitShape<typeof SetMetadataRequestSchema>;\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 * 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 workspaceId,\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: (workspaceId, 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 try {\n const { customDomains } = await client.listCustomDomains({\n workspaceId,\n staticWebsiteName: name,\n });\n const domainsWithLabels = 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 existingDomainsByWebsite.set(name, domainsWithLabels);\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return;\n }\n throw error;\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","/**\n * Migration configuration utilities\n */\n\nimport * as path from \"pathe\";\nimport type { AppConfig } from \"@/types/app-config\";\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 * 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 = 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/**\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/** 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/** 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/**\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 | FieldAddedChange\n | FieldRemovedChange\n | FieldModifiedChange\n | IndexAddedChange\n | IndexRemovedChange\n | IndexModifiedChange\n | FileAddedChange\n | FileRemovedChange\n | FileModifiedChange\n | RelationshipAddedChange\n | RelationshipRemovedChange\n | RelationshipModifiedChange\n | PermissionModifiedChange;\n\n/**\n * Field-level diff change (added / removed / modified).\n */\nexport type FieldDiffChange = FieldAddedChange | FieldRemovedChange | FieldModifiedChange;\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: typeof SCHEMA_SNAPSHOT_VERSION;\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}\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 \"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 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 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 field_added: \"field(s) added\",\n field_removed: \"field(s) removed\",\n field_modified: \"field(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};\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","/**\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 * 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 /** 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 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}\n","/**\n * Schema snapshot management for TailorDB migrations\n */\n\nimport * as fs from \"node:fs\";\nimport * as inflection from \"inflection\";\nimport * as path from \"pathe\";\nimport {\n type MigrationDiff,\n type DiffChange,\n type FieldDiffChange,\n type BreakingChangeInfo,\n type WarningChangeInfo,\n SCHEMA_SNAPSHOT_VERSION,\n} from \"./diff-calculator\";\nimport { formatMigrationNumber } from \"./migration-number\";\nimport type {\n SnapshotActionPermission,\n SnapshotFieldConfig,\n SnapshotGqlAction,\n SnapshotGqlPermission,\n SnapshotIndexConfig,\n SnapshotPermissionCondition,\n SnapshotRecordPermission,\n SnapshotRelationship,\n TailorDBSnapshotType,\n} from \"./snapshot-types\";\nimport type { SchemaDrift } from \"./types\";\nimport type {\n ParsedField,\n TailorDBType,\n OperatorFieldConfig,\n StandardActionPermission,\n} from \"@/types/tailordb\";\nimport type { TailorDBType as ProtoTailorDBType } from \"@tailor-proto/tailor/v1/tailordb_resource_pb\";\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 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\n/**\n * Normalize a snapshot field in place so the snapshot becomes the canonical\n * form for comparison. Currently fills in the platform default decimal scale\n * when omitted, which avoids false drift between local schemas (where scale\n * may be omitted) and the platform (which always materializes a scale).\n * @param {SnapshotFieldConfig} field - Field configuration to normalize\n */\nfunction normalizeSnapshotField(field: SnapshotFieldConfig): void {\n if (field.type === \"decimal\" && field.scale === undefined) {\n field.scale = DEFAULT_DECIMAL_SCALE;\n }\n if (field.fields) {\n for (const nested of Object.values(field.fields)) {\n normalizeSnapshotField(nested);\n }\n }\n}\n\n/**\n * Normalize a snapshot type in place to the canonical comparison shape.\n * 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 */\nfunction normalizeSnapshotType(type: TailorDBSnapshotType): void {\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 if (!(type as { pluralForm?: string }).pluralForm) {\n type.pluralForm = inflection.pluralize(type.name);\n }\n for (const field of Object.values(type.fields)) {\n normalizeSnapshotField(field);\n }\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 SnapshotHook,\n SnapshotValidation,\n SnapshotSerial,\n SnapshotEnumValue,\n SnapshotFieldConfig,\n SnapshotIndexConfig,\n SnapshotRelationship,\n SnapshotFieldRefOperand,\n SnapshotValueOperand,\n SnapshotPermissionOperand,\n SnapshotPermissionOperator,\n SnapshotPermissionCondition,\n SnapshotActionPermission,\n SnapshotRecordPermission,\n SnapshotGqlAction,\n SnapshotGqlPermissionPolicy,\n SnapshotGqlPermission,\n TailorDBSnapshotType,\n} from \"./snapshot-types\";\n\n/**\n * Schema snapshot - full schema state at a point in time\n * Stored as XXXX/schema.json (e.g., 0000/schema.json for initial snapshot)\n */\nexport interface SchemaSnapshot {\n /** Format version for future compatibility */\n version: typeof SCHEMA_SNAPSHOT_VERSION;\n namespace: string;\n createdAt: string;\n types: Record<string, TailorDBSnapshotType>;\n}\n\n/**\n * Migration file type\n */\nexport type MigrationFileType = \"schema\" | \"diff\" | \"migrate\" | \"db\";\n\n/**\n * Information about a migration\n */\nexport interface MigrationInfo {\n /** Migration number (e.g., 1, 2, 3) */\n number: number;\n /** Migration number as 4-digit string (e.g., \"0001\", \"0002\") */\n numberStr: string;\n /** Migration file type */\n type: MigrationFileType;\n /** Path to migration file */\n path: string;\n /** Parsed content (schema snapshot or diff) */\n content: SchemaSnapshot | MigrationDiff;\n}\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 * Parse migration number from file name\n * @param {string} fileName - File name (e.g., \"0001_schema.json\")\n * @returns {number | null} Parsed number or null if invalid\n */\nexport function parseMigrationNumber(fileName: string): number | null {\n const match = fileName.match(/^(\\d{4})_/);\n if (!match) return null;\n const num = parseInt(match[1], 10);\n return isNaN(num) ? null : num;\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 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 a parsed field\n * @param {ParsedField} field - Parsed field definition\n * @returns {SnapshotFieldConfig} Snapshot field configuration\n */\nfunction createSnapshotFieldConfig(field: ParsedField): SnapshotFieldConfig {\n // Note: Use `!== false` to match generateParsedTailorDBTypeManifest behavior\n // where undefined defaults to true (required by default in SDK)\n const config: SnapshotFieldConfig = {\n type: field.config.type,\n required: field.config.required !== false,\n };\n\n if (field.config.array) config.array = true;\n if (field.config.index) config.index = true;\n if (field.config.unique) config.unique = true;\n\n if (field.config.allowedValues && field.config.allowedValues.length > 0) {\n config.allowedValues = field.config.allowedValues.map((v) => ({\n value: v.value,\n ...(v.description && { description: v.description }),\n }));\n }\n\n if (field.config.foreignKey) {\n config.foreignKey = true;\n if (field.config.foreignKeyType) config.foreignKeyType = field.config.foreignKeyType;\n if (field.config.foreignKeyField) config.foreignKeyField = field.config.foreignKeyField;\n }\n\n if (field.config.description) config.description = field.config.description;\n if (field.config.vector) config.vector = true;\n\n if (field.config.hooks) {\n config.hooks = {};\n if (field.config.hooks.create) {\n config.hooks.create = { expr: field.config.hooks.create.expr };\n }\n if (field.config.hooks.update) {\n config.hooks.update = { expr: field.config.hooks.update.expr };\n }\n }\n\n if (field.config.validate && field.config.validate.length > 0) {\n config.validate = field.config.validate.map((v) => ({\n script: { expr: v.script.expr },\n errorMessage: v.errorMessage,\n }));\n }\n\n if (field.config.serial) {\n config.serial = {\n start: field.config.serial.start,\n ...(field.config.serial.maxValue !== undefined && { maxValue: field.config.serial.maxValue }),\n ...(field.config.serial.format && { format: field.config.serial.format }),\n };\n }\n\n if (field.config.scale !== undefined) config.scale = field.config.scale;\n\n if (field.config.fields && Object.keys(field.config.fields).length > 0) {\n config.fields = {};\n for (const [nestedName, nestedConfig] of Object.entries(field.config.fields)) {\n config.fields[nestedName] = createSnapshotFieldConfigFromOperatorConfig(nestedConfig);\n }\n }\n\n normalizeSnapshotField(config);\n return config;\n}\n\n/**\n * Create a snapshot field config from an OperatorFieldConfig (for nested fields)\n * @param {import(\"@/types/tailordb\").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\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 normalizeSnapshotField(config);\n return 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: Record<string, SnapshotFieldConfig> = {};\n\n for (const [fieldName, field] of Object.entries(type.fields)) {\n fields[fieldName] = createSnapshotFieldConfig(field);\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 if (type.settings) {\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\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 (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 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 {SchemaSnapshot} Schema snapshot\n */\nexport function createSnapshotFromLocalTypes(\n types: Record<string, TailorDBType>,\n namespace: string,\n): SchemaSnapshot {\n const snapshotTypes: Record<string, TailorDBSnapshotType> = {};\n\n for (const [typeName, type] of Object.entries(types)) {\n snapshotTypes[typeName] = createSnapshotType(type);\n }\n\n return {\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 {SchemaSnapshot} Loaded schema snapshot\n */\nexport function loadSnapshot(filePath: string): SchemaSnapshot {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const snapshot = JSON.parse(content) as SchemaSnapshot;\n for (const type of Object.values(snapshot.types)) {\n normalizeSnapshotType(type);\n }\n return 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 const parsed = JSON.parse(content) as MigrationDiff;\n // Backfill fields introduced after the initial diff.json schema so that older\n // migrations on disk remain readable without manual edits. hasWarnings is\n // derived from the warnings array to stay consistent even if a hand-edited\n // diff.json sets one side without the other.\n const warnings = parsed.warnings ?? [];\n return {\n ...parsed,\n warnings,\n hasWarnings: warnings.length > 0,\n };\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 {SchemaSnapshot} Resulting snapshot after applying diff\n */\nfunction applyDiffToSnapshot(snapshot: SchemaSnapshot, diff: MigrationDiff): SchemaSnapshot {\n const types = { ...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 if (types[change.typeName] && change.after) {\n const after = change.after;\n types[change.typeName] = {\n ...types[change.typeName],\n ...(after.indexes !== undefined && { indexes: after.indexes }),\n ...(after.files !== undefined && { files: after.files }),\n };\n }\n break;\n case \"field_added\":\n case \"field_modified\":\n if (types[change.typeName] && change.fieldName) {\n types[change.typeName] = {\n ...types[change.typeName],\n fields: {\n ...types[change.typeName].fields,\n [change.fieldName]: change.after,\n },\n };\n }\n break;\n case \"field_removed\":\n if (types[change.typeName] && change.fieldName) {\n const { [change.fieldName]: _, ...remainingFields } = types[change.typeName].fields;\n types[change.typeName] = {\n ...types[change.typeName],\n fields: remainingFields,\n };\n }\n break;\n case \"index_added\":\n case \"index_modified\":\n if (types[change.typeName] && change.indexName) {\n types[change.typeName] = {\n ...types[change.typeName],\n indexes: {\n ...types[change.typeName].indexes,\n [change.indexName]: change.after,\n },\n };\n }\n break;\n case \"index_removed\":\n if (types[change.typeName] && change.indexName && types[change.typeName].indexes) {\n const { [change.indexName]: _, ...remainingIndexes } = types[change.typeName].indexes!;\n types[change.typeName] = {\n ...types[change.typeName],\n indexes: Object.keys(remainingIndexes).length > 0 ? remainingIndexes : undefined,\n };\n }\n break;\n case \"file_added\":\n case \"file_modified\":\n if (types[change.typeName] && change.fieldName) {\n types[change.typeName] = {\n ...types[change.typeName],\n files: {\n ...types[change.typeName].files,\n [change.fieldName]: change.after,\n },\n };\n }\n break;\n case \"file_removed\":\n if (types[change.typeName] && change.fieldName && types[change.typeName].files) {\n const { [change.fieldName]: _, ...remainingFiles } = types[change.typeName].files!;\n types[change.typeName] = {\n ...types[change.typeName],\n files: Object.keys(remainingFiles).length > 0 ? remainingFiles : undefined,\n };\n }\n break;\n case \"relationship_added\":\n case \"relationship_modified\":\n if (types[change.typeName] && change.relationshipName) {\n const rel = change.after;\n // Use relationshipType if specified, fallback to existing logic for backwards compatibility\n const targetType =\n change.relationshipType ??\n (types[change.typeName].forwardRelationships?.[change.relationshipName]\n ? \"forward\"\n : types[change.typeName].backwardRelationships?.[change.relationshipName]\n ? \"backward\"\n : \"forward\");\n\n if (targetType === \"forward\") {\n types[change.typeName] = {\n ...types[change.typeName],\n forwardRelationships: {\n ...types[change.typeName].forwardRelationships,\n [change.relationshipName]: rel,\n },\n };\n } else {\n types[change.typeName] = {\n ...types[change.typeName],\n backwardRelationships: {\n ...types[change.typeName].backwardRelationships,\n [change.relationshipName]: rel,\n },\n };\n }\n }\n break;\n case \"relationship_removed\":\n if (types[change.typeName] && change.relationshipName) {\n const type = types[change.typeName];\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 { [change.relationshipName]: _, ...remaining } = type.forwardRelationships;\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 { [change.relationshipName]: _, ...remaining } = type.backwardRelationships;\n types[change.typeName] = {\n ...type,\n backwardRelationships: Object.keys(remaining).length > 0 ? remaining : undefined,\n };\n }\n }\n break;\n case \"permission_modified\":\n if (types[change.typeName] && change.after) {\n const after = change.after;\n types[change.typeName] = {\n ...types[change.typeName],\n permissions: {\n record: after.recordPermission,\n gql: after.gqlPermission,\n },\n };\n }\n break;\n }\n }\n\n return {\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 {SchemaSnapshot | null} Reconstructed snapshot or null if no migrations exist\n */\nexport function reconstructSnapshotFromMigrations(\n migrationsDir: string,\n maxVersion?: number,\n): SchemaSnapshot | 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 const files = getMigrationFiles(migrationsDir);\n if (files.length === 0) return 0;\n return Math.max(...files.map((f) => f.number));\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 if (oldValidate[i].script.expr !== newValidate[i].script.expr) return true;\n if (oldValidate[i].errorMessage !== newValidate[i].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 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 if (!newFields[fieldName]) return true;\n if (areFieldsDifferent(oldFields[fieldName], newFields[fieldName])) return true;\n }\n\n return false;\n}\n\n/**\n * Determine if a field change is a breaking 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 | null} Breaking change info or null if not breaking\n */\nfunction isBreakingFieldChange(\n typeName: string,\n fieldName: string,\n oldField: SnapshotFieldConfig | undefined,\n newField: SnapshotFieldConfig | undefined,\n): BreakingChangeInfo | null {\n // Field added as required - breaking (existing records don't have this value)\n if (!oldField && newField && newField.required) {\n return {\n typeName,\n fieldName,\n reason: \"Required field added\",\n };\n }\n\n // Field type changed - unsupported (requires 3-step migration)\n if (oldField && newField && oldField.type !== newField.type) {\n return {\n typeName,\n fieldName,\n reason: `Field type changed from ${oldField.type} to ${newField.type}`,\n unsupported: true,\n showThreeStepHint: true,\n };\n }\n\n // Optional to required - breaking\n if (oldField && newField && !oldField.required && newField.required) {\n return {\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 return {\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 return {\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 return {\n typeName,\n fieldName,\n reason: \"Unique constraint added to field\",\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 return {\n typeName,\n fieldName,\n reason: `Enum values removed: ${removedValues.join(\", \")}`,\n };\n }\n }\n\n return null;\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 breaking = isBreakingFieldChange(change.typeName, change.fieldName, oldField, newField);\n if (breaking) {\n ctx.breakingChanges.push(breaking);\n return;\n }\n\n // Non-breaking removal still risks data loss: surface as 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 (existing data will be dropped in the post-migration phase)\",\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 addChange(\n ctx,\n {\n kind: \"field_added\",\n typeName,\n fieldName,\n after: currType.fields[fieldName],\n },\n undefined,\n currType.fields[fieldName],\n );\n }\n }\n\n // Check for removed fields\n for (const fieldName of prevFieldNames) {\n if (!currFieldNames.has(fieldName)) {\n addChange(\n ctx,\n {\n kind: \"field_removed\",\n typeName,\n fieldName,\n before: prevType.fields[fieldName],\n },\n prevType.fields[fieldName],\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 = prevType.fields[fieldName];\n const currField = currType.fields[fieldName];\n\n if (areFieldsDifferent(prevField, currField)) {\n addChange(\n ctx,\n {\n kind: \"field_modified\",\n typeName,\n fieldName,\n before: prevField,\n after: currField,\n },\n prevField,\n currField,\n );\n }\n }\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 of newKeys) {\n if (!oldKeys.has(indexName)) {\n ctx.changes.push({\n kind: \"index_added\",\n typeName,\n indexName,\n after: newIndexes![indexName],\n });\n }\n }\n\n // Index removed\n for (const indexName of oldKeys) {\n if (!newKeys.has(indexName)) {\n ctx.changes.push({\n kind: \"index_removed\",\n typeName,\n indexName,\n before: oldIndexes![indexName],\n });\n }\n }\n\n // Index modified\n for (const indexName of newKeys) {\n if (oldKeys.has(indexName)) {\n const oldIndex = oldIndexes![indexName];\n const newIndex = newIndexes![indexName];\n\n const oldFieldsStr = JSON.stringify(oldIndex.fields.toSorted());\n const newFieldsStr = JSON.stringify(newIndex.fields.toSorted());\n\n if (oldFieldsStr !== newFieldsStr || oldIndex.unique !== newIndex.unique) {\n const reasons: string[] = [];\n if (oldFieldsStr !== newFieldsStr) reasons.push(\"fields changed\");\n if (oldIndex.unique !== newIndex.unique) 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 }\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 of newKeys) {\n if (!oldKeys.has(fileName)) {\n ctx.changes.push({\n kind: \"file_added\",\n typeName,\n fieldName: fileName,\n after: newFiles![fileName],\n });\n }\n }\n\n // File field removed\n for (const fileName of oldKeys) {\n if (!newKeys.has(fileName)) {\n ctx.changes.push({\n kind: \"file_removed\",\n typeName,\n fieldName: fileName,\n before: oldFiles![fileName],\n });\n }\n }\n\n // File field modified (description changed)\n for (const fileName of newKeys) {\n if (oldKeys.has(fileName)) {\n if (oldFiles![fileName] !== newFiles![fileName]) {\n ctx.changes.push({\n kind: \"file_modified\",\n typeName,\n fieldName: fileName,\n reason: \"description changed\",\n before: oldFiles![fileName],\n after: newFiles![fileName],\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 of newKeys) {\n if (!oldKeys.has(relName)) {\n ctx.changes.push({\n kind: \"relationship_added\",\n typeName,\n relationshipName: relName,\n relationshipType,\n after: newRelationships![relName],\n });\n }\n }\n\n // Relationship removed\n for (const relName of oldKeys) {\n if (!newKeys.has(relName)) {\n ctx.changes.push({\n kind: \"relationship_removed\",\n typeName,\n relationshipName: relName,\n relationshipType,\n before: oldRelationships![relName],\n });\n }\n }\n\n // Relationship modified\n for (const relName of newKeys) {\n if (oldKeys.has(relName)) {\n const oldRel = oldRelationships![relName];\n const newRel = newRelationships![relName];\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\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 oldRecordStr = JSON.stringify(oldRecordPerm ?? null);\n const newRecordStr = JSON.stringify(newRecordPerm ?? null);\n const recordPermChanged = oldRecordStr !== newRecordStr;\n\n // Compare GQL permissions\n const oldGqlStr = JSON.stringify(oldGqlPerm ?? null);\n const newGqlStr = JSON.stringify(newGqlPerm ?? 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: oldRecordPerm, gqlPermission: oldGqlPerm },\n after: { recordPermission: newRecordPerm, gqlPermission: newGqlPerm },\n });\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 // Defense-in-depth: factory functions (`createSnapshotType`, `loadSnapshot`,\n // `convertRemoteFieldsToSnapshot`) are expected to produce normalized\n // snapshots, but a caller assembling a SchemaSnapshot literal would otherwise\n // produce silent false drift (e.g. decimal scale 6 vs unset). Idempotent.\n for (const type of Object.values(previous.types)) normalizeSnapshotType(type);\n for (const type of Object.values(current.types)) normalizeSnapshotType(type);\n\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 of currentTypeNames) {\n if (!previousTypeNames.has(typeName)) {\n ctx.changes.push({\n kind: \"type_added\",\n typeName,\n after: current.types[typeName],\n });\n }\n }\n\n // Check for removed types\n for (const typeName of previousTypeNames) {\n if (!currentTypeNames.has(typeName)) {\n ctx.changes.push({\n kind: \"type_removed\",\n typeName,\n before: previous.types[typeName],\n });\n ctx.warnings.push({\n typeName,\n reason:\n \"Type removed (all records of this type will be dropped in the post-migration phase)\",\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 = previous.types[typeName];\n const currType = current.types[typeName];\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 if (file.type === \"diff\") {\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\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: Record<string, SnapshotFieldConfig> = {};\n const remoteFields = remoteType.schema?.fields ?? {};\n\n for (const [fieldName, remoteField] of Object.entries(remoteFields)) {\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 if (remoteField.allowedValues && remoteField.allowedValues.length > 0) {\n config.allowedValues = remoteField.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 if (remoteField.validate && remoteField.validate.length > 0) {\n config.validate = remoteField.validate.map((v) => ({\n script: { expr: v.script?.expr ?? \"\" },\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 // TODO: Add nested field conversion when remote API supports it\n\n normalizeSnapshotField(config);\n fields[fieldName] = config;\n }\n\n return fields;\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\n // Compare type\n if (remoteField.type !== snapshotField.type) {\n differences.push(`type: remote=${remoteField.type}, expected=${snapshotField.type}`);\n }\n\n // Compare required\n if (remoteField.required !== snapshotField.required) {\n differences.push(\n `required: remote=${remoteField.required}, expected=${snapshotField.required}`,\n );\n }\n\n // Compare array\n const remoteArray = remoteField.array ?? false;\n const snapshotArray = snapshotField.array ?? false;\n if (remoteArray !== snapshotArray) {\n differences.push(`array: remote=${remoteArray}, expected=${snapshotArray}`);\n }\n\n // Compare unique\n const remoteUnique = remoteField.unique ?? false;\n const snapshotUnique = snapshotField.unique ?? false;\n if (remoteUnique !== snapshotUnique) {\n differences.push(`unique: remote=${remoteUnique}, expected=${snapshotUnique}`);\n }\n\n // Compare foreignKey\n const remoteFk = remoteField.foreignKey ?? false;\n const snapshotFk = snapshotField.foreignKey ?? false;\n if (remoteFk !== snapshotFk) {\n differences.push(`foreignKey: remote=${remoteFk}, expected=${snapshotFk}`);\n }\n\n // Compare foreignKeyType\n if (remoteField.foreignKeyType !== snapshotField.foreignKeyType) {\n differences.push(\n `foreignKeyType: remote=${remoteField.foreignKeyType ?? \"none\"}, expected=${snapshotField.foreignKeyType ?? \"none\"}`,\n );\n }\n\n const remoteAllowed = remoteField.allowedValues ?? [];\n const snapshotAllowed = snapshotField.allowedValues ?? [];\n const remoteAllowedValues = new Set(remoteAllowed.map((v) => v.value));\n const snapshotAllowedValues = new Set(snapshotAllowed.map((v) => v.value));\n if (remoteAllowedValues.size !== snapshotAllowedValues.size) {\n differences.push(\n `allowedValues count: remote=${remoteAllowedValues.size}, expected=${snapshotAllowedValues.size}`,\n );\n } else {\n for (const v of remoteAllowedValues) {\n if (!snapshotAllowedValues.has(v)) {\n differences.push(`allowedValues: remote has '${v}' not in snapshot`);\n break;\n }\n }\n for (const v of snapshotAllowedValues) {\n if (!remoteAllowedValues.has(v)) {\n differences.push(`allowedValues: snapshot has '${v}' not in remote`);\n break;\n }\n }\n }\n\n const remoteVector = remoteField.vector ?? false;\n const snapshotVector = snapshotField.vector ?? false;\n if (remoteVector !== snapshotVector) {\n differences.push(`vector: remote=${remoteVector}, expected=${snapshotVector}`);\n }\n\n if (remoteField.scale !== snapshotField.scale) {\n differences.push(`scale: remote=${remoteField.scale}, expected=${snapshotField.scale}`);\n }\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 * @returns {SchemaDrift[]} List of drifts detected\n */\nexport function compareRemoteWithSnapshot(\n remoteTypes: ProtoTailorDBType[],\n snapshot: SchemaSnapshot,\n): SchemaDrift[] {\n // Defense-in-depth normalize — matches `compareSnapshots`. Idempotent.\n for (const type of Object.values(snapshot.types)) normalizeSnapshotType(type);\n\n const drifts: SchemaDrift[] = [];\n\n // Build maps for easy lookup\n const remoteTypeMap = new Map<string, ProtoTailorDBType>();\n for (const remoteType of remoteTypes) {\n remoteTypeMap.set(remoteType.name, remoteType);\n }\n\n const snapshotTypeNames = new Set(Object.keys(snapshot.types));\n const remoteTypeNames = new Set(remoteTypeMap.keys());\n\n // Check for types missing in remote\n for (const typeName of snapshotTypeNames) {\n if (!remoteTypeNames.has(typeName)) {\n drifts.push({\n typeName,\n kind: \"type_missing_remote\",\n details: `Type '${typeName}' exists in snapshot but not in remote`,\n });\n }\n }\n\n // Check for types missing in snapshot (unexpected types in remote)\n for (const typeName of remoteTypeNames) {\n if (!snapshotTypeNames.has(typeName)) {\n drifts.push({\n typeName,\n kind: \"type_missing_local\",\n details: `Type '${typeName}' exists in remote but not in snapshot`,\n });\n }\n }\n\n // Compare fields for types that exist in both\n for (const typeName of snapshotTypeNames) {\n if (!remoteTypeNames.has(typeName)) continue;\n\n const remoteType = remoteTypeMap.get(typeName)!;\n const snapshotType = snapshot.types[typeName];\n\n const remoteFields = convertRemoteFieldsToSnapshot(remoteType);\n const snapshotFields = snapshotType.fields;\n\n // Exclude system fields (like 'id') from comparison\n const remoteFieldNames = new Set(\n Object.keys(remoteFields).filter((f) => !SYSTEM_FIELDS.has(f)),\n );\n const snapshotFieldNames = new Set(\n Object.keys(snapshotFields).filter((f) => !SYSTEM_FIELDS.has(f)),\n );\n\n // Check for fields missing in remote\n for (const fieldName of snapshotFieldNames) {\n if (!remoteFieldNames.has(fieldName)) {\n drifts.push({\n typeName,\n kind: \"field_missing_remote\",\n fieldName,\n details: `Field '${fieldName}' exists in snapshot but not in remote`,\n });\n }\n }\n\n // Check for fields missing in snapshot\n for (const fieldName of remoteFieldNames) {\n if (!snapshotFieldNames.has(fieldName)) {\n drifts.push({\n typeName,\n kind: \"field_missing_local\",\n fieldName,\n details: `Field '${fieldName}' exists in remote but not in snapshot`,\n });\n }\n }\n\n // Compare fields that exist in both\n for (const fieldName of snapshotFieldNames) {\n if (!remoteFieldNames.has(fieldName)) continue;\n\n const drift = compareFields(\n typeName,\n fieldName,\n remoteFields[fieldName],\n snapshotFields[fieldName],\n );\n if (drift) {\n drifts.push(drift);\n }\n }\n }\n\n return drifts;\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 {\n lines.push(` - ${drift.details}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\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 TailorDBType_Permission_Operator,\n TailorDBType_Permission_Permit,\n TailorDBType_PermitAction,\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-proto/tailor/v1/tailordb_resource_pb\";\nimport * as inflection from \"inflection\";\nimport { isSnapshotFieldRefOperand } from \"./snapshot\";\nimport type {\n SchemaSnapshot,\n SnapshotEnumValue,\n SnapshotFieldConfig,\n TailorDBSnapshotType,\n SnapshotRelationship,\n SnapshotRecordPermission,\n SnapshotActionPermission,\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 to enable publishRecordEvents (default: false) */\n publishRecordEvents?: 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 // Read publishEvents from snapshot settings first, then fall back to options\n publishRecordEvents:\n snapshotType.settings?.publishEvents ?? options.publishRecordEvents ?? false,\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<string, MessageInitShape<typeof TailorDBType_FieldConfigSchema>> = {};\n for (const [fieldName, fieldConfig] of Object.entries(snapshotType.fields)) {\n if (fieldName === \"id\") continue;\n fields[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 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 },\n };\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 validate: toProtoSnapshotFieldValidate(config),\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 ?? true,\n vector: config.vector ?? false,\n ...toProtoSnapshotFieldHooks(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\nfunction toProtoSnapshotFieldValidate(\n config: SnapshotFieldConfig,\n): MessageInitShape<typeof TailorDBType_FieldConfigSchema>[\"validate\"] {\n return (config.validate ?? []).map((val) => ({\n action: TailorDBType_PermitAction.DENY,\n errorMessage: val.errorMessage || \"\",\n ...(val.script && {\n script: {\n expr: val.script.expr ? `!${val.script.expr}` : \"\",\n },\n }),\n }));\n}\n\nfunction toProtoSnapshotFieldHooks(\n config: SnapshotFieldConfig,\n): Pick<MessageInitShape<typeof TailorDBType_FieldConfigSchema>, \"hooks\"> | Record<never, never> {\n if (!config.hooks) {\n return {};\n }\n return {\n hooks: {\n create: config.hooks.create\n ? {\n expr: config.hooks.create.expr || \"\",\n }\n : undefined,\n update: config.hooks.update\n ? {\n expr: config.hooks.update.expr || \"\",\n }\n : undefined,\n },\n };\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 validate: toProtoSnapshotFieldValidate(fieldConfig),\n required: fieldConfig.required ?? true,\n array: fieldConfig.array ?? false,\n index: false,\n unique: false,\n foreignKey: false,\n vector: false,\n ...toProtoSnapshotFieldHooks(fieldConfig),\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 validate: toProtoSnapshotFieldValidate(fieldConfig),\n required: fieldConfig.required ?? true,\n array: fieldConfig.array ?? false,\n index: false,\n unique: false,\n foreignKey: false,\n vector: false,\n ...toProtoSnapshotFieldHooks(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 */\nfunction 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 // Validate: if executor uses this type, publishEvents must not be explicitly false\n if (executorUsedTypes?.has(typeName) && snapshotType.settings?.publishEvents === false) {\n throw new Error(\n `Type \"${typeName}\" has publishEvents set to false, but it is used by an executor with a record trigger. ` +\n `Either remove the publishEvents: false setting or remove the executor trigger for this type.`,\n );\n }\n\n // Determine publishRecordEvents:\n // - If user explicitly sets a value (true or false), respect that (validation above ensures no executor conflict)\n // - If not set, check if executor uses this type (true if yes)\n // - Fall back to base options or default to false\n let publishRecordEvents: boolean;\n if (snapshotType.settings?.publishEvents !== undefined) {\n publishRecordEvents = snapshotType.settings.publishEvents;\n } else if (executorUsedTypes?.has(typeName)) {\n publishRecordEvents = true;\n } else {\n publishRecordEvents = baseOptions.publishRecordEvents ?? false;\n }\n const typeOptions: GenerateManifestOptions = {\n ...baseOptions,\n publishRecordEvents,\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 * 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 *\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 { convertFieldConfigToProto } from \"./snapshot-manifest\";\nimport type { DiffChange, FieldDiffChange } from \"./diff-calculator\";\nimport type { PendingMigration } from \"./types\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { TailorDBType_FieldConfigSchema } from \"@tailor-proto/tailor/v1/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_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 * 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 // Guard against malformed diff.json: `before` is typed required but\n // the file is parsed without validation.\n if (change.before) {\n fields[fieldName] = convertFieldConfigToProto(change.before);\n }\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 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 * 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 { resolveTSConfig } from \"pkg-types\";\nimport * as rolldown from \"rolldown\";\nimport { getDistDir } from \"@/cli/shared/dist-dir\";\nimport { platformBundleDefinePlugin } from \"@/cli/shared/platform-bundle-plugin\";\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 TestExecScript\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 * @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): Promise<MigrationBundleResult> {\n // Output directory in .tailor-sdk (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 let tsconfig: string | undefined;\n try {\n tsconfig = await resolveTSConfig();\n } catch {\n tsconfig = undefined;\n }\n\n // Bundle with tree-shaking (write: false to avoid unnecessary disk I/O)\n const result = await rolldown.build({\n plugins: [platformBundleDefinePlugin],\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 logLevel: \"silent\",\n } as rolldown.BuildOptions);\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 * Types for TailorDB migration execution\n */\n\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 */\nexport const 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// ============================================================================\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 const num = parseInt(numStr, 10);\n return isNaN(num) ? null : num;\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// 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 | \"field_missing_remote\"\n | \"field_missing_local\"\n | \"field_mismatch\";\n\n/**\n * Single schema drift item\n */\nexport interface SchemaDrift {\n typeName: string;\n kind: SchemaDriftKind;\n fieldName?: string;\n details: 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}\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-proto/tailor/v1/function_resource_pb\";\nimport type { OperatorClient } from \"@/cli/shared/client\";\nimport type { AuthInvoker } from \"@tailor-proto/tailor/v1/auth_resource_pb\";\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 {\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 string argument to pass to the script */\n arg?: string;\n /** Auth invoker for script execution */\n invoker: AuthInvoker;\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 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(\n options: ScriptExecutionOptions,\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: arg ?? JSON.stringify({}),\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 { 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(FRAMES[this.#frame] ?? FRAMES[0]!);\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(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(`${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 { AuthInvokerSchema, type AuthInvoker } from \"@tailor-proto/tailor/v1/auth_resource_pb\";\nimport { bundleMigrationScript } from \"@/cli/commands/tailordb/migrate/bundler\";\nimport { type NamespaceWithMigrations } from \"@/cli/commands/tailordb/migrate/config\";\nimport {\n loadDiff,\n getMigrationFiles,\n getMigrationFilePath,\n formatMigrationNumber,\n} from \"@/cli/commands/tailordb/migrate/snapshot\";\nimport {\n type PendingMigration,\n MIGRATION_LABEL_KEY,\n parseMigrationLabelNumber,\n} from \"@/cli/commands/tailordb/migrate/types\";\nimport { 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 } 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 authInvoker: AuthInvoker;\n env: Record<string, string | number | boolean>;\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}\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 {\n return 0;\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 * @returns {Promise<PendingMigration[]>} List of pending migrations\n */\nexport async function detectPendingMigrations(\n client: OperatorClient,\n workspaceId: string,\n namespacesWithMigrations: NamespaceWithMigrations[],\n): Promise<PendingMigration[]> {\n const pendingMigrations: PendingMigration[] = [];\n\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n // Get current applied migration number\n const currentMigration = 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 still hard-require a script; warnings (e.g. field_removed)\n // may 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) {\n logger.warn(\n `Migration ${namespace}/${file.number} requires a script but migrate.ts not found`,\n );\n continue;\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, authInvoker, env } = 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 );\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: authInvoker,\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 * @returns {Promise<void>}\n */\nexport async function updateMigrationLabel(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n migrationNumber: number,\n): Promise<void> {\n const trn = resourceTrn(workspaceId, \"tailordb\", namespace);\n\n // Get existing metadata\n const { metadata } = await client.getMetadata({ trn });\n const existingLabels = metadata?.labels ?? {};\n\n const newLabel = `m${formatMigrationNumber(migrationNumber)}`;\n\n // Update with new migration label\n await client.setMetadata({\n trn,\n labels: {\n ...existingLabels,\n [MIGRATION_LABEL_KEY]: newLabel,\n },\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 // Create authInvoker for this namespace\n const authInvoker = create(AuthInvokerSchema, {\n namespace: context.authNamespace,\n machineUserName,\n });\n\n const options: MigrationExecutionOptions = {\n client: context.client,\n workspaceId: context.workspaceId,\n authInvoker,\n env: context.env,\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 { fromJson, type MessageInitShape } from \"@bufbuild/protobuf\";\nimport { ValueSchema } from \"@bufbuild/protobuf/wkt\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\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-proto/tailor/v1/tailordb_pb\";\nimport {\n TailorDBGQLPermission_Action,\n type TailorDBGQLPermission_ConditionSchema,\n type TailorDBGQLPermission_OperandSchema,\n TailorDBGQLPermission_Operator,\n TailorDBGQLPermission_Permit,\n type TailorDBGQLPermission_PolicySchema,\n type TailorDBGQLPermissionSchema,\n type TailorDBType as ProtoTailorDBType,\n type TailorDBTypeSchema,\n} from \"@tailor-proto/tailor/v1/tailordb_resource_pb\";\nimport * as path from \"pathe\";\nimport {\n getNamespacesWithMigrations,\n type NamespaceWithMigrations,\n} from \"@/cli/commands/tailordb/migrate/config\";\nimport {\n hasChanges,\n formatMigrationDiff,\n formatDiffSummary,\n type MigrationDiff,\n} from \"@/cli/commands/tailordb/migrate/diff-calculator\";\nimport {\n applyPreMigrationFieldAdjustments,\n buildPreMigrationChangesMap,\n} from \"@/cli/commands/tailordb/migrate/pre-migration-schema\";\nimport {\n reconstructSnapshotFromMigrations,\n compareLocalTypesWithSnapshot,\n assertValidMigrationFiles,\n formatMigrationNumber,\n compareRemoteWithSnapshot,\n formatSchemaDrifts,\n createSnapshotType,\n getLatestMigrationNumber,\n getMigrationFiles,\n isSnapshotFieldRefOperand,\n type SchemaSnapshot,\n type TailorDBSnapshotType,\n type SnapshotPermissionCondition,\n type SnapshotPermissionOperand,\n type SnapshotGqlPermission,\n type SnapshotGqlPermissionPolicy,\n} from \"@/cli/commands/tailordb/migrate/snapshot\";\nimport { generateTailorDBTypeManifestFromSnapshot } from \"@/cli/commands/tailordb/migrate/snapshot-manifest\";\nimport { type TailorDBService } from \"@/cli/services/tailordb/service\";\nimport { fetchAll, type OperatorClient } from \"@/cli/shared/client\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { createChangeSet, type HasName, type ChangeSet } from \"../change-set\";\nimport { areNormalizedEqual, normalizeProtoConfig } from \"../compare\";\nimport { ACTION_SYMBOLS, type DisplayAction, type GroupedDisplayEntry } from \"../grouped-display\";\nimport {\n buildMetaRequest,\n hasMatchingSdkVersion,\n isOwnedByApp,\n resourceTrn,\n sdkNameLabelKey,\n type WithLabel,\n} from \"../label\";\nimport {\n executeMigrations,\n detectPendingMigrations,\n updateMigrationLabel,\n type MigrationContext,\n} from \"./migration\";\nimport type { OwnerConflict, UnmanagedResource } from \"../confirm\";\nimport type { ApplyPhase, PlanContext } from \"../types\";\nimport type {\n PendingMigration,\n RemoteSchemaVerificationResult,\n} from \"@/cli/commands/tailordb/migrate/types\";\nimport type { LoadedConfig } from \"@/cli/shared/config-loader\";\nimport type { TailorDBServiceConfig } from \"@/types/tailordb.generated\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\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 fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { tailordbTypes, nextPageToken } = await client.listTailorDBTypes({\n workspaceId,\n namespaceName: namespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbTypes, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n}\n\n/**\n * Get the current migration number from remote metadata\n * @param {OperatorClient} client - Operator client instance\n * @param {string} workspaceId - Workspace ID\n * @param {string} namespace - TailorDB namespace\n * @returns {Promise<number | null>} Current migration number, or null if no migration label exists\n */\nasync function getRemoteMigrationNumber(\n client: OperatorClient,\n workspaceId: string,\n namespace: string,\n): Promise<number | null> {\n try {\n const trn = resourceTrn(workspaceId, \"tailordb\", namespace);\n const { metadata } = await client.getMetadata({ trn });\n const label = metadata?.labels?.[\"sdk-migration\"];\n if (!label) return null; // No migration label means first apply\n const match = label.match(/^m(\\d+)$/);\n return match ? parseInt(match[1], 10) : null;\n } catch {\n return null;\n }\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 * @returns {Promise<RemoteSchemaVerificationResult[]>} Verification results per namespace\n */\nasync function verifyRemoteSchema(\n client: OperatorClient,\n workspaceId: string,\n namespacesWithMigrations: NamespaceWithMigrations[],\n): Promise<RemoteSchemaVerificationResult[]> {\n const results: RemoteSchemaVerificationResult[] = [];\n\n for (const { namespace, migrationsDir } of namespacesWithMigrations) {\n // Get current remote migration number\n const remoteMigrationNumber = await getRemoteMigrationNumber(client, workspaceId, namespace);\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 });\n continue;\n }\n\n // Reconstruct snapshot at the remote migration version\n const expectedSnapshot = reconstructSnapshotFromMigrations(\n migrationsDir,\n remoteMigrationNumber,\n );\n if (!expectedSnapshot) {\n // No snapshots exist - skip verification\n results.push({\n namespace,\n remoteMigrationNumber,\n drifts: [],\n hasDrift: false,\n });\n continue;\n }\n\n // Fetch remote types\n const remoteTypes = await fetchRemoteTypes(client, workspaceId, namespace);\n\n // Compare remote with expected snapshot\n const drifts = compareRemoteWithSnapshot(remoteTypes, expectedSnapshot);\n\n results.push({\n namespace,\n remoteMigrationNumber,\n drifts,\n hasDrift: drifts.length > 0,\n });\n }\n\n return results;\n}\n\n/**\n * Format remote schema verification results for display\n * @param {RemoteSchemaVerificationResult[]} results - Verification results\n * @returns {string} Formatted results string\n */\nfunction 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// Migration Validation\n// ============================================================================\n\ntype ValidateAndDetectResult = {\n pendingMigrations: PendingMigration[];\n namespacesWithMigrations: NamespaceWithMigrations[];\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 * @returns {Promise<ValidateAndDetectResult>} Pending migrations and namespaces that have migration directories configured\n */\nasync function validateAndDetectMigrations(\n client: OperatorClient,\n workspaceId: string,\n typesByNamespace: ReadonlyMap<string, Record<string, TailorDBSnapshotType>>,\n config: LoadedConfig,\n noSchemaCheck: boolean,\n): Promise<ValidateAndDetectResult> {\n const configDir = path.dirname(config.path);\n const namespacesWithMigrations = getNamespacesWithMigrations(config, configDir);\n let pendingMigrations: PendingMigration[] = [];\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 }\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-sdk 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 );\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 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(\"Use '--no-schema-check' to skip this check (not recommended).\");\n throw new Error(\"Remote schema verification failed\");\n }\n }\n\n // Detect pending migrations (migration scripts that haven't been executed yet)\n pendingMigrations = await detectPendingMigrations(\n client,\n workspaceId,\n namespacesWithMigrations,\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(`Applying ${pendingMigrations.length} migration(s):`);\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 { pendingMigrations, namespacesWithMigrations };\n}\n\n/**\n * Force each namespace's `sdk-migration` label to the working tree's latest\n * migration number 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 */\nasync function reconcileMigrationLabels(\n client: OperatorClient,\n workspaceId: string,\n namespacesWithMigrations: NamespaceWithMigrations[],\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 currentVersion = await getRemoteMigrationNumber(client, workspaceId, namespace);\n if (currentVersion === targetVersion) {\n continue;\n }\n await updateMigrationLabel(client, workspaceId, namespace, targetVersion);\n const from = currentVersion === null ? \"<unset>\" : formatMigrationNumber(currentVersion);\n logger.info(\n `Migration label for namespace ${namespace} reconciled: ${from} → ${formatMigrationNumber(targetVersion)}.`,\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 };\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 // Validate and detect migrations\n // Build types by namespace map (snapshot-shaped, the canonical deploy form)\n const typesByNamespace = new Map<string, Record<string, TailorDBSnapshotType>>();\n for (const tailordb of migrationContext.tailorDBInputs) {\n typesByNamespace.set(tailordb.namespace, tailordb.types);\n }\n\n const { pendingMigrations, namespacesWithMigrations } = await validateAndDetectMigrations(\n client,\n migrationContext.workspaceId,\n typesByNamespace,\n migrationContext.config,\n migrationContext.noSchemaCheck,\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 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 // 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\n // Post-migration phase: Apply final types (required: true) and deletions\n await executeSingleMigrationPostPhase(\n client,\n changeSet,\n migration,\n migrationContext.tailorDBInputs,\n migrationContext.executorUsedTypes,\n );\n\n // Update migration label only after all phases complete successfully\n await updateMigrationLabel(\n client,\n migrationContext.workspaceId,\n migration.namespace,\n migration.number,\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 } 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 client.setMetadata(create.metaRequest);\n }),\n ...changeSet.service.updates.map((update) => client.setMetadata(update.metaRequest)),\n ]);\n\n // Types\n try {\n await Promise.all([\n ...changeSet.type.creates.map((create) => client.createTailorDBType(create.request)),\n ...changeSet.type.updates.map((update) => client.updateTailorDBType(update.request)),\n ]);\n } catch (error) {\n handleOptionalToRequiredError(error, [\n \"Run 'tailor-sdk 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 );\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 if (phase === \"delete-services\") {\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 * 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 */\nfunction 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// 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 client.setMetadata(create.metaRequest);\n }),\n ...changeSet.service.updates.map((update) => client.setMetadata(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\n/**\n * Build the TailorDBType manifest for `typeName` from migration N's snapshot.\n * @param migration - The pending migration whose snapshot to consult\n * @param typeName - The type name to look up in the snapshot\n * @param tailorDBInputs - Deploy inputs, used to resolve namespace gqlOperations\n * @param executorUsedTypes - Types used by executors (drives publishRecordEvents default)\n * @returns The manifest, or undefined if `typeName` is not in that snapshot.\n */\nfunction buildSnapshotTypeManifest(\n migration: PendingMigration,\n typeName: string,\n tailorDBInputs: ReadonlyArray<TailorDBDeployInput>,\n executorUsedTypes: ReadonlySet<string>,\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 return generateTailorDBTypeManifestFromSnapshot(snapshotType, {\n publishRecordEvents: executorUsedTypes.has(snapshotType.name),\n namespaceGqlOperations: input?.config.gqlOperations,\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 map 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.\n const preMigrationChanges = buildPreMigrationChangesMap([migration]);\n const affectedTypes = getAffectedTypeNames(migration);\n const createdBeforeMigration = new Set(processedTypes.created);\n\n await Promise.all([\n ...changeSet.type.creates\n .filter((create) => {\n const typeName = create.request.tailordbType?.name;\n return typeName && affectedTypes.has(typeName) && !createdBeforeMigration.has(typeName);\n })\n .map((create) => {\n const typeName = create.request.tailordbType?.name;\n const snapshotType = typeName\n ? buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes)\n : undefined;\n if (!snapshotType) return undefined;\n if (typeName) processedTypes.created.add(typeName);\n\n const clonedRequest = structuredClone(create.request);\n clonedRequest.tailordbType = snapshotType;\n\n const typeChanges = typeName ? preMigrationChanges.get(typeName) : undefined;\n if (typeChanges && typeChanges.size > 0 && clonedRequest.tailordbType?.schema?.fields) {\n applyPreMigrationFieldAdjustments(clonedRequest.tailordbType.schema.fields, typeChanges);\n }\n\n return client.createTailorDBType(clonedRequest);\n }),\n // Update types already created in previous migrations (from create list)\n ...changeSet.type.creates\n .filter((create) => {\n const typeName = create.request.tailordbType?.name;\n return typeName && affectedTypes.has(typeName) && createdBeforeMigration.has(typeName);\n })\n .map((create) => {\n const typeName = create.request.tailordbType?.name;\n const snapshotType = typeName\n ? buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes)\n : undefined;\n if (!snapshotType) return undefined;\n if (typeName) processedTypes.updated.add(typeName);\n\n const clonedTypeRequest = structuredClone(snapshotType);\n const typeChanges = typeName ? preMigrationChanges.get(typeName) : undefined;\n if (typeChanges && typeChanges.size > 0 && clonedTypeRequest.schema?.fields) {\n applyPreMigrationFieldAdjustments(clonedTypeRequest.schema.fields, typeChanges);\n }\n\n return client.updateTailorDBType({\n workspaceId: create.request.workspaceId,\n namespaceName: create.request.namespaceName,\n tailordbType: clonedTypeRequest,\n });\n }),\n // Update types that are affected by this migration\n ...changeSet.type.updates\n .filter((update) => {\n const typeName = update.request.tailordbType?.name;\n return typeName && affectedTypes.has(typeName);\n })\n .map((update) => {\n const typeName = update.request.tailordbType?.name;\n const snapshotType = typeName\n ? buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes)\n : undefined;\n if (!snapshotType) return undefined;\n if (typeName) processedTypes.updated.add(typeName);\n\n const clonedRequest = structuredClone(update.request);\n clonedRequest.tailordbType = snapshotType;\n\n const typeChanges = typeName ? preMigrationChanges.get(typeName) : undefined;\n if (typeChanges && typeChanges.size > 0 && clonedRequest.tailordbType?.schema?.fields) {\n applyPreMigrationFieldAdjustments(clonedRequest.tailordbType.schema.fields, typeChanges);\n }\n\n return client.updateTailorDBType(clonedRequest);\n }),\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 await Promise.all(\n missingTypeCreates.map((create) => {\n const typeName = create.request.tailordbType?.name;\n if (typeName) processedTypes.created.add(typeName);\n return client.createTailorDBType(create.request);\n }),\n );\n }\n processedTypes.gqlPermissionsProcessed.add(migration.namespace);\n await Promise.all([\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\n/**\n * Execute post-migration phase for a single migration: Apply final types (with required: true) and deletions\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 map 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 affectedTypes = getAffectedTypeNames(migration);\n const deletedTypeNames = getDeletedTypeNames(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 await Promise.all([\n // For newly created types that had pre-migration adjustments in this migration, send update with snapshot[N] values\n ...changeSet.type.creates\n .filter((create) => {\n const typeName = create.request.tailordbType?.name;\n return typeName && affectedTypes.has(typeName) && preMigrationChanges.has(typeName);\n })\n .map((create) => {\n const typeName = create.request.tailordbType?.name;\n const snapshotType = typeName\n ? buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes)\n : undefined;\n if (!snapshotType) return undefined;\n return client.updateTailorDBType({\n workspaceId: create.request.workspaceId,\n namespaceName: create.request.namespaceName,\n tailordbType: snapshotType,\n });\n }),\n // For updated types affected by this migration, send update with snapshot[N] values\n ...changeSet.type.updates\n .filter((update) => {\n const typeName = update.request.tailordbType?.name;\n return typeName && affectedTypes.has(typeName) && preMigrationChanges.has(typeName);\n })\n .map((update) => {\n const typeName = update.request.tailordbType?.name;\n const snapshotType = typeName\n ? buildSnapshotTypeManifest(migration, typeName, tailorDBInputs, executorUsedTypes)\n : undefined;\n if (!snapshotType) return undefined;\n return client.updateTailorDBType({\n workspaceId: update.request.workspaceId,\n namespaceName: update.request.namespaceName,\n tailordbType: snapshotType,\n });\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 // Delete types that are removed in this migration\n if (deletedTypeNames.size > 0) {\n // First delete GQL permissions for the types being deleted\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 // Check if this permission is for a type being deleted in this migration\n // del.name and del.request.typeName both hold the type name\n const typeName = del.name;\n if (typeName && deletedTypeNames.has(typeName)) {\n deletedResources.gqlPermissions.add(permKey);\n return true;\n }\n return false;\n });\n await Promise.all(\n gqlPermissionsToDelete.map((del) => client.deleteTailorDBGQLPermission(del.request)),\n );\n\n // Then delete the types\n const typesToDelete = changeSet.type.deletes.filter((del) => {\n // del.name and del.request.tailordbTypeName both hold the type name\n const typeName = del.name;\n if (!typeName || deletedResources.types.has(typeName)) return false;\n if (deletedTypeNames.has(typeName)) {\n deletedResources.types.add(typeName);\n return true;\n }\n return false;\n });\n await Promise.all(typesToDelete.map((del) => client.deleteTailorDBType(del.request)));\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 */\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 */\ntype 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 */\nfunction 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\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 if (!forRemoval) {\n for (const tailordb of application.tailorDBServices) {\n await tailordb.loadTypes();\n tailordbs.push(toTailorDBDeployInput(tailordb));\n }\n }\n const executors = forRemoval\n ? []\n : Object.values((await application.executorService?.loadExecutors()) ?? {});\n const executorUsedTypes = new Set<string>();\n for (const executor of executors) {\n if (executor.trigger.kind === \"tailordb\") {\n executorUsedTypes.add(executor.trigger.typeName);\n }\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 planGqlPermissions(client, workspaceId, tailordbs, deletedServices, forceApplyAll),\n ]);\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 },\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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateService = {\n name: string;\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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 withoutLabel = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { tailordbServices, nextPageToken } = await client.listTailorDBServices({\n workspaceId,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbServices, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n const existingServices: WithLabel<(typeof withoutLabel)[number]> = {};\n await Promise.all(\n withoutLabel.map(async (resource) => {\n if (!resource.namespace?.name) {\n return;\n }\n const { metadata } = await client.getMetadata({\n trn: resourceTrn(workspaceId, \"tailordb\", resource.namespace.name),\n });\n existingServices[resource.namespace.name] = {\n resource,\n label: metadata?.labels[sdkNameLabelKey],\n allLabels: metadata?.labels,\n };\n }),\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 existingLabels: existing?.allLabels,\n });\n if (existing) {\n const owned = isOwnedByApp(existing.allLabels, appName, appId);\n if (!owned) {\n if (!existing.label) {\n unmanaged.push({\n resourceType: \"TailorDB service\",\n resourceName: tailordb.namespace,\n });\n } else {\n conflicts.push({\n resourceType: \"TailorDB service\",\n resourceName: tailordb.namespace,\n currentOwner: existing.label,\n });\n }\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 // Set UTC to match tailorctl/terraform\n defaultTimezone: \"UTC\",\n },\n metaRequest,\n });\n }\n }\n Object.entries(existingServices).forEach(([namespaceName]) => {\n const entry = existingServices[namespaceName];\n const label = entry?.label;\n const owned = isOwnedByApp(entry?.allLabels, appName, appId);\n if (label && !owned) {\n resourceOwners.add(label);\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};\n\ntype UpdateType = {\n name: string;\n request: MessageInitShape<typeof UpdateTailorDBTypeRequestSchema>;\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) {\n const changeSet = createChangeSet<CreateType, UpdateType, DeleteType>(\"TailorDB types\");\n\n const fetchTypes = (namespaceName: string) => {\n return fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { tailordbTypes, nextPageToken } = await client.listTailorDBTypes({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbTypes, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n };\n\n // Validate that types used by executors don't have publishEvents explicitly set to false\n for (const tailordb of tailordbs) {\n const types = filteredTypesByNamespace?.get(tailordb.namespace) ?? tailordb.types;\n for (const typeName of Object.keys(types)) {\n const type = types[typeName];\n if (executorUsedTypes.has(typeName) && type.settings?.publishEvents === false) {\n throw new Error(\n `Type \"${typeName}\" has publishEvents set to false, but it is used by an executor with a record trigger. ` +\n `Either remove the publishEvents: false setting or remove the executor trigger for this type.`,\n );\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\n for (const typeName of Object.keys(types)) {\n const tailordbType = generateTailorDBTypeManifestFromSnapshot(types[typeName], {\n publishRecordEvents: 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 changeSet.unchanged.push({ name: typeName });\n } else {\n changeSet.updates.push({\n name: typeName,\n request: {\n workspaceId,\n namespaceName: tailordb.namespace,\n tailordbType,\n },\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 });\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: unknown) {\n const normalized = normalizeProtoConfig(type) 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 };\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 },\n },\n [],\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 === \"number\" || typeof value === \"bigint\" || typeof value === \"string\") {\n if (matchesNumericStringPath(path) && isNumericLikeValue(value)) {\n return String(value);\n }\n // Platform returns an empty string for `expr` (validate scripts) and field/type\n // `description` when the SDK omitted them, while local manifests omit the key\n // entirely. Treat the empty string as unset so it matches an omitted value.\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 return value\n .map((item, index) => normalizeTailorDBCompareValue(item, [...path, index]))\n .filter((item) => item !== undefined);\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 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 fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { permissions, nextPageToken } = await client.listTailorDBGQLPermissions({\n workspaceId,\n namespaceName,\n pageToken,\n pageSize: maxPageSize,\n });\n return [permissions, nextPageToken];\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n return [[], \"\"];\n }\n throw error;\n }\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 of Object.keys(types)) {\n const gqlPermission = types[typeName].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\nfunction 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// ============================================================================\n// Migration Integration\n// ============================================================================\n\ninterface 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 */\nasync 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 // Try to reconstruct snapshot from migrations\n let previousSnapshot;\n try {\n previousSnapshot = reconstructSnapshotFromMigrations(migrationsDir);\n } catch {\n // No migrations directory - this is fine, no check needed\n results.push({\n namespace,\n migrationsDir,\n hasDiff: false,\n });\n continue;\n }\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 */\nfunction 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(\n \" No migration snapshot found. Run 'tailor-sdk tailordb migration generate' first.\",\n );\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","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 { 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 { buildMetaRequest, hasMatchingSdkVersion, isOwnedByApp, resourceTrn } from \"./label\";\nimport {\n fetchExistingResourcesWithLabels,\n trackDesiredResourceOwnership,\n trackRemainingResourceOwner,\n} from \"./owned-resource\";\nimport type { OwnerConflict, UnmanagedResource } from \"./confirm\";\nimport type { ApplyPhase } from \"./phase\";\nimport type { ConcurrencyPolicy, Workflow, RetryPolicy } from \"@/types/workflow.generated\";\nimport type { MessageInitShape } from \"@bufbuild/protobuf\";\nimport type { SetMetadataRequestSchema } from \"@tailor-proto/tailor/v1/metadata_pb\";\nimport type {\n ConcurrencyPolicySchema,\n RetryPolicySchema,\n} from \"@tailor-proto/tailor/v1/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 );\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 await client.createWorkflow({\n workspaceId: create.workspaceId,\n workflowName: create.workflow.name,\n mainJobFunctionName: create.workflow.mainJob.name,\n jobFunctions: filteredVersions,\n ...(create.workflow.retryPolicy && {\n retryPolicy: toRetryPolicy(create.workflow.retryPolicy),\n }),\n ...(create.workflow.concurrencyPolicy && {\n concurrencyPolicy: toConcurrencyPolicy(create.workflow.concurrencyPolicy),\n }),\n });\n await client.setMetadata(create.metaRequest);\n }),\n ...changeSet.updates.map(async (update) => {\n const filteredVersions = filterJobFunctionVersions(\n jobFunctionVersions,\n update.usedJobNames,\n );\n await client.updateWorkflow({\n workspaceId: update.workspaceId,\n workflowName: update.workflow.name,\n mainJobFunctionName: update.workflow.mainJob.name,\n jobFunctions: filteredVersions,\n ...(update.workflow.retryPolicy && {\n retryPolicy: toRetryPolicy(update.workflow.retryPolicy),\n }),\n ...(update.workflow.concurrencyPolicy && {\n concurrencyPolicy: toConcurrencyPolicy(update.workflow.concurrencyPolicy),\n }),\n });\n await client.setMetadata(update.metaRequest);\n }),\n ]);\n } else if (phase === \"delete\") {\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 ?? collectDeletableJobFunctions(changeSet.deletes)).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 = operations[index];\n const error = result.reason;\n if (!operation) {\n errors.push(error);\n return;\n }\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\nfunction collectDeletableJobFunctions(deletes: readonly DeleteWorkflow[]) {\n const seen = new Set<string>();\n const jobFunctions: Array<{ workspaceId: string; jobFunctionName: string }> = [];\n for (const del of deletes) {\n for (const jobFunctionName of del.deletableJobNames) {\n const key = `${del.workspaceId}\\0${jobFunctionName}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n jobFunctions.push({ workspaceId: del.workspaceId, jobFunctionName });\n }\n }\n return jobFunctions;\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\n * @param unchangedWorkflowJobNames - Job function names used by unchanged workflows\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): 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 response = isExisting\n ? await client.updateWorkflowJobFunction({\n workspaceId,\n jobFunctionName: jobName,\n scriptRef: workflowJobFunctionName(jobName),\n })\n : await client.createWorkflowJobFunction({\n workspaceId,\n jobFunctionName: jobName,\n scriptRef: workflowJobFunctionName(jobName),\n });\n\n // Set metadata to mark this JobFunction as owned by this app\n await client.setMetadata(\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: MessageInitShape<typeof SetMetadataRequestSchema>;\n};\n\ntype UpdateWorkflow = {\n name: string;\n workspaceId: string;\n workflow: Workflow;\n usedJobNames: string[];\n metaRequest: MessageInitShape<typeof SetMetadataRequestSchema>;\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/**\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\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 * @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) {\n const changeSet = createChangeSet<CreateWorkflow, UpdateWorkflow, DeleteWorkflow>(\"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 existingWorkflows = await fetchExistingResourcesWithLabels({\n client,\n workspaceId,\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: (workspaceId, name) => resourceTrn(workspaceId, \"workflow\", name),\n });\n\n for (const workflow of Object.values(workflows)) {\n const existing = existingWorkflows[workflow.name];\n const metaRequest = await buildMetaRequest({\n trn: resourceTrn(workspaceId, \"workflow\", workflow.name),\n appName,\n appId,\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 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.resource,\n workflow,\n usedJobNames,\n unchangedJobFunctions,\n )\n ) {\n changeSet.unchanged.push({ name: workflow.name });\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,\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,\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 retainedWorkflowJobNames,\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 };\n}\n\ntype PlanWorkflowJobFunctionDeletesParams = {\n client: OperatorClient;\n workspaceId: string;\n appName: string;\n appId: string | undefined;\n retainedWorkflowJobNames: ReadonlySet<string>;\n};\n\nasync function planWorkflowJobFunctionDeletes(\n params: PlanWorkflowJobFunctionDeletesParams,\n): Promise<DeleteWorkflowJobFunction[]> {\n const { client, workspaceId, appName, appId, retainedWorkflowJobNames } = params;\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((jobFunction) => jobFunction.name), response.nextPageToken];\n });\n const candidates = [...new Set(existingJobFunctions)].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 return isOwnedByApp(metadata?.labels, appName, appId)\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\nfunction canTreatWorkflowAsUnchanged(\n existing: {\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 },\n workflow: Workflow,\n usedJobNames: string[],\n unchangedJobFunctions: ReadonlySet<string>,\n) {\n if (!usedJobNames.every((jobName) => unchangedJobFunctions.has(jobName))) {\n return false;\n }\n return areWorkflowsEqual(existing, workflow, usedJobNames);\n}\n\nfunction areWorkflowsEqual(\n existing: {\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 },\n workflow: Workflow,\n usedJobNames: readonly string[],\n) {\n return (\n existing.mainJobFunctionName === workflow.mainJob.name &&\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 * as fs from \"node:fs\";\nimport { Code, ConnectError } from \"@connectrpc/connect\";\nimport { findUpSync } from \"find-up-simple\";\nimport * as path from \"pathe\";\nimport { hashFile } from \"@/cli/cache/hasher\";\nimport { createCacheManager } from \"@/cli/cache/manager\";\nimport { loadApplication, type Application } from \"@/cli/services/application\";\nimport { assertUniqueTailorDBTypeNamesWithExternal } from \"@/cli/services/tailordb/type-name-validation\";\nimport { initOperatorClient, type OperatorClient } from \"@/cli/shared/client\";\nimport { loadConfig } from \"@/cli/shared/config-loader\";\nimport { loadAccessToken, loadConfigPath, loadWorkspaceId } 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 { generateUserTypes } from \"@/cli/shared/type-generator\";\nimport { withSpan } from \"@/cli/telemetry\";\nimport { PluginManager } from \"@/plugin/manager\";\nimport { applyApplication, planApplication } from \"./application\";\nimport { applyAuth, formatAuthHookChangeEntries, planAuth } from \"./auth\";\nimport {\n formatPlanSummary,\n summarizeChangeSets,\n type HasName,\n type PlanSummary,\n} from \"./change-set\";\nimport { ensureConfigId } from \"./config-id-injector\";\nimport {\n confirmImportantResourceDeletion,\n confirmOwnerConflict,\n confirmUnmanagedResources,\n type ImportantResourceDeletion,\n type OwnerConflict,\n type UnmanagedResource,\n} from \"./confirm\";\nimport {\n applyExecutor,\n buildPlannedExecutorsByName,\n formatExecutorChangeEntries,\n planExecutor,\n} from \"./executor\";\nimport {\n applyFunctionRegistry,\n collectFunctionEntries,\n filterBundledWorkflowJobs,\n planFunctionRegistry,\n splitFunctionRegistryChanges,\n WORKFLOW_PREFIX,\n} from \"./function-registry\";\nimport {\n extractServiceActions,\n formatChangeSetEntries,\n printGroupedDisplaySection,\n type GroupedDisplayEntry,\n type NamespaceAction,\n} from \"./grouped-display\";\nimport { applyIdP, planIdP } from \"./idp\";\nimport { buildMetaRequest, hasMatchingSdkVersion, resourceTrn, sdkNameLabelKey } from \"./label\";\nimport { applyPipeline, formatResolverChangeEntries, planPipeline } from \"./resolver\";\nimport { applySecretManager, planSecretManager } from \"./secret-manager\";\nimport { applyStaticWebsite, planStaticWebsite } from \"./staticwebsite\";\nimport { applyTailorDB, formatTailorDBResourceChangeEntries, planTailorDB } from \"./tailordb\";\nimport { applyWorkflow, formatWorkflowChangeEntries, planWorkflow } from \"./workflow\";\nimport type { PlanContext } 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 noCache?: boolean;\n cleanCache?: boolean;\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\n/**\n * Resolve the set of IdP names that have at least one executor subscribed to\n * their user events. When an executor's idpUser trigger omits the `idp` option\n * and exactly one IdP is configured, that IdP is implicitly the target.\n * Executors that omit `idp` while multiple IdPs exist are skipped here; the\n * apply pipeline throws a clearer error for them later.\n * @param application - Loaded application\n * @returns Set of IdP names targeted by idpUser triggers\n */\nfunction collectIdpUserTriggerTargets(application: Readonly<Application>): ReadonlySet<string> {\n const targets = new Set<string>();\n const idps = application.idpServices;\n for (const executor of Object.values(application.executorService?.executors ?? {})) {\n if (executor.trigger.kind !== \"idpUser\") {\n continue;\n }\n if (executor.trigger.idp != null) {\n targets.add(executor.trigger.idp);\n } else if (idps.length === 1) {\n targets.add(idps[0].name);\n }\n }\n return targets;\n}\n\nasync 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.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 for (const trn of candidateTrns) {\n try {\n const { metadata } = await client.getMetadata({ trn });\n if (metadata?.labels?.[sdkNameLabelKey] !== application.name) {\n continue;\n }\n if (!hasMatchingSdkVersion(metadata.labels, desiredLabels)) {\n return true;\n }\n } catch (error) {\n if (error instanceof ConnectError && error.code === Code.NotFound) {\n continue;\n }\n throw error;\n }\n }\n\n return false;\n}\n\n/**\n * Decide which renamed-away applications should be deleted. Excludes the\n * target itself: id regeneration alone keeps the name unchanged, so deleting\n * by name would destroy the 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.targetAppName - The application currently being deployed\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 targetAppName: string;\n}): string[] {\n const { conflicts, resourceOwners, targetAppName } = params;\n const conflictOwners = new Set(conflicts.map((c) => c.currentOwner));\n return [...conflictOwners].filter(\n (owner) => !resourceOwners.has(owner) && owner !== targetAppName,\n );\n}\n\ntype PlanResults = {\n functionRegistry: Awaited<ReturnType<typeof planFunctionRegistry>>;\n tailorDB: Awaited<ReturnType<typeof planTailorDB>>;\n staticWebsite: Awaited<ReturnType<typeof planStaticWebsite>>;\n idp: Awaited<ReturnType<typeof planIdP>>;\n auth: Awaited<ReturnType<typeof planAuth>>;\n pipeline: Awaited<ReturnType<typeof planPipeline>>;\n app: Awaited<ReturnType<typeof planApplication>>;\n executor: Awaited<ReturnType<typeof planExecutor>>;\n workflow: Awaited<ReturnType<typeof planWorkflow>>;\n secretManager: Awaited<ReturnType<typeof planSecretManager>>;\n};\n\nfunction printPlanResults(results: PlanResults) {\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 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 tailorDBEntries: GroupedDisplayEntry[] = [...tailorDBResourceEntries];\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 ...(results.auth.changeSet.connection\n ? formatChangeSetEntries(results.auth.changeSet.connection, [\"connection\"], namespaceOf)\n : []),\n ];\n\n // Print grouped sections\n const { otherChanges: otherFunctionRegistryChanges } = splitFunctionRegistryChanges(\n results.functionRegistry.changeSet,\n );\n printGroupedDisplaySection(\n results.functionRegistry.changeSet.title,\n formatChangeSetEntries(otherFunctionRegistryChanges),\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 results.staticWebsite.changeSet.print();\n results.staticWebsite.customDomainChangeSet.print();\n results.app.print();\n printGroupedDisplaySection(\"TailorDB\", tailorDBEntries, tailorDBServiceActions);\n printGroupedDisplaySection(\"Resolver\", pipelineEntries, pipelineServiceActions);\n printGroupedDisplaySection(\"Executor\", executorEntries);\n printGroupedDisplaySection(\"Workflow\", workflowEntries);\n printGroupedDisplaySection(\"IdP\", idpEntries, idpServiceActions);\n printGroupedDisplaySection(\"Auth\", authEntries, authServiceActions);\n results.secretManager.vaultChangeSet.print();\n results.secretManager.secretChangeSet.print();\n if (results.secretManager.skippedSecrets.length > 0) {\n logger.log(styles.bold(\"Secret Manager secrets (skipped - no value provided):\"));\n for (const name of results.secretManager.skippedSecrets) {\n logger.log(` ${styles.dim(\"○\")} ${name}`);\n }\n }\n\n // Compute summary: count display entries + service actions + non-grouped changesets\n const allDisplayEntries = [\n ...tailorDBEntries,\n ...pipelineEntries,\n ...executorEntries,\n ...workflowEntries,\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 logger.log(formatPlanSummary(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 = {\n create: 0,\n update: 0,\n delete: 0,\n replace: 0,\n unchanged: 0,\n };\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.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 * Deploy the configured application to the Tailor platform.\n * @param options - Options for deploy execution\n * @returns Promise that resolves to `{ bundledScripts }` when `buildOnly` is true, otherwise void\n */\nexport async function deploy(options?: DeployOptions) {\n return withSpan(\"deploy\", async (rootSpan) => {\n rootSpan.setAttribute(\"deploy.dry_run\", options?.dryRun ?? false);\n\n // Phase 0: Build\n const {\n config,\n application,\n workflowBuildResult,\n httpAdapterBuildResult,\n bundledScripts,\n buildOnly,\n } = await withSpan(\"build\", async () => {\n const dryRun = options?.dryRun ?? false;\n const buildOnly =\n options?.buildOnly ?? parseBoolean(process.env.TAILOR_PLATFORM_SDK_BUILD_ONLY) === true;\n\n const { config, plugins } = await withSpan(\"build.loadConfig\", async () => {\n const foundPath = loadConfigPath(options?.configPath);\n // Skip id injection in dry-run / build-only flows: those modes are\n // expected to have no on-disk side effects.\n if (foundPath && !dryRun && !buildOnly) {\n const resolvedPath = path.resolve(process.cwd(), foundPath);\n if (fs.existsSync(resolvedPath)) {\n await ensureConfigId(resolvedPath);\n }\n }\n return loadConfig(options?.configPath);\n });\n\n const noCache = options?.noCache ?? false;\n\n // Initialize cache manager\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 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: packageJson.version ?? \"unknown\",\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<\n ReturnType<typeof loadApplication>\n >[\"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 // Persist even on partial failure: successfully built bundles\n // are cached so the next run only rebuilds what failed.\n cacheManager.finalize();\n }\n\n return {\n config,\n plugins,\n application,\n workflowBuildResult,\n httpAdapterBuildResult,\n bundledScripts,\n dryRun,\n buildOnly,\n };\n });\n if (buildOnly) {\n return { bundledScripts };\n }\n\n // Note: the normal apply path intentionally skips writing bundle files to\n // .tailor-sdk/. 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 // Initialize client\n const accessToken = await loadAccessToken({\n useProfile: true,\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 rootSpan.setAttribute(\"app.name\", application.name);\n rootSpan.setAttribute(\"workspace.id\", workspaceId);\n\n await withSpan(\"plan.validateTailorDBTypeNames\", () =>\n assertUniqueTailorDBTypeNamesWithExternal({\n client,\n workspaceId,\n tailorDBServices: application.tailorDBServices,\n externalTailorDBNamespaces: application.externalTailorDBNamespaces,\n }),\n );\n\n // Collect function entries from in-memory bundled scripts (after build, before plan)\n const workflowService = application.workflowService;\n const bundledWorkflowJobs = filterBundledWorkflowJobs(\n workflowService?.jobs ?? [],\n workflowBuildResult?.usedJobNames ?? [],\n );\n const functionEntries = collectFunctionEntries(\n application,\n bundledWorkflowJobs,\n bundledScripts,\n );\n\n const dryRun = options?.dryRun ?? false;\n const yes = options?.yes ?? false;\n const forceApplyAll = await withSpan(\"plan.detectSdkVersionChange\", () =>\n shouldForceApplyAll(client, workspaceId, application, functionEntries),\n );\n\n // Phase 1: Plan\n const {\n functionRegistry,\n tailorDB,\n staticWebsite,\n idp,\n auth,\n pipeline,\n app,\n executor,\n workflow,\n secretManager,\n } = await withSpan(\"plan\", async () => {\n const idpUserTriggerTargets = collectIdpUserTriggerTargets(application);\n const ctx: PlanContext = {\n client,\n workspaceId,\n application,\n forRemoval: false,\n config,\n noSchemaCheck: options?.noSchemaCheck,\n forceApplyAll,\n idpUserTriggerTargets,\n };\n const functionRegistry = await withSpan(\"plan.functionRegistry\", () =>\n planFunctionRegistry(\n client,\n workspaceId,\n application.name,\n application.id,\n functionEntries,\n ),\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 [tailorDB, staticWebsite, idp, auth, pipeline, app, executor, workflow, secretManager] =\n await Promise.all([\n withSpan(\"plan.tailorDB\", () => planTailorDB(ctx)),\n withSpan(\"plan.staticWebsite\", () => planStaticWebsite(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 ),\n withSpan(\"plan.secretManager\", () => planSecretManager(ctx)),\n ]);\n return {\n functionRegistry,\n tailorDB,\n staticWebsite,\n idp,\n auth,\n pipeline,\n app,\n executor,\n workflow,\n secretManager,\n };\n });\n\n // Phase 1b: Confirm\n await withSpan(\"confirm\", async () => {\n const allConflicts: OwnerConflict[] = [\n ...functionRegistry.conflicts,\n ...tailorDB.conflicts,\n ...staticWebsite.conflicts,\n ...idp.conflicts,\n ...auth.conflicts,\n ...pipeline.conflicts,\n ...executor.conflicts,\n ...workflow.conflicts,\n ...secretManager.conflicts,\n ];\n await confirmOwnerConflict(allConflicts, application.name, yes);\n\n const allUnmanaged: UnmanagedResource[] = [\n ...functionRegistry.unmanaged,\n ...tailorDB.unmanaged,\n ...staticWebsite.unmanaged,\n ...idp.unmanaged,\n ...auth.unmanaged,\n ...pipeline.unmanaged,\n ...executor.unmanaged,\n ...workflow.unmanaged,\n ...secretManager.unmanaged,\n ];\n await confirmUnmanagedResources(allUnmanaged, application.name, yes);\n\n const importantDeletions: ImportantResourceDeletion[] = [];\n for (const del of tailorDB.changeSet.type.deletes) {\n importantDeletions.push({\n resourceType: \"TailorDB type\",\n resourceName: del.name,\n });\n }\n for (const del of staticWebsite.changeSet.deletes) {\n importantDeletions.push({\n resourceType: \"StaticWebsite\",\n resourceName: del.name,\n });\n }\n for (const del of auth.changeSet.oauth2Client.deletes) {\n importantDeletions.push({\n resourceType: \"OAuth2 client\",\n resourceName: del.name,\n });\n }\n for (const replace of 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 auth.changeSet.connection.deletes) {\n importantDeletions.push({\n resourceType: \"Auth connection\",\n resourceName: del.name,\n });\n }\n for (const del of secretManager.vaultChangeSet.deletes) {\n importantDeletions.push({\n resourceType: \"Secret Manager vault\",\n resourceName: del.name,\n });\n }\n for (const del of secretManager.secretChangeSet.deletes) {\n importantDeletions.push({\n resourceType: \"Secret Manager secret\",\n resourceName: del.name,\n });\n }\n await confirmImportantResourceDeletion(importantDeletions, yes);\n\n // Delete renamed applications\n const resourceOwners = new Set([\n ...functionRegistry.resourceOwners,\n ...tailorDB.resourceOwners,\n ...staticWebsite.resourceOwners,\n ...idp.resourceOwners,\n ...auth.resourceOwners,\n ...pipeline.resourceOwners,\n ...executor.resourceOwners,\n ...workflow.resourceOwners,\n ...secretManager.resourceOwners,\n ]);\n const emptyApps = computeRenamedAppDeletions({\n conflicts: allConflicts,\n resourceOwners,\n targetAppName: application.name,\n });\n for (const emptyApp of emptyApps) {\n app.deletes.push({\n name: emptyApp,\n request: {\n workspaceId,\n applicationName: emptyApp,\n },\n });\n }\n });\n\n printPlanResults({\n functionRegistry,\n tailorDB,\n staticWebsite,\n idp,\n auth,\n pipeline,\n app,\n executor,\n workflow,\n secretManager,\n });\n\n if (dryRun) {\n logger.info(\"Dry run enabled. No changes applied.\");\n return;\n }\n\n // Phase 2: Create/Update services that Application depends on\n await withSpan(\"apply.createUpdateServices\", async () => {\n await applySecretManager(client, secretManager, \"create-update\", application);\n await applyFunctionRegistry(client, workspaceId, functionRegistry, \"create-update\");\n await applyStaticWebsite(client, staticWebsite, \"create-update\");\n await applyIdP(client, idp, \"create-update\");\n await applyAuth(client, auth, \"create-update\");\n await applyTailorDB(client, tailorDB, \"create-update\");\n await applyPipeline(client, pipeline, \"create-update\");\n });\n\n // Phase 3: Delete subgraph resources (types, resolvers, etc.) before Application update\n await withSpan(\"apply.deleteSubgraphResources\", async () => {\n await applyPipeline(client, pipeline, \"delete-resources\");\n await applyAuth(client, auth, \"delete-resources\");\n await applyIdP(client, idp, \"delete-resources\");\n });\n\n // Phase 4: Create/Update Application\n await withSpan(\"apply.createUpdateApplication\", () =>\n applyApplication(client, app, \"create-update\"),\n );\n\n // Phase 5: Create/Update services that depend on Application\n await withSpan(\"apply.createUpdateDependentServices\", async () => {\n await applyExecutor(client, executor, \"create-update\");\n await applyWorkflow(client, workflow, \"create-update\");\n });\n\n // Phase 6: Delete services that depend on Application\n await withSpan(\"apply.deleteDependentServices\", async () => {\n await applyWorkflow(client, workflow, \"delete\");\n await applyExecutor(client, executor, \"delete\");\n await applyStaticWebsite(client, staticWebsite, \"delete\");\n await applySecretManager(client, secretManager, \"delete\");\n });\n\n // Phase 7: Delete Application\n await withSpan(\"apply.deleteApplication\", () => applyApplication(client, app, \"delete\"));\n\n // Phase 8: Delete subgraph services (after Application is deleted, no reference errors)\n await withSpan(\"apply.deleteSubgraphServices\", async () => {\n await applyPipeline(client, pipeline, \"delete-services\");\n await applyAuth(client, auth, \"delete-services\");\n await applyIdP(client, idp, \"delete-services\");\n await applyTailorDB(client, tailorDB, \"delete-services\");\n });\n\n // Phase 9: Delete unused function registry entries\n await withSpan(\"apply.cleanup\", () =>\n applyFunctionRegistry(client, workspaceId, functionRegistry, \"delete\"),\n );\n\n logger.success(\"Successfully applied changes.\");\n });\n}\n","import {\n ExecutorJobStatus,\n ExecutorTargetType,\n ExecutorTriggerType,\n} from \"@tailor-proto/tailor/v1/executor_resource_pb\";\nimport { FunctionExecution_Status } from \"@tailor-proto/tailor/v1/function_resource_pb\";\nimport { styles } from \"@/cli/shared/logger\";\n\n// ============================================================================\n// Executor Job Status\n// ============================================================================\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 (\n status === ExecutorJobStatus.SUCCESS ||\n status === ExecutorJobStatus.FAILED ||\n status === ExecutorJobStatus.CANCELED\n );\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-proto/tailor/v1/executor_resource_pb\";\nimport { executorTargetTypeToString, executorTriggerTypeToString } from \"./status\";\nimport type {\n ExecutorExecutor,\n ExecutorJob,\n ExecutorJobAttempt,\n ExecutorTriggerEventConfig,\n} from \"@tailor-proto/tailor/v1/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 || 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 || typedConfig.case === undefined) {\n return {\n eventType: config.eventType,\n condition: config.condition?.expr || \"\",\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 * @deprecated Use GetExecutorTypedOptions instead.\n */\nexport interface GetExecutorOptions {\n name: string;\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>;\nexport async function getExecutor(options: GetExecutorOptions): Promise<ExecutorInfo>;\nexport async function getExecutor<E extends ExecutorLike>(\n options: GetExecutorOptions | GetExecutorTypedOptions<E>,\n): Promise<ExecutorInfo> {\n // Discriminant: legacy options have top-level 'name', typed options use 'executor'.\n const name = \"name\" in options ? options.name : options.executor.name;\n const accessToken = await loadAccessToken({\n useProfile: true,\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\n .object({\n ...workspaceArgs,\n ...nameArgs,\n })\n .strict(),\n run: async (args) => {\n const executor = await getExecutor({\n 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 { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\n// eslint-disable-next-line no-restricted-imports\nimport { getBorderCharacters, table } from \"table\";\nimport type { Timestamp } from \"@bufbuild/protobuf/wkt\";\nimport type { TableUserConfig } from \"table\";\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 `table` directly.\n * @param data - Table data\n * @param config - Table configuration\n * @returns Formatted table string\n */\nexport function formatTable(data: unknown[][], config?: TableUserConfig): string {\n return table(data, {\n ...config,\n border: getBorderCharacters(\"norc\"),\n });\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 { FunctionExecution_Status } from \"@tailor-proto/tailor/v1/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 { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { durationArg } from \"@/cli/shared/args\";\n\ntype ArgsShape = Record<string, z.ZodType>;\n\nexport const nameArgs = {\n name: arg(z.string(), {\n positional: true,\n description: \"Workflow name\",\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 interval: arg(durationArg.default(\"3s\"), {\n alias: \"i\",\n description: \"Polling interval when using --wait (e.g., '3s', '500ms', '1m')\",\n }),\n logs: arg(z.boolean().default(false), {\n alias: \"l\",\n description: \"Display job execution logs after completion (requires --wait)\",\n }),\n} satisfies ArgsShape;\n","import { WorkflowExecution_Status } from \"@tailor-proto/tailor/v1/workflow_resource_pb\";\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 status === WorkflowExecution_Status.SUCCESS ||\n status === WorkflowExecution_Status.FAILED ||\n status === WorkflowExecution_Status.PENDING_RESUME\n );\n}\n","import { timestampDate } from \"@bufbuild/protobuf/wkt\";\nimport {\n WorkflowExecution_Status,\n WorkflowJobExecution_Status,\n} from \"@tailor-proto/tailor/v1/workflow_resource_pb\";\nimport type {\n Workflow,\n WorkflowExecution,\n WorkflowJobExecution,\n} from \"@tailor-proto/tailor/v1/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 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 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 { create } from \"@bufbuild/protobuf\";\nimport {\n Condition_Operator,\n ConditionSchema,\n FilterSchema,\n} from \"@tailor-proto/tailor/v1/resource_pb\";\nimport { WorkflowExecution_Status } from \"@tailor-proto/tailor/v1/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 { spinner } from \"@/cli/shared/spinner\";\nimport { waitArgs } from \"./args\";\nimport { isWorkflowExecutionTerminalStatus } from \"./status\";\nimport {\n type WorkflowExecutionInfo,\n type WorkflowJobExecutionInfo,\n toWorkflowExecutionInfo,\n toWorkflowJobExecutionInfo,\n} from \"./transform\";\nimport type { FunctionExecution } from \"@tailor-proto/tailor/v1/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\n/**\n * @deprecated Use ListWorkflowExecutionsTypedOptions instead.\n */\nexport interface ListWorkflowExecutionsOptions {\n workspaceId?: string;\n profile?: string;\n workflowName?: string;\n status?: 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 logs?: boolean;\n}\n\nexport interface WorkflowExecutionDetailInfo extends WorkflowExecutionInfo {\n jobDetails?: (WorkflowJobExecutionInfo & {\n logs?: string;\n result?: string;\n })[];\n}\n\nexport interface GetWorkflowExecutionResult {\n execution: WorkflowExecutionDetailInfo;\n wait: () => Promise<WorkflowExecutionDetailInfo>;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\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 return styles.dim(statusText);\n case WorkflowExecution_Status.PENDING_RESUME:\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 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 default:\n throw new Error(\n `Invalid status: ${status}. Valid values: PENDING, PENDING_RESUME, RUNNING, SUCCESS, FAILED`,\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[]>;\nexport async function listWorkflowExecutions(\n options?: ListWorkflowExecutionsOptions,\n): Promise<WorkflowExecutionInfo[]>;\nexport async function listWorkflowExecutions<W extends WorkflowLike>(\n options?: ListWorkflowExecutionsOptions | ListWorkflowExecutionsTypedOptions<W>,\n): Promise<WorkflowExecutionInfo[]> {\n // Discriminant: legacy options have 'workflowName', typed options use 'workflow'.\n // Note: since ListWorkflowExecutionsTypedOptions has all optional fields, TypeScript may\n // resolve a legacy-typed variable to the typed overload (skipping excess property checks).\n // Runtime behavior is correct regardless because the discriminant handles both shapes.\n const workflowName =\n options && \"workflowName\" in options\n ? options.workflowName\n : options && \"workflow\" in options\n ? options.workflow?.name\n : undefined;\n const accessToken = await loadAccessToken({\n useProfile: true,\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 useProfile: true,\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<WorkflowExecutionDetailInfo> {\n const interval = options.interval ?? 3000;\n\n while (true) {\n const { execution } = await client.getWorkflowExecution({\n workspaceId,\n executionId: options.executionId,\n });\n\n if (!execution) {\n throw new Error(`Execution '${options.executionId}' not found.`);\n }\n\n // Terminal states (SUCCESS, FAILED, PENDING_RESUME)\n if (isWorkflowExecutionTerminalStatus(execution.status)) {\n return await fetchExecutionWithLogs(options.executionId, options.logs ?? false);\n }\n\n await sleep(interval);\n }\n }\n\n const execution = await fetchExecutionWithLogs(options.executionId, options.logs ?? false);\n\n return {\n execution,\n wait: waitForCompletion,\n };\n}\n\nasync function waitWithSpinner(\n waitFn: () => Promise<WorkflowExecutionDetailInfo>,\n interval: number,\n json: boolean,\n): Promise<WorkflowExecutionDetailInfo> {\n const sp = !json ? spinner().start(\"Waiting for workflow to complete...\") : null;\n\n const updateInterval = setInterval(() => {\n if (sp) {\n const now = formatTime(new Date());\n sp.text = `Waiting for workflow to complete... (${now})`;\n }\n }, interval);\n\n try {\n const result = await waitFn();\n const coloredStatus = colorizeStatus(\n WorkflowExecution_Status[result.status as keyof typeof WorkflowExecution_Status],\n );\n if (result.status === \"SUCCESS\") {\n sp?.succeed(`Completed: ${coloredStatus}`);\n } else {\n sp?.fail(`Completed: ${coloredStatus}`);\n }\n return result;\n } finally {\n clearInterval(updateInterval);\n sp?.stop();\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\n .object({\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 .strict(),\n run: async (args) => {\n if (args.executionId) {\n const interval = parseDuration(args.interval);\n const { execution, wait } = 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.json) {\n logger.info(`Execution ID: ${execution.id}`, { mode: \"stream\" });\n }\n\n const result = args.wait ? await waitWithSpinner(wait, interval, args.json) : execution;\n\n if (args.logs && !args.json) {\n printExecutionWithLogs(result);\n } else {\n logger.out(result);\n }\n } else {\n const executions = await listWorkflowExecutions({\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n workflowName: 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 * @deprecated Use GetWorkflowTypedOptions instead.\n */\nexport interface GetWorkflowOptions {\n name: string;\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>;\nexport async function getWorkflow(options: GetWorkflowOptions): Promise<WorkflowInfo>;\nexport async function getWorkflow<W extends WorkflowLike>(\n options: GetWorkflowOptions | GetWorkflowTypedOptions<W>,\n): Promise<WorkflowInfo> {\n // Discriminant: legacy options have top-level 'name', typed options use 'workflow'.\n // Note: passing a workflow object directly (e.g., getWorkflow(myWorkflow)) would match\n // the legacy branch due to structural typing, but still works correctly since it reads .name.\n const name = \"name\" in options ? options.name : options.workflow.name;\n const accessToken = await loadAccessToken({\n useProfile: true,\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\n .object({\n ...workspaceArgs,\n ...nameArgs,\n })\n .strict(),\n run: async (args) => {\n const workflow = await getWorkflow({\n 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-proto/tailor/v1/auth_resource_pb\";\nimport {\n WorkflowExecution_Status,\n WorkflowJobExecution_Status,\n} from \"@tailor-proto/tailor/v1/workflow_resource_pb\";\nimport { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { deploymentArgs, parseDuration } 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, styles } from \"@/cli/shared/logger\";\nimport { spinner } from \"@/cli/shared/spinner\";\nimport { nameArgs, waitArgs } from \"./args\";\nimport { getWorkflowExecution, printExecutionWithLogs } from \"./executions\";\nimport { resolveWorkflow } from \"./get\";\nimport { type WorkflowExecutionInfo, toWorkflowExecutionInfo } from \"./transform\";\nimport type { WorkflowExecution } from \"@tailor-proto/tailor/v1/workflow_resource_pb\";\nimport type { Jsonifiable } from \"type-fest\";\n\ntype WorkflowLike = {\n name: string;\n mainJob: {\n body: unknown;\n };\n};\n\ntype AuthInvoker<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\n/**\n * @deprecated Use StartWorkflowTypedOptions instead.\n */\nexport interface StartWorkflowOptions {\n name: string;\n machineUser: string;\n arg?: Jsonifiable;\n workspaceId?: string;\n profile?: string;\n configPath?: string;\n interval?: number;\n}\n\ntype StartWorkflowTypedBaseOptions<W extends WorkflowLike> = {\n workflow: W;\n authInvoker: AuthInvoker<string>;\n workspaceId?: string;\n profile?: string;\n interval?: number;\n};\n\nexport type StartWorkflowTypedOptions<W extends WorkflowLike = WorkflowLike> =\n W extends WorkflowLike ? StartWorkflowTypedBaseOptions<W> & StartWorkflowArgOption<W> : never;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\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 return styles.dim(statusText);\n case WorkflowExecution_Status.PENDING_RESUME:\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\nexport interface WaitForExecutionOptions {\n client: Awaited<ReturnType<typeof initOperatorClient>>;\n workspaceId: string;\n executionId: string;\n interval: number;\n showProgress?: boolean;\n trackJobs?: boolean;\n}\n\n/**\n * Wait for a workflow execution to reach a terminal state, optionally showing progress.\n * @param options - Wait options\n * @returns Final workflow execution info\n */\nexport async function waitForExecution(\n options: WaitForExecutionOptions,\n): Promise<WorkflowExecutionInfo> {\n const { client, workspaceId, executionId, interval, showProgress, trackJobs } = options;\n\n let lastStatus: WorkflowExecution_Status | undefined;\n let lastRunningJobs: string | undefined;\n const sp = showProgress\n ? spinner({ indent: 2 }).start(\"Waiting for workflow to complete...\")\n : null;\n\n try {\n while (true) {\n const { execution } = await client.getWorkflowExecution({\n workspaceId,\n executionId,\n });\n\n if (!execution) {\n sp?.fail(`Execution '${executionId}' not found.`);\n throw new Error(`Execution '${executionId}' not found.`);\n }\n\n const now = formatTime(new Date());\n const coloredStatus = colorizeStatus(execution.status);\n\n // Show workflow status change (persist previous line)\n if (execution.status !== lastStatus) {\n if (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 // Show job execution details when running (optional)\n if (trackJobs && execution.status === WorkflowExecution_Status.RUNNING) {\n const runningJobs = getRunningJobs(execution);\n if (runningJobs && runningJobs !== lastRunningJobs) {\n if (showProgress) {\n sp?.stop();\n logger.info(`Job | ${runningJobs}: ${coloredStatus}`, {\n mode: \"stream\",\n indent: 2,\n });\n sp?.start(`Waiting for workflow to complete...`);\n }\n lastRunningJobs = runningJobs;\n }\n }\n\n if (sp) {\n sp.text = `Waiting for workflow to complete... (${now})`;\n }\n\n // Terminal states: SUCCESS, FAILED, or PENDING_RESUME\n if (isTerminalStatus(execution.status)) {\n if (execution.status === WorkflowExecution_Status.SUCCESS) {\n sp?.succeed(`Completed: ${coloredStatus}`);\n } else if (execution.status === WorkflowExecution_Status.FAILED) {\n sp?.fail(`Completed: ${coloredStatus}`);\n } else {\n sp?.warn(`Completed: ${coloredStatus}`);\n }\n return toWorkflowExecutionInfo(execution);\n }\n\n await sleep(interval);\n }\n } catch (error) {\n sp?.stop();\n throw error;\n }\n}\n\nfunction getRunningJobs(execution: WorkflowExecution): string {\n return execution.jobExecutions\n .filter((job) => job.status === WorkflowJobExecution_Status.RUNNING)\n .map((job) => job.stackedJobName)\n .join(\", \");\n}\n\nfunction isTerminalStatus(status: WorkflowExecution_Status): boolean {\n return (\n status === WorkflowExecution_Status.SUCCESS ||\n status === WorkflowExecution_Status.FAILED ||\n status === WorkflowExecution_Status.PENDING_RESUME\n );\n}\n\nexport interface WaitOptions {\n showProgress?: boolean;\n}\n\nexport interface StartWorkflowResultWithWait {\n executionId: string;\n wait: (options?: WaitOptions) => Promise<WorkflowExecutionInfo>;\n}\n\ninterface StartWorkflowCoreOptions {\n client: Awaited<ReturnType<typeof initOperatorClient>>;\n workspaceId: string;\n workflowName: string;\n authInvoker: AuthInvoker<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 authInvoker = create(AuthInvokerSchema, options.authInvoker);\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,\n arg,\n });\n\n return {\n executionId,\n wait: (waitOptions?: WaitOptions) =>\n waitForExecution({\n client,\n workspaceId,\n executionId,\n interval: options.interval ?? 3000,\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 startWorkflowByName(\n options: StartWorkflowOptions,\n): Promise<StartWorkflowResultWithWait> {\n const accessToken = await loadAccessToken({\n useProfile: true,\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 return await startWorkflowCore({\n client,\n workspaceId,\n workflowName: options.name,\n authInvoker: {\n namespace: application.authNamespace,\n machineUserName: options.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>;\nexport async function startWorkflow(\n options: StartWorkflowOptions,\n): Promise<StartWorkflowResultWithWait>;\nexport async function startWorkflow<W extends WorkflowLike>(\n options: StartWorkflowOptions | StartWorkflowTypedOptions<W>,\n): Promise<StartWorkflowResultWithWait> {\n // Keep backward compatibility: if both legacy and typed keys are present, prefer legacy shape.\n if (\"name\" in options) {\n return await startWorkflowByName(options);\n }\n\n const accessToken = await loadAccessToken({\n useProfile: true,\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 startWorkflowCore({\n client,\n workspaceId,\n workflowName: options.workflow.name,\n authInvoker: options.authInvoker,\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\n .object({\n ...deploymentArgs,\n ...nameArgs,\n \"machine-user\": arg(z.string(), {\n alias: \"m\",\n hiddenAlias: \"machineuser\",\n description: \"Machine user name\",\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 .strict(),\n run: async (args) => {\n const { executionId, wait } = await startWorkflowByName({\n name: args.name,\n machineUser: 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({ showProgress: !jsonOutput });\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 {\n logger.out(result);\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-proto/tailor/v1/executor_resource_pb\";\nimport { FunctionExecution_Status } from \"@tailor-proto/tailor/v1/function_resource_pb\";\nimport {\n Condition_Operator,\n ConditionSchema,\n FilterSchema,\n PageDirection,\n} from \"@tailor-proto/tailor/v1/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 { getWorkflowExecution } from \"../workflow/executions\";\nimport { waitForExecution } from \"../workflow/start\";\nimport {\n colorizeExecutorJobStatus,\n colorizeFunctionExecutionStatus,\n executorTargetTypeToString,\n isFunctionExecutionTerminalStatus,\n isExecutorJobTerminalStatus,\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 logs?: boolean;\n};\n\n/**\n * @deprecated Use ListExecutorJobsTypedOptions instead.\n */\nexport interface ListExecutorJobsOptions {\n executorName: string;\n status?: string;\n order?: Order;\n limit?: number;\n workspaceId?: string;\n profile?: string;\n}\n\n/**\n * @deprecated Use GetExecutorJobTypedOptions instead.\n */\nexport interface GetExecutorJobOptions {\n executorName: string;\n jobId: string;\n attempts?: boolean;\n workspaceId?: string;\n profile?: string;\n}\n\n/**\n * @deprecated Use WatchExecutorJobTypedOptions instead.\n */\nexport interface WatchExecutorJobOptions {\n executorName: string;\n jobId: string;\n workspaceId?: string;\n profile?: string;\n interval?: number;\n logs?: 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 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\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[]>;\nexport async function listExecutorJobs(\n options: ListExecutorJobsOptions,\n): Promise<ExecutorJobListInfo[]>;\nexport async function listExecutorJobs<E extends ExecutorLike>(\n options: ListExecutorJobsOptions | ListExecutorJobsTypedOptions<E>,\n): Promise<ExecutorJobListInfo[]> {\n // Discriminant: legacy options have top-level 'executorName', typed options use 'executor'.\n const executorName = \"executorName\" in options ? options.executorName : options.executor.name;\n const accessToken = await loadAccessToken({\n useProfile: true,\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>;\nexport async function getExecutorJob(\n options: GetExecutorJobOptions,\n): Promise<ExecutorJobDetailInfo>;\nexport async function getExecutorJob<E extends ExecutorLike>(\n options: GetExecutorJobOptions | GetExecutorJobTypedOptions<E>,\n): Promise<ExecutorJobDetailInfo> {\n // Discriminant: legacy options have top-level 'executorName', typed options use 'executor'.\n const executorName = \"executorName\" in options ? options.executorName : options.executor.name;\n const accessToken = await loadAccessToken({\n useProfile: true,\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>;\nexport async function watchExecutorJob(\n options: WatchExecutorJobOptions,\n): Promise<WatchExecutorJobResult>;\nexport async function watchExecutorJob<E extends ExecutorLike>(\n options: WatchExecutorJobOptions | WatchExecutorJobTypedOptions<E>,\n): Promise<WatchExecutorJobResult> {\n // Discriminant: legacy options have top-level 'executorName', typed options use 'executor'.\n const executorName = \"executorName\" in options ? options.executorName : options.executor.name;\n const accessToken = await loadAccessToken({\n useProfile: true,\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 sp = spinner().start(\"Waiting for executor job to complete...\");\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 while (true) {\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\n if (isExecutorJobTerminalStatus(job.status)) {\n break;\n }\n\n sp.text = `Waiting for executor job... (${formatTime(new Date())})`;\n await setTimeout(interval);\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 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 const attemptInfos = attempts.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 // Use waitForExecution with progress display (same as workflow start)\n const executionResult = await waitForExecution({\n client,\n workspaceId,\n executionId: operationReference,\n interval,\n showProgress: true,\n trackJobs: true,\n });\n\n // Fetch logs if requested\n let workflowJobLogs: WorkflowJobLog[] | undefined;\n if (options.logs) {\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 }\n\n return {\n job: jobDetail,\n targetType: targetTypeStr,\n workflowExecutionId: operationReference,\n workflowStatus: executionResult.status,\n workflowJobLogs,\n };\n } catch (error) {\n logger.warn(\n `Could not track workflow execution: ${error instanceof Error ? error.message : error}`,\n );\n return {\n job: jobDetail,\n targetType: targetTypeStr,\n workflowExecutionId: operationReference,\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 while (true) {\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 if (isFunctionExecutionTerminalStatus(execution.status)) {\n const statusStr = functionExecutionStatusToString(execution.status);\n const coloredFnStatus = colorizeFunctionExecutionStatus(statusStr);\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 {\n job: jobDetail,\n targetType: targetTypeStr,\n functionExecutionId: operationReference,\n functionStatus: statusStr,\n functionLogs: options.logs ? execution.logs || undefined : undefined,\n };\n }\n\n sp.text = `Waiting for function execution... (${formatTime(new Date())})`;\n await setTimeout(interval);\n }\n } catch (error) {\n sp.warn(\n `Could not track function execution: ${error instanceof Error ? error.message : error}`,\n );\n return {\n job: jobDetail,\n targetType: targetTypeStr,\n functionExecutionId: operationReference,\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 { job: jobDetail, targetType: targetTypeStr };\n } finally {\n sp.stop();\n }\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\n .object({\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 ...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 .strict(),\n run: async (args) => {\n if (args.jobId) {\n if (args.wait) {\n const result = await watchExecutorJob({\n executorName: args.executorName,\n jobId: args.jobId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval: parseDuration(args.interval),\n logs: args.logs,\n });\n\n // Print result\n if (!args.json) {\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 return;\n }\n\n const job = await getExecutorJob({\n executorName: args.executorName,\n jobId: args.jobId,\n attempts: args.attempts,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n });\n if (args.attempts && !args.json) {\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 executorName: 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 useProfile: true,\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\n .object({\n ...workspaceArgs,\n ...paginationArgs(),\n })\n .strict(),\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-sdk executor webhook list\");\n }\n }\n },\n});\n","import { Code, ConnectError } from \"@connectrpc/connect\";\nimport { ExecutorTriggerType } from \"@tailor-proto/tailor/v1/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 { 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\n/**\n * @deprecated Use TriggerExecutorTypedOptions instead.\n */\nexport interface TriggerExecutorOptions {\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: TriggerExecutorOptions,\n): Promise<TriggerExecutorResult> {\n const accessToken = await loadAccessToken({\n useProfile: true,\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>;\nexport async function triggerExecutor(\n options: TriggerExecutorOptions,\n): Promise<TriggerExecutorResult>;\nexport async function triggerExecutor<E extends ManualTriggerExecutor>(\n options: TriggerExecutorOptions | TriggerExecutorTypedOptions<E>,\n): Promise<TriggerExecutorResult> {\n // Keep backward compatibility: if both legacy and typed keys are present, prefer legacy shape.\n if (\"executorName\" in options) {\n return await triggerExecutorByName(options);\n }\n\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\n .object({\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 logs: arg(z.boolean().default(false), {\n alias: \"l\",\n description: \"Display function execution logs after completion (requires --wait)\",\n }),\n })\n .strict(),\n run: async (args) => {\n await assertWritable({ profile: args.profile });\n // Validate trigger type before processing\n const accessToken = await loadAccessToken({\n useProfile: true,\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 executorName: args.executorName,\n jobId: result.jobId,\n workspaceId: args[\"workspace-id\"],\n profile: args.profile,\n interval: parseDuration(args.interval),\n logs: args.logs,\n });\n\n // Print result\n if (!args.json) {\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 }\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 useProfile: true,\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\n .object({\n ...workspaceArgs,\n ...paginationArgs(),\n })\n .strict(),\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(\n 'To test a webhook, run: tailor-sdk executor trigger <name> -d \\'{\"key\":\"value\"}\\'',\n );\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-proto/tailor/v1/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 { functionRegistryInfo, type FunctionRegistryInfo } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\n ...workspaceArgs,\n name: arg(z.string(), {\n description: \"Function name\",\n alias: \"n\",\n }),\n })\n .strict(),\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 { functionRegistryInfo, type FunctionRegistryInfo } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\n ...workspaceArgs,\n ...paginationArgs(),\n })\n .strict(),\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 { IdProvider as IdProviderConfig, OAuth2Client } from \"@/types/auth.generated\";\nimport type { Executor } from \"@/types/executor.generated\";\nimport type { PluginAttachment } from \"@/types/plugin\";\nimport type { Resolver } from \"@/types/resolver.generated\";\nimport type { TailorDBType, TypeSourceInfoEntry } from \"@/types/tailordb\";\n\nexport type { PluginAttachment } from \"@/types/plugin\";\n\n// ========================================\n// Basic types\n// ========================================\n\ninterface GeneratedFile {\n path: string;\n content: string;\n skipIfExists?: boolean; // default: false\n executable?: boolean; // default: false - if true, sets chmod +x\n}\n\nexport interface GeneratorResult {\n files: GeneratedFile[];\n errors?: string[];\n}\n\n// Namespace results for TailorDB\nexport interface TailorDBNamespaceResult<T> {\n namespace: string;\n types: T;\n}\n\n// Namespace results for Resolver\nexport interface ResolverNamespaceResult<R> {\n namespace: string;\n resolvers: R;\n}\n\n// Auth configuration for generators\nexport interface GeneratorAuthInput {\n name: string;\n userProfile?: {\n typeName: string;\n namespace: string;\n usernameField: string;\n };\n machineUsers?: Record<string, { attributes?: Record<string, unknown> }>;\n oauth2Clients?: Record<string, OAuth2Client>;\n idProvider?: IdProviderConfig;\n}\n\n// ========================================\n// Dependency types\n// ========================================\n\nexport type DependencyKind = \"tailordb\" | \"resolver\" | \"executor\";\n\n// Check if array includes a specific element\ntype ArrayIncludes<T extends readonly unknown[], U> = T extends readonly [\n infer First,\n ...infer Rest,\n]\n ? First extends U\n ? true\n : ArrayIncludes<Rest, U>\n : false;\n\n// Check if dependencies array includes a specific dependency\nexport type HasDependency<\n Deps extends readonly DependencyKind[],\n D extends DependencyKind,\n> = ArrayIncludes<Deps, D>;\n\n// ========================================\n// Source info type for TailorDB types\n// Re-exported from parser module\n// ========================================\n\nexport type {\n UserDefinedTypeSource,\n PluginGeneratedTypeSource,\n TypeSourceInfoEntry,\n} from \"@/types/tailordb\";\n\n// ========================================\n// Method interfaces for each dependency\n// ========================================\n\nexport interface TailorDBProcessMethods<T, Ts> {\n processType(args: {\n type: TailorDBType;\n namespace: string;\n source: TypeSourceInfoEntry;\n /** Plugin attachments configured on this type via .plugin() method */\n plugins: readonly PluginAttachment[];\n }): T | Promise<T>;\n\n processTailorDBNamespace?(args: {\n namespace: string;\n types: Record<string, T>;\n }): Ts | Promise<Ts>;\n}\n\nexport interface ResolverProcessMethods<R, Rs> {\n processResolver(args: { resolver: Resolver; namespace: string }): R | Promise<R>;\n\n processResolverNamespace?(args: {\n namespace: string;\n resolvers: Record<string, R>;\n }): Rs | Promise<Rs>;\n}\n\nexport interface ExecutorProcessMethods<E> {\n processExecutor(executor: Executor): E | Promise<E>;\n}\n\n// ========================================\n// Conditional method selection\n// ========================================\n\ntype SelectMethods<Deps extends readonly DependencyKind[], T, R, E, Ts, Rs> = (HasDependency<\n Deps,\n \"tailordb\"\n> extends true\n ? TailorDBProcessMethods<T, Ts>\n : object) &\n (HasDependency<Deps, \"resolver\"> extends true ? ResolverProcessMethods<R, Rs> : object) &\n (HasDependency<Deps, \"executor\"> extends true ? ExecutorProcessMethods<E> : object);\n\n// ========================================\n// Conditional input selection for aggregate\n// ========================================\n\ninterface TailorDBInputPart<Ts> {\n tailordb: TailorDBNamespaceResult<Ts>[];\n}\n\ninterface ResolverInputPart<Rs> {\n resolver: ResolverNamespaceResult<Rs>[];\n}\n\ninterface ExecutorInputPart<E> {\n executor: E[];\n}\n\n// Auth is always available (resolved after TailorDB, before generators)\ninterface AuthPart {\n auth?: GeneratorAuthInput;\n}\n\ntype SelectInput<Deps extends readonly DependencyKind[], Ts, Rs, E> = (HasDependency<\n Deps,\n \"tailordb\"\n> extends true\n ? TailorDBInputPart<Ts>\n : object) &\n (HasDependency<Deps, \"resolver\"> extends true ? ResolverInputPart<Rs> : object) &\n (HasDependency<Deps, \"executor\"> extends true ? ExecutorInputPart<E> : object) &\n AuthPart;\n\n/** Input type for TailorDB-only generators */\nexport type TailorDBInput<Ts> = TailorDBInputPart<Ts> & AuthPart;\n\n/** Input type for Resolver-only generators */\nexport type ResolverInput<Rs> = ResolverInputPart<Rs> & AuthPart;\n\n/** Input type for Executor-only generators */\nexport type ExecutorInput<E> = ExecutorInputPart<E> & AuthPart;\n\n/** Input type for full generators (TailorDB + Resolver + Executor) */\nexport type FullInput<Ts, Rs, E> = TailorDBInputPart<Ts> &\n ResolverInputPart<Rs> &\n ExecutorInputPart<E> &\n AuthPart;\n\n/** Arguments type for aggregate method */\nexport interface AggregateArgs<Input> {\n input: Input;\n baseDir: string;\n configPath: string;\n}\n\n// ========================================\n// CodeGenerator type definition\n// ========================================\n\ninterface CodeGeneratorCore {\n readonly id: string;\n readonly description: string;\n}\n\n/**\n * Generator interface with dependencies-based conditional methods.\n * @template Deps - Dependencies array (e.g., ['tailordb'], ['tailordb', 'resolver'])\n * @template T - Return type of processType\n * @template R - Return type of processResolver\n * @template E - Return type of processExecutor\n * @template Ts - Return type of processTailorDBNamespace (default: Record<string, T>)\n * @template Rs - Return type of processResolverNamespace (default: Record<string, R>)\n */\nexport type CodeGenerator<\n Deps extends readonly DependencyKind[],\n T = unknown,\n R = unknown,\n E = unknown,\n Ts = Record<string, T>,\n Rs = Record<string, R>,\n> = CodeGeneratorCore &\n SelectMethods<Deps, T, R, E, Ts, Rs> & {\n readonly dependencies: Deps;\n\n aggregate(args: {\n input: SelectInput<Deps, Ts, Rs, E>;\n baseDir: string;\n configPath: string;\n }): GeneratorResult | Promise<GeneratorResult>;\n };\n\n// ========================================\n// Helper types for common generator patterns\n// ========================================\n\n/** TailorDB-only generator */\nexport type TailorDBGenerator<T = unknown, Ts = Record<string, T>> = CodeGenerator<\n readonly [\"tailordb\"],\n T,\n never,\n never,\n Ts,\n never\n>;\n\n/** Resolver-only generator */\nexport type ResolverGenerator<R = unknown, Rs = Record<string, R>> = CodeGenerator<\n readonly [\"resolver\"],\n never,\n R,\n never,\n never,\n Rs\n>;\n\n/** Executor-only generator */\nexport type ExecutorGenerator<E = unknown> = CodeGenerator<\n readonly [\"executor\"],\n never,\n never,\n E,\n never,\n never\n>;\n\n/** TailorDB + Resolver generator */\nexport type TailorDBResolverGenerator<\n T = unknown,\n R = unknown,\n Ts = Record<string, T>,\n Rs = Record<string, R>,\n> = CodeGenerator<readonly [\"tailordb\", \"resolver\"], T, R, never, Ts, Rs>;\n\n/** Full generator (all dependencies) */\nexport type FullCodeGenerator<\n T = unknown,\n R = unknown,\n E = unknown,\n Ts = Record<string, T>,\n Rs = Record<string, R>,\n> = CodeGenerator<readonly [\"tailordb\", \"resolver\", \"executor\"], T, R, E, Ts, Rs>;\n\n// ========================================\n// Runtime utility\n// ========================================\n\ninterface DependencyCarrier {\n dependencies: readonly DependencyKind[];\n}\n\n/**\n * Type guard to check if a generator has a specific dependency.\n * @template D\n * @param generator - Code generator instance\n * @param dependency - Dependency kind to check\n * @returns True if the generator has the dependency\n */\nexport function hasDependency<D extends DependencyKind>(\n generator: DependencyCarrier,\n dependency: D,\n): boolean {\n return generator.dependencies.includes(dependency);\n}\n\n// Type for any generator (used in GenerationManager)\n// This is a more permissive type that includes all possible methods\nexport interface AnyCodeGenerator {\n readonly id: string;\n readonly description: string;\n readonly dependencies: readonly DependencyKind[];\n\n processType?(args: {\n type: TailorDBType;\n namespace: string;\n source: TypeSourceInfoEntry;\n plugins: readonly PluginAttachment[];\n }): unknown | Promise<unknown>;\n\n processTailorDBNamespace?(args: {\n namespace: string;\n types: Record<string, unknown>;\n }): unknown | Promise<unknown>;\n\n processResolver?(args: { resolver: Resolver; namespace: string }): unknown | Promise<unknown>;\n\n processResolverNamespace?(args: {\n namespace: string;\n resolvers: Record<string, unknown>;\n }): unknown | Promise<unknown>;\n\n processExecutor?(executor: Executor): unknown | Promise<unknown>;\n\n aggregate(args: {\n input: Record<string, unknown>;\n baseDir: string;\n configPath: string;\n }): GeneratorResult | Promise<GeneratorResult>;\n}\n","import { glob } from \"node:fs/promises\";\nimport { watch } from \"chokidar\";\nimport * as madgeModule from \"madge\";\nimport * as path from \"pathe\";\nimport { logger, styles } from \"@/cli/shared/logger\";\nimport type { MadgeLoader } from \"./types\";\n\n/**\n * Types of file change events.\n */\ntype FileChangeEvent = \"add\" | \"change\" | \"unlink\";\n\n/**\n * Definition of a watch group.\n */\ninterface WatchGroup {\n /** Unique identifier of the group. */\n id: string;\n /** File patterns to watch (glob format). */\n patterns: string[];\n /** List of absolute file paths in the group. */\n files: Set<string>;\n}\n\n/**\n * Node in the dependency graph.\n */\ninterface DependencyNode {\n /** Absolute path of the file. */\n filePath: string;\n /** List of files this file depends on. */\n dependencies: Set<string>;\n /** List of files that depend on this file. */\n dependents: Set<string>;\n}\n\n/**\n * Impact analysis result.\n */\ninterface ImpactAnalysisResult {\n /** Changed file. */\n changedFile: string;\n /** List of affected files (all files depending on the changed file). */\n affectedFiles: string[];\n /** List of affected watch groups. */\n affectedGroups: string[];\n}\n\n/**\n * Type of the error handling callback.\n */\ntype ErrorCallback = (error: WatcherError) => void;\n\n/**\n * Options for the watcher system.\n */\ninterface WatcherOptions {\n /** Options for chokidar. */\n chokidarOptions?: Parameters<typeof watch>[1];\n /** Options for madge. */\n madgeOptions?: Parameters<MadgeLoader>[1];\n /** Update interval for the dependency graph (milliseconds). */\n dependencyUpdateInterval?: number;\n /** Debounce duration (milliseconds). */\n debounceTime?: number;\n /** Whether to enable circular dependency detection. */\n detectCircularDependencies?: boolean;\n}\n\n/**\n * Watcher status.\n */\ninterface WatchStatus {\n /** Whether watching is active. */\n isWatching: boolean;\n /** Number of watch groups. */\n groupCount: number;\n /** Number of watched files. */\n fileCount: number;\n /** Number of nodes in the dependency graph. */\n dependencyNodeCount: number;\n}\n\n/**\n * Graph statistics.\n */\ninterface GraphStats {\n /** Number of nodes. */\n nodeCount: number;\n /** Number of edges. */\n edgeCount: number;\n /** Number of circular dependencies. */\n circularDependencyCount: number;\n}\n\n/**\n * Error codes.\n */\nconst WatcherErrorCode = {\n DEPENDENCY_ANALYSIS_FAILED: \"DEPENDENCY_ANALYSIS_FAILED\",\n FILE_WATCH_FAILED: \"FILE_WATCH_FAILED\",\n CIRCULAR_DEPENDENCY_DETECTED: \"CIRCULAR_DEPENDENCY_DETECTED\",\n INVALID_WATCH_GROUP: \"INVALID_WATCH_GROUP\",\n MADGE_INITIALIZATION_FAILED: \"MADGE_INITIALIZATION_FAILED\",\n} as const;\ntype WatcherErrorCode = (typeof WatcherErrorCode)[keyof typeof WatcherErrorCode];\n\n/**\n * Watcher-specific error.\n */\nexport class WatcherError extends Error {\n constructor(\n message: string,\n public readonly code: WatcherErrorCode,\n public readonly filePath?: string,\n public readonly originalError?: Error,\n ) {\n super(message);\n this.name = \"WatcherError\";\n }\n}\n\n/**\n * Dependency graph manager type.\n */\nexport type DependencyGraphManager = {\n buildGraph: (filePaths: string[]) => Promise<void>;\n getDependents: (filePath: string) => string[];\n getDependencies: (filePath: string) => string[];\n findCircularDependencies: () => string[][];\n addNode: (filePath: string) => void;\n removeNode: (filePath: string) => void;\n getGraphStats: () => GraphStats;\n};\n\n/**\n * Creates a dependency graph manager.\n * @param options - Options for madge\n * @returns DependencyGraphManager instance\n */\nexport function createDependencyGraphManager(\n options: Parameters<MadgeLoader>[1] = {},\n): DependencyGraphManager {\n const graph: Map<string, DependencyNode> = new Map();\n let madgeInstance: Awaited<ReturnType<MadgeLoader>> | null = null;\n let madgeLoader: MadgeLoader | null = null;\n\n function getMadgeLoader(): MadgeLoader {\n if (madgeLoader) {\n return madgeLoader;\n }\n\n const defaultExport = (madgeModule as { default?: unknown }).default;\n if (typeof defaultExport === \"function\") {\n madgeLoader = defaultExport as MadgeLoader;\n return madgeLoader;\n }\n\n if (typeof (madgeModule as unknown) === \"function\") {\n madgeLoader = madgeModule as unknown as MadgeLoader;\n return madgeLoader;\n }\n\n throw new WatcherError(\n \"Failed to initialize madge analyzer: module did not export a callable function.\",\n WatcherErrorCode.MADGE_INITIALIZATION_FAILED,\n );\n }\n\n function traverseDependents(filePath: string, visited: Set<string>): string[] {\n if (visited.has(filePath)) return [];\n visited.add(filePath);\n\n const node = graph.get(filePath);\n if (!node) return [];\n\n const result: string[] = [];\n for (const dependent of node.dependents) {\n result.push(dependent);\n result.push(...traverseDependents(dependent, visited));\n }\n\n return result;\n }\n\n function traverseDependencies(filePath: string, visited: Set<string>): string[] {\n if (visited.has(filePath)) return [];\n visited.add(filePath);\n\n const node = graph.get(filePath);\n if (!node) return [];\n\n const result: string[] = [];\n for (const dependency of node.dependencies) {\n result.push(dependency);\n result.push(...traverseDependencies(dependency, visited));\n }\n\n return result;\n }\n\n function addNode(filePath: string): void {\n const absolutePath = path.resolve(filePath);\n if (!graph.has(absolutePath)) {\n graph.set(absolutePath, {\n filePath: absolutePath,\n dependencies: new Set(),\n dependents: new Set(),\n });\n }\n }\n\n function removeNode(filePath: string): void {\n const absolutePath = path.resolve(filePath);\n const node = graph.get(absolutePath);\n if (!node) return;\n\n for (const dep of node.dependencies) {\n const depNode = graph.get(dep);\n if (depNode) {\n depNode.dependents.delete(absolutePath);\n }\n }\n\n for (const dependent of node.dependents) {\n const dependentNode = graph.get(dependent);\n if (dependentNode) {\n dependentNode.dependencies.delete(absolutePath);\n }\n }\n\n graph.delete(absolutePath);\n }\n\n function findCircularDependencies(): string[][] {\n if (!madgeInstance) return [];\n try {\n return madgeInstance.circular();\n } catch (error) {\n logger.warn(`Failed to detect circular dependencies: ${String(error)}`);\n return [];\n }\n }\n\n return {\n async buildGraph(filePaths: string[]): Promise<void> {\n try {\n if (filePaths.length === 0) return;\n\n const madge = getMadgeLoader();\n\n madgeInstance = await madge(filePaths, {\n fileExtensions: [\"ts\", \"js\"],\n excludeRegExp: [/node_modules/],\n baseDir: \".\",\n ...options,\n });\n\n const dependencyObj = madgeInstance.obj() as Record<string, string[]>;\n graph.clear();\n\n for (const filePath of filePaths) {\n addNode(filePath);\n }\n\n for (const [filePath, dependencies] of Object.entries(dependencyObj)) {\n const absoluteFilePath = path.resolve(\".\", filePath);\n const node = graph.get(absoluteFilePath);\n if (!node) continue;\n\n for (const dep of dependencies) {\n const absoluteDepPath = path.resolve(\".\", dep);\n node.dependencies.add(absoluteDepPath);\n\n const depNode = graph.get(absoluteDepPath);\n if (depNode) {\n depNode.dependents.add(absoluteFilePath);\n }\n }\n }\n } catch (error) {\n if (error instanceof WatcherError) {\n throw error;\n }\n throw new WatcherError(\n `Failed to build dependency graph: ${error instanceof Error ? error.message : String(error)}`,\n WatcherErrorCode.DEPENDENCY_ANALYSIS_FAILED,\n undefined,\n error instanceof Error ? error : undefined,\n );\n }\n },\n\n getDependents(filePath: string): string[] {\n const visited = new Set<string>();\n return traverseDependents(path.resolve(filePath), visited);\n },\n\n getDependencies(filePath: string): string[] {\n const visited = new Set<string>();\n return traverseDependencies(path.resolve(filePath), visited);\n },\n\n findCircularDependencies,\n addNode,\n removeNode,\n\n getGraphStats(): GraphStats {\n let edgeCount = 0;\n for (const node of graph.values()) {\n edgeCount += node.dependencies.size;\n }\n\n return {\n nodeCount: graph.size,\n edgeCount,\n circularDependencyCount: findCircularDependencies().length,\n };\n },\n };\n}\n\n/**\n * Dependency watcher type.\n */\nexport type DependencyWatcher = {\n initialize: () => Promise<void>;\n addWatchGroup: (groupId: string, patterns: string[]) => Promise<void>;\n removeWatchGroup: (groupId: string) => Promise<void>;\n start: () => Promise<void>;\n stop: () => Promise<void>;\n onError: (callback: ErrorCallback) => void;\n updateDependencyGraph: () => Promise<void>;\n calculateImpact: (filePath: string) => ImpactAnalysisResult;\n detectCircularDependencies: () => string[][];\n getWatchStatus: () => WatchStatus;\n setRestartCallback: (callback: () => void) => void;\n};\n\n/**\n * Creates a dependency watcher.\n * @param options - Watcher options\n * @returns DependencyWatcher instance\n */\nexport function createDependencyWatcher(options: WatcherOptions = {}): DependencyWatcher {\n let chokidarWatcher: ReturnType<typeof watch> | null = null;\n const watchGroups: Map<string, WatchGroup> = new Map();\n const dependencyGraphManager = createDependencyGraphManager(options.madgeOptions);\n let errorCallback: ErrorCallback | null = null;\n const debounceTimers: Map<string, NodeJS.Timeout> = new Map();\n let isInitialized = false;\n const dependencyCache: Map<string, string[]> = new Map();\n const maxCacheSize = 1000;\n let signalHandlersRegistered = false;\n let restartCallback: (() => void) | null = null;\n\n function validateWatchGroup(groupId: string, patterns: string[]): void {\n if (!groupId || typeof groupId !== \"string\") {\n throw new WatcherError(\n \"Group ID must be a non-empty string\",\n WatcherErrorCode.INVALID_WATCH_GROUP,\n );\n }\n\n if (!Array.isArray(patterns) || patterns.length === 0) {\n throw new WatcherError(\n \"Patterns must be a non-empty array\",\n WatcherErrorCode.INVALID_WATCH_GROUP,\n );\n }\n\n if (watchGroups.has(groupId)) {\n throw new WatcherError(\n `Watch group with ID '${groupId}' already exists`,\n WatcherErrorCode.INVALID_WATCH_GROUP,\n );\n }\n }\n\n function handleError(error: WatcherError): void {\n logger.error(\n `[DependencyWatcher] ${error.message} (code: ${error.code}, filePath: ${error.filePath})`,\n );\n\n if (errorCallback) {\n errorCallback(error);\n }\n }\n\n function setCacheValue(key: string, value: string[]): void {\n if (dependencyCache.size >= maxCacheSize) {\n const firstKey = dependencyCache.keys().next().value;\n if (firstKey) {\n dependencyCache.delete(firstKey);\n }\n }\n dependencyCache.set(key, value);\n }\n\n function findAffectedFiles(changedFile: string): string[] {\n return dependencyGraphManager.getDependents(changedFile);\n }\n\n function findAffectedGroups(affectedFiles: string[]): string[] {\n logger.debug(`Finding affected groups for files: ${affectedFiles.join(\", \")}`);\n const affectedGroupsSet = new Set<string>();\n\n for (const [groupId, group] of watchGroups) {\n for (const affectedFile of affectedFiles) {\n if (group.files.has(affectedFile)) {\n logger.debug(`Group ${groupId} is affected by file: ${affectedFile}`);\n affectedGroupsSet.add(groupId);\n break;\n }\n }\n }\n\n return Array.from(affectedGroupsSet);\n }\n\n function calculateImpact(filePath: string): ImpactAnalysisResult {\n const cacheKey = `impact:${filePath}`;\n let affectedFiles = dependencyCache.get(cacheKey);\n\n if (!affectedFiles) {\n affectedFiles = findAffectedFiles(filePath);\n setCacheValue(cacheKey, affectedFiles);\n }\n\n // Include the changed file itself in the affected files\n const allAffectedFiles = [filePath, ...affectedFiles];\n const affectedGroups = findAffectedGroups(allAffectedFiles);\n\n return {\n changedFile: filePath,\n affectedFiles: allAffectedFiles,\n affectedGroups,\n };\n }\n\n async function updateDependencyGraph(): Promise<void> {\n const allFiles: string[] = [];\n for (const group of watchGroups.values()) {\n allFiles.push(...Array.from(group.files));\n }\n\n await dependencyGraphManager.buildGraph(allFiles);\n dependencyCache.clear();\n\n if (options.detectCircularDependencies) {\n const circularDeps = dependencyGraphManager.findCircularDependencies();\n if (circularDeps.length > 0) {\n logger.warn(`Circular dependencies detected: ${JSON.stringify(circularDeps)}`);\n }\n }\n }\n\n async function handleFileChange(event: FileChangeEvent, filePath: string): Promise<void> {\n try {\n const absolutePath = path.resolve(filePath);\n\n if (event === \"unlink\") {\n dependencyGraphManager.removeNode(absolutePath);\n } else {\n dependencyGraphManager.addNode(absolutePath);\n if (event === \"change\") {\n await updateDependencyGraph();\n }\n }\n\n dependencyCache.clear();\n\n const impactResult = calculateImpact(absolutePath);\n\n // If any groups are affected, trigger restart instead of calling callbacks\n if (impactResult.affectedGroups.length > 0) {\n logger.info(\"File change detected, restarting watch process...\", {\n mode: \"stream\",\n });\n logger.info(`Changed file: ${absolutePath}`, { mode: \"stream\" });\n logger.info(`Affected groups: ${impactResult.affectedGroups.join(\", \")}`, {\n mode: \"stream\",\n });\n\n if (restartCallback) {\n restartCallback();\n }\n } else {\n logger.debug(`No affected groups found for file: ${absolutePath}`);\n }\n } catch (error) {\n handleError(\n new WatcherError(\n `Failed to handle file change: ${error instanceof Error ? error.message : String(error)}`,\n WatcherErrorCode.DEPENDENCY_ANALYSIS_FAILED,\n filePath,\n error instanceof Error ? error : undefined,\n ),\n );\n }\n }\n\n function debounceFileChange(event: FileChangeEvent, filePath: string): void {\n const key = `${event}:${filePath}`;\n\n if (debounceTimers.has(key)) {\n clearTimeout(debounceTimers.get(key));\n }\n\n const timer = setTimeout(() => {\n handleFileChange(event, filePath);\n debounceTimers.delete(key);\n }, options.debounceTime || 100);\n\n debounceTimers.set(key, timer);\n }\n\n async function stop(): Promise<void> {\n if (chokidarWatcher) {\n await chokidarWatcher.close();\n chokidarWatcher = null;\n }\n\n for (const timer of debounceTimers.values()) {\n clearTimeout(timer);\n }\n debounceTimers.clear();\n\n removeSignalHandlers();\n isInitialized = false;\n }\n\n function setupSignalHandlers(): void {\n if (signalHandlersRegistered) return;\n\n const handleSignal = async () => {\n try {\n await stop();\n logger.info(\"Watcher stopped successfully\");\n process.exit(0);\n } catch (error) {\n logger.error(`Error during shutdown: ${String(error)}`);\n process.exit(0);\n }\n };\n\n process.on(\"SIGINT\", () => handleSignal());\n process.on(\"SIGTERM\", () => handleSignal());\n signalHandlersRegistered = true;\n }\n\n function removeSignalHandlers(): void {\n if (!signalHandlersRegistered) return;\n\n process.removeAllListeners(\"SIGINT\");\n process.removeAllListeners(\"SIGTERM\");\n signalHandlersRegistered = false;\n }\n\n async function initialize(): Promise<void> {\n if (isInitialized) return;\n\n try {\n chokidarWatcher = watch([], {\n ignored: /node_modules/,\n persistent: true,\n ignoreInitial: true,\n usePolling: false,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 100,\n },\n ...options.chokidarOptions,\n });\n\n chokidarWatcher.on(\"add\", (filePath: string) => {\n logger.debug(`File added: ${filePath}`);\n debounceFileChange(\"add\", filePath);\n });\n\n chokidarWatcher.on(\"change\", (filePath: string) => {\n logger.debug(`File changed: ${filePath}`);\n debounceFileChange(\"change\", filePath);\n });\n\n chokidarWatcher.on(\"unlink\", (filePath: string) => {\n logger.debug(`File removed: ${filePath}`);\n debounceFileChange(\"unlink\", filePath);\n });\n\n chokidarWatcher.on(\"error\", (error: unknown) => {\n logger.error(`Watcher error: ${error instanceof Error ? error.message : String(error)}`, {\n mode: \"stream\",\n });\n handleError(\n new WatcherError(\n `File watcher error: ${error instanceof Error ? error.message : String(error)}`,\n WatcherErrorCode.FILE_WATCH_FAILED,\n undefined,\n error instanceof Error ? error : undefined,\n ),\n );\n });\n\n setupSignalHandlers();\n isInitialized = true;\n } catch (error) {\n throw new WatcherError(\n `Failed to initialize watcher: ${error instanceof Error ? error.message : String(error)}`,\n WatcherErrorCode.FILE_WATCH_FAILED,\n undefined,\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n return {\n initialize,\n\n async addWatchGroup(groupId: string, patterns: string[]): Promise<void> {\n validateWatchGroup(groupId, patterns);\n\n if (!isInitialized) {\n await initialize();\n }\n\n const files = new Set<string>();\n for (const pattern of patterns) {\n logger.log(\n `${styles.dim(`Watch pattern for`)} ${styles.dim(groupId + \":\")} ${path.relative(process.cwd(), pattern)}`,\n );\n for await (const file of glob(pattern)) {\n files.add(path.resolve(file));\n }\n }\n\n const watchGroup: WatchGroup = {\n id: groupId,\n patterns,\n files,\n };\n\n watchGroups.set(groupId, watchGroup);\n\n if (chokidarWatcher) {\n const filePaths = Array.from(files);\n chokidarWatcher.add(filePaths);\n }\n\n await updateDependencyGraph();\n },\n\n async removeWatchGroup(groupId: string): Promise<void> {\n const watchGroup = watchGroups.get(groupId);\n if (!watchGroup) return;\n\n if (chokidarWatcher) {\n chokidarWatcher.unwatch(watchGroup.patterns);\n }\n\n for (const filePath of watchGroup.files) {\n dependencyGraphManager.removeNode(filePath);\n }\n\n watchGroups.delete(groupId);\n dependencyCache.clear();\n },\n\n async start(): Promise<void> {\n if (!isInitialized) {\n await initialize();\n }\n await updateDependencyGraph();\n },\n\n stop,\n\n onError(callback: ErrorCallback): void {\n errorCallback = callback;\n },\n\n updateDependencyGraph,\n calculateImpact,\n\n detectCircularDependencies(): string[][] {\n return dependencyGraphManager.findCircularDependencies();\n },\n\n getWatchStatus(): WatchStatus {\n let fileCount = 0;\n for (const group of watchGroups.values()) {\n fileCount += group.files.size;\n }\n\n const stats = dependencyGraphManager.getGraphStats();\n\n return {\n isWatching: isInitialized && chokidarWatcher !== null,\n groupCount: watchGroups.size,\n fileCount,\n dependencyNodeCount: stats.nodeCount,\n };\n },\n\n setRestartCallback(callback: () => void): void {\n restartCallback = callback;\n },\n };\n}\n\nexport { WatcherErrorCode };\n","import { spawn } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport {\n type AnyCodeGenerator,\n type TailorDBNamespaceResult,\n type ResolverNamespaceResult,\n type GeneratorAuthInput,\n type GeneratorResult,\n type DependencyKind,\n hasDependency,\n} from \"@/cli/commands/generate/types\";\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 { loadConfig, type LoadedConfig, type Generator } 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\";\nimport { PluginManager } from \"@/plugin/manager\";\nimport { type TailorDBNamespaceData, type ResolverNamespaceData } from \"@/types/plugin-generation\";\nimport { createDependencyWatcher, type DependencyWatcher } from \"./watch\";\nimport type { GenerateOptions } from \"./options\";\nimport type { Executor } from \"@/types/executor.generated\";\nimport type { Plugin, PluginAttachment } from \"@/types/plugin\";\nimport type { Resolver } from \"@/types/resolver.generated\";\nimport type { TypeSourceInfo, TailorDBType } from \"@/types/tailordb\";\n\nexport type { CodeGenerator } from \"@/cli/commands/generate/types\";\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 generators: Generator[];\n readonly services: {\n tailordb: Record<string, TypeInfo>;\n resolver: Record<string, Record<string, Resolver>>;\n executor: Record<string, Executor>;\n };\n readonly generatorResults: GeneratorResults;\n processGenerator: (gen: AnyCodeGenerator) => Promise<void>;\n processTailorDBNamespace: (\n gen: AnyCodeGenerator,\n namespace: string,\n typeInfo: TypeInfo,\n ) => Promise<void>;\n processResolverNamespace: (\n gen: AnyCodeGenerator,\n namespace: string,\n resolvers: Record<string, Resolver>,\n ) => Promise<void>;\n processExecutors: (gen: AnyCodeGenerator) => Promise<void>;\n aggregate: (gen: AnyCodeGenerator) => Promise<void>;\n generate: (watch: boolean) => Promise<void>;\n watch: () => Promise<void>;\n};\n\ntype GeneratorResults = Record<\n /* generator */ string,\n {\n tailordbResults: Record</* namespace */ string, Record</* type */ string, unknown>>;\n resolverResults: Record</* namespace */ string, Record</* resolver */ string, unknown>>;\n tailordbNamespaceResults: Record</* namespace */ string, unknown>;\n resolverNamespaceResults: Record</* namespace */ string, unknown>;\n executorResults: Record</* executor */ string, unknown>;\n }\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.generators - Code generators to run\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 generators?: Generator[];\n pluginManager?: PluginManager;\n}): GenerationManager {\n const { application, config, generators = [], 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 let watcher: DependencyWatcher | null = null;\n const generatorResults: GeneratorResults = {};\n\n // Get plugins that have generation hooks\n const generationPlugins = pluginManager?.getPluginsWithGenerationHooks() ?? [];\n\n // Returns generators that subscribe to the given dependency phase\n function getReadyGenerators(dep: DependencyKind): Generator[] {\n return generators.filter((g) => (g as AnyCodeGenerator).dependencies.includes(dep));\n }\n\n function getAuthInput(): 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\n // =========================================================================\n // Generator processing (unchanged - per-type/perNS/aggregate pipeline)\n // =========================================================================\n\n async function processTailorDBNamespace(\n gen: AnyCodeGenerator,\n namespace: string,\n typeInfo: TypeInfo,\n ): Promise<void> {\n const results = generatorResults[gen.id];\n results.tailordbResults[namespace] = {};\n\n // Check if generator has processType method\n if (!gen.processType) {\n return;\n }\n\n const processType = gen.processType;\n await Promise.allSettled(\n Object.entries(typeInfo.types).map(async ([typeName, type]) => {\n try {\n results.tailordbResults[namespace][typeName] = await processType({\n type,\n namespace,\n source: typeInfo.sourceInfo[typeName],\n plugins: typeInfo.pluginAttachments.get(typeName) ?? [],\n });\n } catch (error) {\n logger.error(\n `Error processing type ${styles.bold(typeName)} in ${namespace} with generator ${gen.id}`,\n );\n logger.error(String(error));\n }\n }),\n );\n\n // Process namespace summary if available\n if (\"processTailorDBNamespace\" in gen && typeof gen.processTailorDBNamespace === \"function\") {\n try {\n results.tailordbNamespaceResults[namespace] = await gen.processTailorDBNamespace({\n namespace,\n types: results.tailordbResults[namespace],\n });\n } catch (error) {\n logger.error(\n `Error processing TailorDB namespace ${styles.bold(namespace)} with generator ${gen.id}`,\n );\n logger.error(String(error));\n }\n } else {\n results.tailordbNamespaceResults[namespace] = results.tailordbResults[namespace];\n }\n }\n\n async function processResolverNamespace(\n gen: AnyCodeGenerator,\n namespace: string,\n resolvers: Record<string, Resolver>,\n ): Promise<void> {\n const results = generatorResults[gen.id];\n results.resolverResults[namespace] = {};\n\n // Check if generator has processResolver method\n if (!gen.processResolver) {\n return;\n }\n\n const processResolver = gen.processResolver;\n // Process individual resolvers\n await Promise.allSettled(\n Object.entries(resolvers).map(async ([resolverName, resolver]) => {\n try {\n results.resolverResults[namespace][resolverName] = await processResolver({\n resolver,\n namespace,\n });\n } catch (error) {\n logger.error(\n `Error processing resolver ${styles.bold(resolverName)} in ${namespace} with generator ${gen.id}`,\n );\n logger.error(String(error));\n }\n }),\n );\n\n // Process namespace summary if available\n if (\"processResolverNamespace\" in gen && typeof gen.processResolverNamespace === \"function\") {\n try {\n results.resolverNamespaceResults[namespace] = await gen.processResolverNamespace({\n namespace,\n resolvers: results.resolverResults[namespace],\n });\n } catch (error) {\n logger.error(\n `Error processing Resolver namespace ${styles.bold(namespace)} with generator ${gen.id}`,\n );\n logger.error(String(error));\n }\n } else {\n results.resolverNamespaceResults[namespace] = results.resolverResults[namespace];\n }\n }\n\n async function processExecutors(gen: AnyCodeGenerator): Promise<void> {\n const results = generatorResults[gen.id];\n\n // Check if generator has processExecutor method\n if (!gen.processExecutor) {\n return;\n }\n\n const processExecutor = gen.processExecutor;\n // Process individual executors\n await Promise.allSettled(\n Object.entries(services.executor).map(async ([executorId, executor]) => {\n try {\n results.executorResults[executorId] = await processExecutor(executor);\n } catch (error) {\n logger.error(\n `Error processing executor ${styles.bold(executor.name)} with generator ${gen.id}`,\n );\n logger.error(String(error));\n }\n }),\n );\n }\n\n async function aggregate(gen: AnyCodeGenerator): Promise<void> {\n const results = generatorResults[gen.id];\n\n const tailordbResults: TailorDBNamespaceResult<unknown>[] = [];\n const resolverResults: ResolverNamespaceResult<unknown>[] = [];\n\n // Collect TailorDB namespace results\n for (const [namespace, types] of Object.entries(results.tailordbNamespaceResults)) {\n tailordbResults.push({\n namespace,\n types,\n });\n }\n\n // Collect Resolver namespace results\n for (const [namespace, resolvers] of Object.entries(results.resolverNamespaceResults)) {\n resolverResults.push({\n namespace,\n resolvers,\n });\n }\n\n // Build input based on generator dependencies\n const input: Record<string, unknown> = {\n auth: getAuthInput(),\n };\n\n if (hasDependency(gen, \"tailordb\")) {\n input.tailordb = tailordbResults;\n }\n if (hasDependency(gen, \"resolver\")) {\n input.resolver = resolverResults;\n }\n if (hasDependency(gen, \"executor\")) {\n input.executor = Object.values(results.executorResults);\n }\n\n // Call generator's aggregate method\n const result = await gen.aggregate({\n input: input as Parameters<typeof gen.aggregate>[0][\"input\"],\n baseDir: path.join(baseDir, gen.id),\n configPath: config.path,\n });\n\n // Write generated files\n await writeGeneratedFiles(gen.id, result);\n }\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();\n const tailordb = buildTailorDBData();\n\n let result: GeneratorResult;\n\n switch (hookName) {\n case \"onTailorDBReady\":\n result = await plugin.onTailorDBReady!({\n tailordb,\n auth,\n baseDir: pluginBaseDir,\n configPath: config.path,\n pluginConfig: plugin.pluginConfig,\n });\n break;\n case \"onResolverReady\":\n result = await plugin.onResolverReady!({\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 plugin.onExecutorReady!({\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 * @param watch - Whether running in watch mode (suppresses throws)\n */\n async function runPluginHook(\n hookName: \"onTailorDBReady\" | \"onResolverReady\" | \"onExecutorReady\",\n watch: boolean,\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 if (!watch) {\n throw error;\n }\n }\n }),\n );\n if (!watch) {\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 // =========================================================================\n // Shared file writing\n // =========================================================================\n\n /**\n * Write generated files to disk.\n * @param sourceId - Generator or plugin ID for logging\n * @param result - Generator 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 // =========================================================================\n // Generator orchestration\n // =========================================================================\n\n async function processGenerator(gen: AnyCodeGenerator): Promise<void> {\n generatorResults[gen.id] = {\n tailordbResults: {},\n resolverResults: {},\n tailordbNamespaceResults: {},\n resolverNamespaceResults: {},\n executorResults: {},\n };\n\n // Process TailorDB if generator has tailordb dependency\n if (hasDependency(gen, \"tailordb\")) {\n for (const [namespace, types] of Object.entries(services.tailordb)) {\n await processTailorDBNamespace(gen, namespace, types);\n }\n }\n\n // Process Resolver if generator has resolver dependency\n if (hasDependency(gen, \"resolver\")) {\n for (const [namespace, resolvers] of Object.entries(services.resolver)) {\n await processResolverNamespace(gen, namespace, resolvers);\n }\n }\n\n // Process Executors if generator has executor dependency\n if (hasDependency(gen, \"executor\")) {\n await processExecutors(gen);\n }\n\n // Aggregate all results\n await aggregate(gen);\n }\n\n async function runGenerators(gens: Generator[], watch: boolean): Promise<void> {\n const results = await Promise.allSettled(\n gens.map(async (gen) => {\n await withSpan(`generate.generator.${gen.id}`, async () => {\n try {\n await processGenerator(gen as AnyCodeGenerator);\n } catch (error) {\n logger.error(`Error processing generator ${styles.bold(gen.id)}`);\n logger.error(String(error));\n if (!watch) {\n throw error;\n }\n }\n });\n }),\n );\n if (!watch) {\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 async function restartWatchProcess(): Promise<void> {\n logger.newline();\n logger.info(\"Restarting watch process to clear module cache...\", {\n mode: \"stream\",\n });\n logger.newline();\n\n // Clean up watcher first\n if (watcher) {\n await watcher.stop();\n }\n\n // Spawn a new process with the same arguments\n const args = process.argv.slice(2);\n const env = {\n ...process.env,\n TAILOR_WATCH_GENERATION: (\n parseInt(process.env.TAILOR_WATCH_GENERATION || \"0\", 10) + 1\n ).toString(),\n };\n\n const child = spawn(process.argv[0], [process.argv[1], ...args], {\n stdio: \"inherit\",\n env,\n detached: false,\n });\n\n // Forward signals to child\n const forwardSignal = (signal: NodeJS.Signals) => {\n child.kill(signal);\n };\n\n process.on(\"SIGINT\", forwardSignal);\n process.on(\"SIGTERM\", forwardSignal);\n\n // Wait for child to exit, then exit parent\n child.on(\"exit\", (code) => {\n process.exit(code || 0);\n });\n\n // Don't exit immediately - let child handle everything\n }\n\n return {\n application,\n baseDir,\n generators,\n services,\n generatorResults,\n processGenerator,\n processTailorDBNamespace,\n processResolverNamespace,\n processExecutors,\n aggregate,\n\n async generate(watch: boolean): 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 if (!watch) {\n throw error;\n }\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 if (!watch) {\n throw error;\n }\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: [] } })\n : undefined);\n return { pluginExecutorFiles, executorService };\n },\n );\n\n // Resolve Auth namespaces (depends on TailorDB)\n if (app.authService) {\n await withSpan(\"generate.resolveAuthNamespaces\", async () =>\n app.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 generators + plugin hooks for onTailorDBReady\n const readyAfterTailorDB = getReadyGenerators(\"tailordb\");\n const hasOnTailorDBReady = generationPlugins.some((p) => p.onTailorDBReady != null);\n if (readyAfterTailorDB.length > 0 || hasOnTailorDBReady) {\n await withSpan(\"generate.onTailorDBReady\", async () => {\n await Promise.all([\n runGenerators(readyAfterTailorDB, watch),\n runPluginHook(\"onTailorDBReady\", watch),\n ]);\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 services.resolver[namespace] = {};\n Object.entries(resolverService.resolvers).forEach(([_, resolver]) => {\n services.resolver[namespace][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 if (!watch) {\n throw error;\n }\n }\n });\n }\n });\n\n // Run generators + plugin hooks for onResolverReady\n const readyAfterResolvers = getReadyGenerators(\"resolver\");\n const hasOnResolverReady = generationPlugins.some((p) => p.onResolverReady != null);\n if (readyAfterResolvers.length > 0 || hasOnResolverReady) {\n await withSpan(\"generate.onResolversReady\", async () => {\n await Promise.all([\n runGenerators(readyAfterResolvers, watch),\n runPluginHook(\"onResolverReady\", watch),\n ]);\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 generators + plugin hooks for onExecutorReady\n const readyAfterExecutors = getReadyGenerators(\"executor\");\n const hasOnExecutorReady = generationPlugins.some((p) => p.onExecutorReady != null);\n if (readyAfterExecutors.length > 0 || hasOnExecutorReady) {\n await withSpan(\"generate.onExecutorsReady\", async () => {\n await Promise.all([\n runGenerators(readyAfterExecutors, watch),\n runPluginHook(\"onExecutorReady\", watch),\n ]);\n });\n logger.newline();\n }\n },\n\n async watch(): Promise<void> {\n watcher = createDependencyWatcher();\n\n // Set up restart callback\n watcher.setRestartCallback(() => {\n restartWatchProcess();\n });\n\n // Watch config file\n await watcher.addWatchGroup(\"Config\", [config.path]);\n\n // Watch application services\n const app = application;\n\n // Watch TailorDB services\n for (const db of app.tailorDBServices) {\n const dbNamespace = db.namespace;\n await watcher?.addWatchGroup(`TailorDB/${dbNamespace}`, db.config.files);\n }\n\n // Watch Resolver services\n for (const resolverService of app.resolverServices) {\n const resolverNamespace = resolverService.namespace;\n await watcher?.addWatchGroup(\n `Resolver/${resolverNamespace}`,\n resolverService[\"config\"].files,\n );\n }\n\n // Keep the process running\n await new Promise(() => {});\n },\n };\n}\n\n/**\n * Run code generation using the Tailor configuration and generators.\n * @param options - Generation options\n * @returns Promise that resolves when generation (and watch, if enabled) completes\n */\nexport async function generate(options?: GenerateOptions) {\n return withSpan(\"generate\", async (rootSpan) => {\n // Load and validate options\n const { config, generators, plugins } = await withSpan(\"generate.loadConfig\", async () => {\n return loadConfig(options?.configPath);\n });\n const watch = options?.watch ?? false;\n\n rootSpan.setAttribute(\"generate.watch\", watch);\n rootSpan.setAttribute(\"generate.generators.count\", generators.length);\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, generators, pluginManager });\n await manager.generate(watch);\n if (watch) {\n await manager.watch();\n }\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-proto/tailor/v1/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 useProfile: true,\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\n .object({\n ...deploymentArgs,\n ...paginationArgs(),\n })\n .strict(),\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 { deploymentArgs } 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, 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\nexport interface MachineUserTokenInfo {\n accessToken: string;\n tokenType: string;\n expiresAt: string;\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 // Load and validate options\n const accessToken = await loadAccessToken({\n useProfile: true,\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: options.name,\n });\n if (!machineUser) {\n throw new Error(`Machine user ${options.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\nexport const tokenCommand = defineAppCommand({\n name: \"token\",\n description: \"Get an access token for a machine user.\",\n args: z\n .object({\n ...deploymentArgs,\n name: arg(z.string(), {\n positional: true,\n description: \"Machine user name\",\n }),\n })\n .strict(),\n run: async (args) => {\n // Execute machineuser token logic\n const token = await getMachineUserToken({\n name: args.name,\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-proto/tailor/v1/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 { 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 useProfile: true,\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(oauth2Client!);\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\n .object({\n ...deploymentArgs,\n name: arg(z.string(), {\n positional: true,\n description: \"OAuth2 client name\",\n }),\n })\n .strict(),\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 useProfile: true,\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\n .object({\n ...deploymentArgs,\n ...paginationArgs(),\n })\n .strict(),\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-proto/tailor/v1/workspace_pb\";\nimport type { Organization, Folder } from \"@tailor-proto/tailor/v1/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 { folderInfo, type FolderInfo } from \"../transform\";\n\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(result.error.issues[0].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\n .object({\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 .strict(),\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\";\n\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(result.error.issues[0].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\n .object({\n ...organizationArgs,\n ...folderArgs,\n ...confirmationArgs,\n })\n .strict(),\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 { folderInfo, type FolderInfo } from \"../transform\";\n\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(result.error.issues[0].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\n .object({\n ...organizationArgs,\n ...folderArgs,\n })\n .strict(),\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 { folderListInfo, type FolderListInfo } from \"../transform\";\n\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(result.error.issues[0].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\n .object({\n ...organizationArgs,\n \"parent-folder-id\": arg(z.string().optional(), {\n description: \"Parent folder ID to list children of\",\n }),\n ...paginationArgs(),\n })\n .strict(),\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 { folderInfo, type FolderInfo } from \"../transform\";\n\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(result.error.issues[0].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\n .object({\n ...organizationArgs,\n ...folderArgs,\n name: arg(z.string(), {\n alias: \"n\",\n description: \"New folder name\",\n }),\n })\n .strict(),\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 { organizationInfo, type OrganizationInfo } from \"./transform\";\n\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(result.error.issues[0].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\n .object({\n ...organizationArgs,\n })\n .strict(),\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\n .object({\n limit: arg(positiveIntArg.optional(), {\n alias: \"l\",\n description: \"Maximum number of organizations to list\",\n }),\n })\n .strict(),\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 (let i = 0; i < nodes.length; i++) {\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}${nodes[i].name}\\n`;\n if (nodes[i].children.length > 0) {\n output += renderTree(nodes[i].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\n .object({\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 .strict(),\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 { organizationInfo, type OrganizationInfo } from \"./transform\";\n\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(result.error.issues[0].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\n .object({\n ...organizationArgs,\n name: arg(z.string(), {\n alias: \"n\",\n description: \"New organization name\",\n }),\n })\n .strict(),\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 { applyApplication, planApplication } from \"@/cli/commands/deploy/application\";\nimport { applyAuth, planAuth } from \"@/cli/commands/deploy/auth\";\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\";\nimport { applyWorkflow, planWorkflow } from \"@/cli/commands/deploy/workflow\";\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 { 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 useProfile: true,\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 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 const tailorDB = await planTailorDB(ctx);\n const staticWebsite = await planStaticWebsite(ctx);\n const idp = await planIdP(ctx);\n const auth = await planAuth(ctx);\n const pipeline = await planPipeline(ctx);\n const app = await planApplication(ctx);\n const executor = await planExecutor(ctx);\n const workflow = await planWorkflow(\n client,\n workspaceId,\n application.name,\n application.id,\n {},\n {},\n );\n const functionRegistry = await planFunctionRegistry(\n client,\n workspaceId,\n application.name,\n application.id,\n [],\n );\n const secretManager = await planSecretManager(ctx);\n\n // Print planned deletions (same order as apply dry-run)\n functionRegistry.changeSet.print();\n staticWebsite.changeSet.print();\n app.print();\n tailorDB.changeSet.service.print();\n tailorDB.changeSet.type.print();\n tailorDB.changeSet.gqlPermission.print();\n pipeline.changeSet.service.print();\n pipeline.changeSet.resolver.print();\n executor.changeSet.print();\n workflow.changeSet.print();\n idp.changeSet.service.print();\n idp.changeSet.client.print();\n auth.changeSet.service.print();\n auth.changeSet.idpConfig.print();\n auth.changeSet.userProfileConfig.print();\n auth.changeSet.tenantConfig.print();\n auth.changeSet.machineUser.print();\n auth.changeSet.oauth2Client.print();\n auth.changeSet.authHook.print();\n auth.changeSet.scim.print();\n auth.changeSet.scimResource.print();\n auth.changeSet.connection?.print();\n secretManager.vaultChangeSet.print();\n secretManager.secretChangeSet.print();\n\n if (\n tailorDB.changeSet.service.deletes.length === 0 &&\n staticWebsite.changeSet.deletes.length === 0 &&\n idp.changeSet.service.deletes.length === 0 &&\n auth.changeSet.service.deletes.length === 0 &&\n pipeline.changeSet.service.deletes.length === 0 &&\n app.deletes.length === 0 &&\n executor.changeSet.deletes.length === 0 &&\n workflow.changeSet.deletes.length === 0 &&\n functionRegistry.changeSet.deletes.length === 0 &&\n secretManager.vaultChangeSet.deletes.length === 0 &&\n secretManager.secretChangeSet.deletes.length === 0\n ) {\n return;\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, workflow, \"delete\");\n await applyExecutor(client, executor, \"delete\");\n await applyStaticWebsite(client, staticWebsite, \"delete\");\n await applyApplication(client, app, \"delete\");\n await applyPipeline(client, pipeline, \"delete-resources\");\n await applyPipeline(client, pipeline, \"delete-services\");\n await applyAuth(client, auth, \"delete-resources\");\n await applyAuth(client, auth, \"delete-services\");\n await applyIdP(client, idp, \"delete-resources\");\n await applyIdP(client, idp, \"delete-services\");\n await applyTailorDB(client, tailorDB, \"delete-resources\");\n await applyTailorDB(client, tailorDB, \"delete-services\");\n await applyFunctionRegistry(client, workspaceId, functionRegistry, \"delete\");\n await applySecretManager(client, secretManager, \"delete\");\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\n .object({\n ...deploymentArgs,\n ...confirmationArgs,\n })\n .strict(),\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 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 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 erd\", \"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 { timestampDate } from \"@bufbuild/protobuf/wkt\";\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 type { Application } from \"@tailor-proto/tailor/v1/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 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 ShowInfo extends ApplicationInfo, WorkspaceInfo {}\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\n/**\n * Show applied application information for the current workspace.\n * @param options - Show options\n * @returns Application information\n */\nexport async function show(options?: ShowOptions): Promise<ShowInfo> {\n // Load and validate options\n const accessToken = await loadAccessToken({\n useProfile: true,\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 [workspaceResp, resp] = await Promise.all([\n client.getWorkspace({\n workspaceId,\n }),\n client.getApplication({\n workspaceId,\n applicationName: config.name,\n }),\n ]);\n const { name, ...appInfo } = applicationInfo(resp.application!);\n\n return {\n name,\n workspaceId,\n workspaceName: workspaceResp.workspace?.name ?? \"\",\n workspaceRegion: workspaceResp.workspace?.region ?? \"\",\n ...appInfo,\n };\n}\n\nexport const showCommand = defineAppCommand({\n name: \"show\",\n description: \"Show information about the deployed application.\",\n args: z\n .object({\n ...deploymentArgs,\n })\n .strict(),\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 },\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 {\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.fieldName) {\n const { before, after } = change;\n\n // Check if this is an optional -> required change\n if (before && after && !before.required && after.required) {\n if (!optionalToRequired.has(change.typeName)) {\n optionalToRequired.set(change.typeName, new Set());\n }\n optionalToRequired.get(change.typeName)!.add(change.fieldName);\n }\n\n // Check if this is an enum value change\n if (\n before &&\n after &&\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 enumValueChanges.get(change.typeName)!.set(change.fieldName, {\n beforeValues,\n afterValues,\n });\n }\n }\n } else if (change.kind === \"field_added\" && change.fieldName) {\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 && after.required) {\n if (!addedRequiredFields.has(change.typeName)) {\n addedRequiredFields.set(change.typeName, new Map());\n }\n addedRequiredFields.get(change.typeName)!.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 \"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 \"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 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\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 // 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 { getMigrationDirPath, getMigrationFilePath, type SchemaSnapshot } from \"./snapshot\";\nimport type { MigrationDiff, DiffChange } from \"./diff-calculator\";\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 script = generateChangeScript(change);\n if (script) {\n updates.push(script);\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-sdk 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 script for a single change\n * @param {DiffChange} change - Diff change to generate script for\n * @returns {string | null} Script content or null if no script needed\n */\nfunction generateChangeScript(change: DiffChange): string | null {\n if (change.kind === \"field_added\") {\n const field = change.after;\n if (field.required) {\n return ` // 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 return null;\n }\n\n if (change.kind !== \"field_modified\") {\n // No data migration needed for type_added, type_removed, or field_removed\n return null;\n }\n\n const { before, after } = change;\n\n // Note: Type change is rejected as unsupported in generate.ts\n // No script generation needed here\n\n // Optional to required\n if (!before.required && after.required) {\n return ` // 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 (!(before.unique ?? false) && (after.unique ?? false)) {\n return ` // Ensure ${change.fieldName} values are unique before adding constraint\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 // Keep first record, add suffix to others\n const records = await trx\n .selectFrom(\"${change.typeName}\")\n .select([\"id\", \"${change.fieldName}\"])\n .where(\"${change.fieldName}\", \"=\", dup.${change.fieldName})\n .execute();\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 }\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 return ` // 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 return ` // 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 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 return null;\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 * 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 { 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 {\n createSnapshotFromLocalTypes,\n reconstructSnapshotFromMigrations,\n compareSnapshots,\n getNextMigrationNumber,\n assertValidMigrationFiles,\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 * 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 // Check if migrations directory exists and has snapshots\n let previousSnapshot: SchemaSnapshot | null = null;\n try {\n previousSnapshot = reconstructSnapshotFromMigrations(migrationsDir);\n } catch {\n // No previous migrations - this is fine\n }\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 logger.info(\"These changes require a manual 3-step migration process:\");\n logger.info(\" Migration 1: Add a new field with the desired structure\");\n logger.info(\" and migrate data from old field to new field\");\n logger.info(\" Migration 2: Remove the old field\");\n logger.info(\" Migration 3: Add the field with the original name and new structure,\");\n logger.info(\" migrate data from temporary field, then remove temporary field\");\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(result.migrationNumber.toString().padStart(4, \"0\"))}`,\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-sdk 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 logger.newline();\n logger.log(\n `Data loss is possible for this migration but no script was generated. To add a custom migrate.ts, run:`,\n );\n logger.log(\n ` ${styles.bold(`tailor-sdk tailordb migration script ${result.migrationNumber.toString().padStart(4, \"0\")} --namespace ${diff.namespace}`)}`,\n );\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\n .object({\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 .strict(),\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","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 && nsConfig.external === true) continue;\n namespaces.add(namespaceName);\n }\n }\n\n return Array.from(namespaces);\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\";\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 useProfile: true,\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 && options?.namespace) {\n const namespace = options.namespace;\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 && dbConfig.external === true) {\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 && options?.types) {\n const typeNames = options.types;\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\n .object({\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 .strict(),\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 useProfile: true,\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\n .object({\n ...workspaceArgs,\n ...paginationArgs(),\n })\n .strict(),\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 { type WorkflowExecutionInfo } from \"./transform\";\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<WorkflowExecutionInfo>;\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 useProfile: true,\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 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\n .object({\n ...workspaceArgs,\n \"execution-id\": arg(z.string(), {\n positional: true,\n description: \"Failed execution ID\",\n }),\n ...waitArgs,\n })\n .strict(),\n run: async (args) => {\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 (!args.json) {\n logger.info(`Execution ID: ${executionId}`, { mode: \"stream\" });\n }\n\n if (args.wait) {\n const result = await wait({ showProgress: !args.json });\n if (args.logs && !args.json) {\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 {\n logger.out(result);\n }\n } else {\n logger.out({ executionId });\n }\n },\n});\n","import {\n type GetApplicationSchemaHealthResponse,\n GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus,\n} from \"@tailor-proto/tailor/v1/application_pb\";\nimport { ApplicationSchemaUpdateAttemptStatus } from \"@tailor-proto/tailor/v1/application_resource_pb\";\nimport { formatTimestamp } from \"@/cli/shared/format\";\nimport type { Application } from \"@tailor-proto/tailor/v1/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 { appHealthInfo, type AppHealthInfo } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\n ...workspaceArgs,\n name: arg(z.string(), {\n description: \"Application name\",\n alias: \"n\",\n }),\n })\n .strict(),\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 { appInfo, type AppInfo } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\n ...workspaceArgs,\n ...paginationArgs(),\n })\n .strict(),\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 { formatTimestamp } from \"@/cli/shared/format\";\nimport type { Workspace } from \"@tailor-proto/tailor/v1/workspace_resource_pb\";\n\nexport interface WorkspaceInfo {\n id: string;\n name: 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): WorkspaceInfo => {\n return {\n id: workspace.id,\n name: workspace.name,\n region: workspace.region,\n createdAt: formatTimestamp(workspace.createTime),\n updatedAt: formatTimestamp(workspace.updateTime),\n };\n};\n\nexport const workspaceDetails = (workspace: Workspace): WorkspaceDetails => {\n return {\n ...workspaceInfo(workspace),\n deleteProtection: workspace.deleteProtection,\n organizationId: workspace.organizationId,\n folderId: workspace.folderId,\n };\n};\n","import { arg } from \"politty\";\nimport { z } from \"zod\";\nimport { initOperatorClient, type OperatorClient } 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 { assertWritable } from \"@/cli/shared/readonly-guard\";\nimport { workspaceInfo, type WorkspaceInfo } 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 */\nconst createWorkspaceOptionsSchema = z.object({\n name: 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 (n) => !n.startsWith(\"-\") && !n.endsWith(\"-\"),\n \"Name cannot start or end with a hyphen\",\n ),\n region: z.string(),\n deleteProtection: z.boolean().optional(),\n organizationId: z.uuid().optional(),\n folderId: z.uuid().optional(),\n});\n\nexport type CreateWorkspaceOptions = z.input<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\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 // Validate options with zod schema\n const result = createWorkspaceOptionsSchema.safeParse(options);\n if (!result.success) {\n throw new Error(result.error.issues[0].message);\n }\n const validated = result.data;\n\n // Load client and validate region\n const accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n await validateRegion(validated.region, client);\n\n // Create workspace\n const resp = await client.createWorkspace({\n workspaceName: validated.name,\n workspaceRegion: validated.region,\n deleteProtection: validated.deleteProtection ?? false,\n organizationId: validated.organizationId,\n folderId: validated.folderId,\n });\n\n return workspaceInfo(resp.workspace!);\n}\n\nexport const createCommand = defineAppCommand({\n name: \"create\",\n description: \"Create a new Tailor Platform workspace.\",\n args: z\n .object({\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-user\": arg(z.string().optional(), {\n description: \"User email 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 .strict(),\n run: async (args) => {\n // This command does not expose `--profile`, so the guard resolves the\n // active profile from `TAILOR_PLATFORM_PROFILE` only.\n await assertWritable();\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 });\n\n let profileInfo: ProfileInfo | undefined;\n const profileName = args[\"profile-name\"];\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 profileUser = args[\"profile-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 if (!config.users[profileUser]) {\n throw new Error(\n `User \"${profileUser}\" not found.\\nPlease verify your user name and login using 'tailor-sdk login' command.`,\n );\n }\n config.profiles[profileName] = {\n user: profileUser,\n workspace_id: workspace.id,\n ...(args.permission === \"read\" ? { readonly: true } : {}),\n };\n writePlatformConfig(config);\n profileInfo = {\n name: profileName,\n user: profileUser,\n workspaceId: workspace.id,\n permission: args.permission,\n };\n\n if (!args.json) {\n logger.success(`Profile \"${profileName}\" created successfully.`);\n }\n }\n\n if (!args.json) {\n logger.success(`Workspace \"${args.name}\" created successfully.`);\n }\n\n if (args.json && profileInfo) {\n logger.out({ ...workspace, profile: profileInfo });\n return;\n }\n\n logger.out(workspace);\n if (profileInfo) {\n logger.out(\"Profile:\");\n logger.out(profileInfo);\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, 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\";\n\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(result.error.issues[0].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\n .object({\n \"workspace-id\": arg(z.string(), {\n alias: \"w\",\n description: \"Workspace ID\",\n }),\n ...confirmationArgs,\n })\n .strict(),\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 // Confirm deletion if not forced\n if (!args.yes) {\n const confirmation = await prompt.text({\n message: `Enter the workspace name to confirm deletion (${workspace.workspace?.name}):`,\n });\n if (confirmation !== workspace.workspace?.name) {\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 \"${args[\"workspace-id\"]}\" and ${profilesToDelete.length} associated profile(s) deleted successfully.`,\n );\n } else {\n logger.success(`Workspace \"${args[\"workspace-id\"]}\" 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 { workspaceDetails, type WorkspaceDetails } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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 workspaceDetails(response.workspace);\n}\n\nexport const getCommand = defineAppCommand({\n name: \"get\",\n description: \"Show detailed information about a workspace\",\n args: z\n .object({\n ...workspaceArgs,\n })\n .strict(),\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 },\n});\n","import { 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 } from \"@/cli/shared/context\";\nimport { logger } from \"@/cli/shared/logger\";\nimport { workspaceInfo, type WorkspaceInfo } from \"./transform\";\n\nexport interface ListWorkspacesOptions {\n order?: Order;\n limit?: number;\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 accessToken = await loadAccessToken();\n const client = await initOperatorClient(accessToken);\n\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 workspaces.map(workspaceInfo);\n}\n\nexport const listCommand = defineAppCommand({\n name: \"list\",\n description: \"List all Tailor Platform workspaces.\",\n args: z\n .object({\n ...paginationArgs(),\n })\n .strict(),\n run: async (args) => {\n const workspaces = await listWorkspaces({\n order: args.order,\n limit: args.limit,\n });\n logger.out(workspaces, { display: { updatedAt: null } });\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\";\n\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(result.error.issues[0].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\n .object({\n \"workspace-id\": arg(z.string(), {\n alias: \"w\",\n description: \"Workspace ID\",\n }),\n ...confirmationArgs,\n })\n .strict(),\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-proto/tailor/v1/workspace_resource_pb\";\nimport type { WorkspacePlatformUser } from \"@tailor-proto/tailor/v1/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 { stringToRole, validRoles } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\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 .strict(),\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 { userInfo, type UserInfo } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\n ...workspaceArgs,\n ...paginationArgs(),\n })\n .strict(),\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\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\n ...workspaceArgs,\n email: arg(z.email(), {\n description: \"Email address of the user to remove\",\n }),\n ...confirmationArgs,\n })\n .strict(),\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 { stringToRole, validRoles } from \"./transform\";\n\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({ useProfile: true, 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\n .object({\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 .strict(),\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 { resolveTSConfig } from \"pkg-types\";\nimport * as rolldown from \"rolldown\";\nimport { getDistDir } from \"@/cli/shared/dist-dir\";\nimport { platformBundleDefinePlugin } from \"@/cli/shared/platform-bundle-plugin\";\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 * @returns Bundled code\n */\nexport async function bundleQueryScript(engine: QueryEngine): 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 let tsconfig: string | undefined;\n try {\n tsconfig = await resolveTSConfig();\n } catch {\n tsconfig = undefined;\n }\n\n const result = await rolldown.build({\n plugins: [platformBundleDefinePlugin],\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 logLevel: \"silent\",\n } as rolldown.BuildOptions);\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-sdk 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","/**\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 = input[i];\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 { loadFilesWithIgnores } from \"@/cli/services/file-loader\";\nimport { TailorDBTypeSchema } from \"@/parser/service/tailordb\";\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 typeFiles = loadFilesWithIgnores(dbConfig);\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(exportedValue);\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-proto/tailor/v1/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 { bundleQueryScript } from \"../bundler/query/query-bundler\";\nimport { deploymentArgs } 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, 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-proto/tailor/v1/application_resource_pb\";\n\nexport type { QueryEngine } from \"./types\";\n\nconst queryEngineSchema = z.enum(queryEngines);\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(),\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 namespaces[0];\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 [...namespacesFromTypes][0];\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(result.error.issues[0].message);\n }\n\n const accessToken = await loadAccessToken({\n useProfile: true,\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: result.data.machineUser,\n });\n\n if (!machineUserResource) {\n throw new Error(`Machine user ${result.data.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: JSON.stringify({\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: JSON.stringify({\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(result.error.issues[0].message);\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);\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: options.machineUser,\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 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 .object({\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(), {\n alias: \"m\",\n hiddenAlias: \"machineuser\",\n description: \"Machine user name for query execution\",\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 .strict(),\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 };\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\"] ??\n parseBoolean(process.env.TAILOR_PLATFORM_QUERY_NEWLINE_ON_ENTER) ??\n 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 = s._location!.start;\n const end = i + 1 < statements.length ? statements[i + 1]._location!.start : 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(result.result[i], options);\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","/**\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"],"mappings":"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"}