@tailor-platform/sdk 2.11.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/application-BFTkaW6X.mjs +1 -0
- package/dist/{application-CcrP-v7z.mjs → application-D3HlhR3i.mjs} +2 -2
- package/dist/{application-CcrP-v7z.mjs.map → application-D3HlhR3i.mjs.map} +1 -1
- package/dist/cli/commands/generate/seed/bundler.d.mts +2 -2
- package/dist/cli/commands/tailordb/migrate/bundler.d.mts +1 -1
- package/dist/cli/commands/workspace/user/remove.d.mts +1 -1
- package/dist/cli/commands/workspace/user/update.d.mts +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/main.mjs +41 -41
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/shared/script-executor.d.mts +2 -2
- package/dist/completion/zsh-worker.zsh +18 -2
- package/dist/kysely-type-B-BOlXH7.mjs +43 -0
- package/dist/kysely-type-B-BOlXH7.mjs.map +1 -0
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/{register-ts-hook-YqgUg8P7.mjs → register-ts-hook-rBH346V_.mjs} +13 -13
- package/dist/register-ts-hook-rBH346V_.mjs.map +1 -0
- package/dist/seed-CMkupmX8.mjs.map +1 -1
- package/dist/service_pb-CFVlGYdr.mjs +1 -0
- package/dist/{service_pb-BNxUPfP3.mjs → service_pb-CxHztLk1.mjs} +2 -2
- package/dist/{service_pb-BNxUPfP3.mjs.map → service_pb-CxHztLk1.mjs.map} +1 -1
- package/dist/tailor-proto/src/tailor/v1/auth_resource_pb.d.mts +10 -0
- package/dist/workflow-Cs9ISw6j.mjs.map +1 -1
- package/dist/workspace_resource_pb-u9bj6p3i.mjs +2 -0
- package/dist/workspace_resource_pb-u9bj6p3i.mjs.map +1 -0
- package/docs/cli/user.md +43 -7
- package/docs/cli-reference.md +1 -0
- package/package.json +3 -3
- package/dist/application-B4tCGHiQ.mjs +0 -1
- package/dist/kysely-type-CmvAz1Xj.mjs +0 -43
- package/dist/kysely-type-CmvAz1Xj.mjs.map +0 -1
- package/dist/register-ts-hook-YqgUg8P7.mjs.map +0 -1
- package/dist/service_pb-D-xFu9Ub.mjs +0 -1
- package/dist/workspace_resource_pb-B7S-zx4Z.mjs +0 -2
- package/dist/workspace_resource_pb-B7S-zx4Z.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-CcrP-v7z.mjs","names":["sanitizePluginId","toCamelCase","toKebabCase","importExpr","callExpr","callExpr","callExpr","CLIError","exportDecl","CLIError","NAME_PATTERN","KEY_GRAMMAR","KEY_REGEX"],"sources":["../src/parser/app-config/log-level.ts","../src/cli/shared/parse-positive-int.ts","../src/cli/shared/apply-concurrency.ts","../src/cli/shared/client.ts","../src/cli/shared/plugin-import.ts","../src/plugin/guards.ts","../src/cli/commands/generate/plugin-executor-generator.ts","../src/cli/commands/generate/plugin-table-generator.ts","../src/cli/cache/dep-collector-plugin.ts","../src/cli/cache/hasher.ts","../src/cli/cache/bundle-cache.ts","../src/cli/services/workflow/ast-utils.ts","../src/cli/services/workflow/sdk-binding-collector.ts","../src/cli/services/workflow/job-detector.ts","../src/cli/services/workflow/workflow-detector.ts","../src/cli/shared/start-context.ts","../src/cli/services/workflow/start-transformer.ts","../src/cli/shared/bundle-log.ts","../src/cli/shared/bundle-log-level.ts","../src/cli/shared/function-treeshake.ts","../src/cli/shared/platform-bundle-plugin.ts","../src/cli/shared/resolve-tsconfig.ts","../src/cli/shared/tsconfig-paths-plugin.ts","../src/cli/shared/virtual-entry.ts","../src/cli/services/auth/bundler.ts","../src/utils/script-expr.ts","../src/parser/service/tailordb/hook-args-object.ts","../src/parser/service/tailordb/hooks-validate-precompiled-expr.ts","../src/parser/service/tailordb/field.ts","../src/parser/service/permission.ts","../src/parser/service/tailordb/permission.ts","../src/parser/service/tailordb/type-parser.ts","../src/cli/shared/free-variables.ts","../src/cli/services/tailordb/hooks-validate-bundler.ts","../src/cli/services/tailordb/type-name-validation.ts","../src/cli/services/tailordb/service.ts","../src/cli/services/auth/service.ts","../src/cli/shared/bundle-concurrency.ts","../src/cli/shared/forbidden-runtime-globals.ts","../src/cli/shared/runtime-exprs.ts","../src/cli/services/executor/bundler.ts","../src/parser/service/http-adapter/methods.ts","../src/parser/service/http-adapter/schema.ts","../src/cli/services/http-adapter/bundler.ts","../src/cli/services/http-adapter/service.ts","../src/parser/service/resolver/schema.ts","../src/cli/services/resolver/loader.ts","../src/cli/services/resolver/bundler.ts","../src/cli/services/resolver/default-permission.ts","../src/cli/services/resolver/service.ts","../src/cli/services/workflow/source-transformer.ts","../src/cli/services/workflow/bundler.ts","../src/parser/service/workflow/schema.ts","../src/cli/services/workflow/service.ts","../src/cli/shared/auth-namespace.ts","../src/cli/shared/dist-dir.ts","../src/cli/shared/inline-sourcemap.ts","../src/cli/shared/resolver-bundle-key.ts","../src/parser/service/aigateway/schema.ts","../src/parser/service/idp/schema.ts","../src/parser/service/secrets/schema.ts","../src/parser/service/staticwebsite/schema.ts","../src/parser/service/workflow/wait-point-key.ts","../src/cli/services/application.ts"],"sourcesContent":["export const LOG_LEVELS = [\"DEBUG\", \"INFO\", \"WARN\", \"ERROR\", \"SILENT\"] as const;\n\nexport function isLogLevel(value: string): value is (typeof LOG_LEVELS)[number] {\n return (LOG_LEVELS as readonly string[]).includes(value);\n}\n","const POSITIVE_INT_PATTERN = /^\\d*[1-9]\\d*$/;\n\n/**\n * Parse a string value as a positive integer.\n *\n * Only decimal digits are accepted (leading zeros allowed), so `0`, negative\n * numbers, decimals, exponent notation, and signed values are all rejected.\n * Values above `Number.MAX_SAFE_INTEGER` are rejected too: past that point the\n * parsed number no longer represents the digits it came from, so it cannot\n * describe a meaningful limit.\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns The parsed integer, or `undefined` when the value is unset or unrecognized\n */\nexport function parsePositiveInt(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim();\n if (!POSITIVE_INT_PATTERN.test(normalized)) return undefined;\n const parsed = Number.parseInt(normalized, 10);\n return Number.isSafeInteger(parsed) ? parsed : undefined;\n}\n","import pLimit from \"p-limit\";\nimport { parsePositiveInt } from \"./parse-positive-int\";\n\n/**\n * Default cap on concurrent operator RPCs when `TAILOR_APPLY_CONCURRENCY` is\n * unset. Chosen to tame the create burst (a fresh workspace fires one\n * `create*` per resource at once) that triggers the platform-side\n * `already_exists` race on compound creates, while still deploying quickly.\n */\nconst DEFAULT_APPLY_CONCURRENCY = 16;\n\n/**\n * Resolve the maximum number of operator RPCs to run in parallel.\n *\n * Resolution order:\n * 1. `TAILOR_APPLY_CONCURRENCY` env var (positive integer)\n * 2. `DEFAULT_APPLY_CONCURRENCY`\n *\n * A fresh-workspace apply creates every resource at once; firing all of them\n * concurrently overloads the platform, whose responses then come back as\n * `Unavailable`/`ResourceExhausted` and drive retries into the non-idempotent\n * compound-create `already_exists` race. Capping bounds the worst case.\n * @returns Concurrency cap (always >= 1)\n */\nexport function resolveApplyConcurrency(): number {\n return parsePositiveInt(process.env.TAILOR_APPLY_CONCURRENCY) ?? DEFAULT_APPLY_CONCURRENCY;\n}\n\n/**\n * Create a limiter capped at the resolved apply concurrency. The returned\n * function defers a task until a slot is free, then resolves with its result.\n *\n * Share a single instance across all RPCs that should contend for the same\n * budget (e.g. one per operator client) so the cap bounds total in-flight\n * calls, not per-call-site bursts.\n * @returns A limiter that defers tasks beyond the concurrency cap\n */\nexport function createApplyLimiter(): <R>(task: () => Promise<R>) => Promise<R> {\n return pLimit(resolveApplyConcurrency());\n}\n\n/**\n * Comparator that orders `name`-bearing items by `name`, for a stable,\n * reproducible apply order within the concurrency cap.\n *\n * Uses a code-point comparison rather than `localeCompare` so the order does\n * not depend on the runtime's default locale/collation.\n * @param a - Left item\n * @param b - Right item\n * @returns Negative, zero, or positive per code-point ordering of the names\n */\nexport function byName(a: { name: string }, b: { name: string }): number {\n if (a.name < b.name) return -1;\n if (a.name > b.name) return 1;\n return 0;\n}\n","import { OAuth2Client } from \"@badgateway/oauth2-client\";\nimport { create } from \"@bufbuild/protobuf\";\nimport { MethodOptions_IdempotencyLevel } from \"@bufbuild/protobuf/wkt\";\nimport {\n type Client,\n Code,\n ConnectError,\n createClient,\n type Interceptor,\n type Transport,\n type UnaryResponse,\n} from \"@connectrpc/connect\";\nimport { z } from \"zod\";\nimport { createApplyLimiter } from \"./apply-concurrency\";\nimport { logger } from \"./logger\";\nimport { parseBoolean } from \"./parse-boolean\";\nimport { userAgent } from \"./user-agent\";\nimport type { OperatorService } from \"@tailor-platform/tailor-proto/service_pb\";\n\nexport const defaultPlatformBaseUrl = \"https://api.tailor.tech\";\nexport const defaultConsoleBaseUrl = \"https://console.tailor.tech\";\n\nconst defaultOAuth2ClientId = \"cpoc_0Iudir72fqSpqC6GQ58ri1cLAqcq5vJl\";\nconst oauth2DiscoveryEndpoint = \"/.well-known/oauth-authorization-server/oauth2/platform\";\n\nexport type PlatformClientConfig = {\n platformUrl?: string;\n oauth2ClientId?: string;\n consoleUrl?: string;\n};\n\nconst tokenPlatformConfigs = new Map<string, PlatformClientConfig>();\n\nfunction getEnvPlatformUrl(): string | undefined {\n return process.env.TAILOR_PLATFORM_URL ?? process.env.PLATFORM_URL;\n}\n\nfunction getEnvOAuth2ClientId(): string | undefined {\n return process.env.TAILOR_PLATFORM_OAUTH2_CLIENT_ID ?? process.env.PLATFORM_OAUTH2_CLIENT_ID;\n}\n\nexport function normalizeBaseUrl(value: string): string {\n const url = new URL(value);\n url.hash = \"\";\n url.search = \"\";\n return url.toString().replace(/\\/$/, \"\");\n}\n\nexport function getEffectivePlatformConfig(config: PlatformClientConfig = {}) {\n const platformUrl = config.platformUrl ?? getEnvPlatformUrl();\n const oauth2ClientId = config.oauth2ClientId ?? getEnvOAuth2ClientId();\n const consoleUrl = config.consoleUrl ?? process.env.TAILOR_PLATFORM_CONSOLE_URL;\n const effective = {\n ...(platformUrl ? { platformUrl } : {}),\n ...(oauth2ClientId ? { oauth2ClientId } : {}),\n ...(consoleUrl ? { consoleUrl } : {}),\n };\n return Object.keys(effective).length > 0 ? effective : undefined;\n}\n\nexport function rememberPlatformConfigForToken(accessToken: string, config?: PlatformClientConfig) {\n const effectiveConfig = getEffectivePlatformConfig(config);\n if (effectiveConfig) {\n tokenPlatformConfigs.set(accessToken, effectiveConfig);\n } else {\n tokenPlatformConfigs.delete(accessToken);\n }\n}\n\nfunction getPlatformConfigForToken(accessToken: string): PlatformClientConfig | undefined {\n return tokenPlatformConfigs.get(accessToken);\n}\n\nexport function getPlatformBaseUrl(config: PlatformClientConfig = {}) {\n return normalizeBaseUrl(config.platformUrl ?? getEnvPlatformUrl() ?? defaultPlatformBaseUrl);\n}\n\nexport function isDefaultPlatform(config?: PlatformClientConfig): boolean {\n return getPlatformBaseUrl(config) === normalizeBaseUrl(defaultPlatformBaseUrl);\n}\n\nexport function getOAuth2ClientId(config: PlatformClientConfig = {}) {\n return config.oauth2ClientId ?? getEnvOAuth2ClientId() ?? defaultOAuth2ClientId;\n}\n\nfunction inferConsoleBaseUrl(platformBaseUrl: string) {\n const platformUrl = new URL(platformBaseUrl);\n if (platformUrl.hostname.startsWith(\"api.\")) {\n platformUrl.hostname = platformUrl.hostname.replace(/^api\\./, \"console.\");\n return normalizeBaseUrl(platformUrl.toString());\n }\n return defaultConsoleBaseUrl;\n}\n\n/**\n * Redirect an inferred console URL to the console-next host when\n * `TAILOR_CONSOLE_NEXT` is enabled. An explicitly configured console URL\n * (`consoleUrl` / `TAILOR_PLATFORM_CONSOLE_URL`) is never rewritten.\n * @param consoleBaseUrl - Inferred console base URL\n * @returns The console-next base URL, or the input unchanged\n */\nfunction applyConsoleNext(consoleBaseUrl: string): string {\n if (parseBoolean(process.env.TAILOR_CONSOLE_NEXT) !== true) return consoleBaseUrl;\n const url = new URL(consoleBaseUrl);\n url.hostname = url.hostname.replace(/^console\\./, \"console-next.\");\n return normalizeBaseUrl(url.toString());\n}\n\nexport function getConsoleBaseUrl(config: PlatformClientConfig = {}) {\n if (config.consoleUrl) return normalizeBaseUrl(config.consoleUrl);\n if (config.platformUrl) {\n const inferredUrl = inferConsoleBaseUrl(config.platformUrl);\n if (inferredUrl !== defaultConsoleBaseUrl) return applyConsoleNext(inferredUrl);\n }\n if (process.env.TAILOR_PLATFORM_CONSOLE_URL)\n return normalizeBaseUrl(process.env.TAILOR_PLATFORM_CONSOLE_URL);\n return applyConsoleNext(inferConsoleBaseUrl(getPlatformBaseUrl(config)));\n}\n\n/**\n * Initialize an OAuth2 client for Tailor Platform.\n * @param config - Optional platform connection settings\n * @returns Configured OAuth2 client\n */\nexport function initOAuth2Client(config?: PlatformClientConfig) {\n return new OAuth2Client({\n clientId: getOAuth2ClientId(config),\n server: getPlatformBaseUrl(config),\n discoveryEndpoint: oauth2DiscoveryEndpoint,\n });\n}\n\nexport type OperatorClient = Client<typeof OperatorService>;\n\n/**\n * Initialize an Operator client with the given access token.\n * @param accessToken - Access token for authentication\n * @param config - Optional platform connection settings\n * @returns Configured Operator client\n */\nexport async function initOperatorClient(accessToken: string, config?: PlatformClientConfig) {\n const platformConfig = config ?? getPlatformConfigForToken(accessToken);\n const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([\n import(\"#/cli/telemetry/interceptor\"),\n import(\"@tailor-platform/tailor-proto/service_pb\"),\n ]);\n\n const interceptors: Interceptor[] = [\n await userAgentInterceptor(),\n await bearerTokenInterceptor(accessToken),\n retryInterceptor(),\n errorHandlingInterceptor(),\n createTracingInterceptor(),\n // Innermost: gates the actual network attempt so each retry re-acquires a\n // slot and backoff waits happen outside the cap.\n concurrencyLimitInterceptor(),\n ];\n\n const transport = await createTransport(getPlatformBaseUrl(platformConfig), interceptors);\n return createClient(OperatorService, transport);\n}\n\n/**\n * Create a Connect transport using connect-node (HTTP/2).\n *\n * connect-node works on both Node.js and Bun. connect-web is not used because\n * it does not support client_streaming, which is required for function uploads.\n * @param baseUrl - Base URL for the transport\n * @param interceptors - Request interceptors\n * @returns Configured transport\n */\nexport async function createTransport(\n baseUrl: string,\n interceptors: Interceptor[],\n): Promise<Transport> {\n const { createConnectTransport } = await import(\"@connectrpc/connect-node\");\n return createConnectTransport({ httpVersion: \"2\", baseUrl, interceptors });\n}\n\n/**\n * Create an interceptor that sets a User-Agent header.\n * @returns User-Agent interceptor\n */\nasync function userAgentInterceptor(): Promise<Interceptor> {\n const ua = await userAgent();\n return (next) => async (req) => {\n req.header.set(\"User-Agent\", ua);\n return await next(req);\n };\n}\n\nexport { userAgent };\n\n/**\n * Create an interceptor that sets the Authorization bearer token.\n * @param accessToken - Access token to use\n * @returns Bearer token interceptor\n */\nasync function bearerTokenInterceptor(accessToken: string): Promise<Interceptor> {\n return (next) => async (req) => {\n req.header.set(\"Authorization\", `Bearer ${accessToken}`);\n return await next(req);\n };\n}\n\n/**\n * Create an interceptor that retries failed unary requests with backoff.\n *\n * Retries unary methods on `Unavailable`/`ResourceExhausted`, and\n * `Aborted`/`Internal` only for methods declared side-effect-free or idempotent,\n * up to 3 attempts. Workspace creation is excluded because it has no idempotency\n * key and a lost response is ambiguous.\n * As a targeted exception for the deploy/apply flow, a post-retry `AlreadyExists`\n * from an allowlisted Create (see `RETRY_SAFE_CREATE_METHODS`) is treated as\n * success, since it means a prior attempt already committed the resource\n * server-side. A first-attempt `AlreadyExists` from such a Create still\n * surfaces, but is routed to crash/error reporting first (the top-level handler\n * skips `ConnectError`), so the otherwise-silent compound-create race is\n * trackable.\n * @internal\n * @returns Retry interceptor\n */\nexport function retryInterceptor(): Interceptor {\n return (next) => async (req) => {\n if (req.stream) {\n return await next(req);\n }\n\n let lastError: unknown;\n for (let i = 0; i < MAX_RETRY_ATTEMPTS; i++) {\n if (i > 0) {\n await waitRetryBackoff(i);\n }\n\n try {\n return await next(req);\n } catch (error) {\n // A retry that comes back AlreadyExists is treated as success: a prior\n // attempt (the one whose retriable error sent us here) already created\n // the resource server-side, but its response was lost as\n // Unavailable/ResourceExhausted under load. The identical retry then\n // races against that committed write and fails with `already_exists`.\n // Restricted to RETRY_SAFE_CREATE_METHODS (deploy creates whose response\n // body is unused) and to actual retries (i > 0).\n if (isRetrySafeCreateAlreadyExists(error, req.method.name)) {\n if (i > 0) {\n logger.debug(\n `retry: ${req.method.name} returned AlreadyExists on attempt ${i + 1}; ` +\n `treating as success (prior attempt likely committed)`,\n );\n return synthesizeEmptyUnaryResponse(req);\n }\n // First-attempt AlreadyExists on a retry-safe create: no retry of ours\n // preceded it, so the resource was committed out-of-band (a concurrent\n // or non-idempotent compound create under load — #1350). The top-level\n // handler skips ConnectError, so route it to error tracking here before\n // letting it surface as the deploy error.\n const { reportCrash } = await import(\"#/cli/crashreport/index\");\n await reportCrash(error, \"handledError\");\n }\n if (req.method.name !== \"CreateWorkspace\" && isRetirable(error, req.method.idempotency)) {\n lastError = error;\n logger.debug(\n `retry: ${req.method.name} attempt ${i + 1} failed with ` +\n `${connectCodeName(error)}; retrying`,\n );\n continue;\n }\n throw error;\n }\n }\n throw lastError;\n };\n}\n\n/**\n * Create an interceptor that caps the number of concurrent unary RPCs.\n *\n * A fresh-workspace apply fires one `create*` per resource at once; left\n * unbounded, the platform sheds load as `Unavailable`/`ResourceExhausted`,\n * which drives retries into the non-idempotent compound-create `already_exists`\n * race (#1350). One shared limiter per client bounds total in-flight calls\n * across every deploy resource, not just a single call site. Streaming RPCs\n * (e.g. function uploads) are not gated.\n * @internal\n * @returns Concurrency-limiting interceptor\n */\nexport function concurrencyLimitInterceptor(): Interceptor {\n const limit = createApplyLimiter();\n return (next) => async (req) => {\n if (req.stream) {\n return await next(req);\n }\n return await limit(() => next(req));\n };\n}\n\n/**\n * Human-readable name for the Connect status code of an error, for diagnostics.\n * @param error - Error thrown by a request (expected to be a ConnectError)\n * @returns The Code name (e.g., \"Unavailable\"), or \"unknown\" for non-ConnectError\n */\nfunction connectCodeName(error: unknown): string {\n return error instanceof ConnectError ? Code[error.code] : \"unknown\";\n}\n\n/**\n * Create RPCs for which a post-retry `AlreadyExists` may be treated as success.\n *\n * Membership is deliberately an allowlist, not `startsWith(\"Create\")`: swallowing\n * synthesizes an empty response (see `synthesizeEmptyUnaryResponse`), which is only\n * safe when every caller tolerates an empty response body. These are the deploy/apply\n * resource creations that fire under heavy parallelism and discard their response —\n * except `CreateSecretManagerSecret`, whose caller reads `secret.updateTime` but\n * degrades safely when it is absent (the next deploy re-updates the secret).\n *\n * Intentionally excluded because their callers read the response body — swallowing\n * would hand back an empty message and corrupt downstream state:\n * - `CreateIdPClient` (uses `resp.client.clientSecret` to seed the secret vault)\n * - `CreateWorkflowJobFunction` (uses `response.jobFunction.version`)\n * - `CreateWorkspace` / `CreatePersonalAccessToken` / `CreateDeployment` /\n * `CreateOrganizationFolder` (interactive commands that return created data)\n *\n * `CreateFunctionRegistry` is client-streaming and never reaches this path\n * (streaming requests bypass the retry loop entirely).\n *\n * An allowlist miss is safe: the resource simply loses race protection and an\n * `already_exists` surfaces loudly, as before — never a silent empty response.\n *\n * A drift guard (see client.test.ts) fails CI if any `client.create*` used in the\n * deploy flow is neither listed here nor explicitly classified as response-consuming,\n * so a newly added apply create cannot silently miss this list.\n * @internal\n */\nexport const RETRY_SAFE_CREATE_METHODS: ReadonlySet<string> = new Set([\n \"CreateAIGateway\",\n \"CreateApplication\",\n \"CreateAuthConnection\",\n \"CreateAuthHook\",\n \"CreateAuthIDPConfig\",\n \"CreateAuthMachineUser\",\n \"CreateAuthOAuth2Client\",\n \"CreateAuthSCIMConfig\",\n \"CreateAuthSCIMResource\",\n \"CreateAuthService\",\n \"CreateExecutorExecutor\",\n \"CreateIdPService\",\n \"CreatePipelineResolver\",\n \"CreatePipelineService\",\n \"CreateSecretManagerSecret\",\n \"CreateSecretManagerVault\",\n \"CreateStaticWebsite\",\n \"CreateTailorDBGQLPermission\",\n \"CreateTailorDBService\",\n \"CreateTailorDBType\",\n \"CreateTenantConfig\",\n \"CreateUserProfileConfig\",\n \"CreateWorkflow\",\n \"CreateWorkflowJobFunctionExecutionPolicy\",\n]);\n\n/**\n * Whether an error is an `AlreadyExists` from a retry-safe Create RPC.\n *\n * Only `AlreadyExists` stands in for \"my prior write already landed\"; for other\n * verbs/codes it would be a real conflict that must surface.\n * @param error - Error thrown by the request\n * @param methodName - RPC method name (e.g., \"CreateTailorDBType\")\n * @returns True if the error is an `AlreadyExists` from a retry-safe Create method\n */\nfunction isRetrySafeCreateAlreadyExists(error: unknown, methodName: string): boolean {\n return (\n error instanceof ConnectError &&\n error.code === Code.AlreadyExists &&\n RETRY_SAFE_CREATE_METHODS.has(methodName)\n );\n}\n\n/**\n * Build a default (empty) unary response for the request's output message.\n *\n * Used when a retried Create is determined to have already succeeded on a prior\n * attempt: callers in the deploy pipeline ignore Create response bodies, so an\n * empty message faithfully represents the already-applied state.\n * @param req - Unary request whose output schema is used\n * @returns A synthesized unary response with an empty output message\n */\nfunction synthesizeEmptyUnaryResponse(req: {\n service: UnaryResponse[\"service\"];\n method: UnaryResponse[\"method\"];\n}): UnaryResponse {\n return {\n stream: false,\n service: req.service,\n method: req.method,\n header: new Headers(),\n message: create(req.method.output),\n trailer: new Headers(),\n };\n}\n\n/**\n * Base delay (ms) for the first retry. Subsequent attempts double it.\n *\n * Kept relatively large so a retry does not immediately race an original request\n * that is still settling server-side under load (e.g. a compound create whose\n * response was lost), which is what triggers the `already_exists` race.\n */\nconst RETRY_BASE_DELAY_MS = 500;\n\n/** Maximum number of attempts, including the initial one, for a retried request. */\nconst MAX_RETRY_ATTEMPTS = 3;\n\n/**\n * Wait for an exponential backoff delay with jitter.\n * @param attempt - Current retry attempt number (1-based)\n * @returns Promise that resolves after the delay\n */\nfunction waitRetryBackoff(attempt: number) {\n const base = RETRY_BASE_DELAY_MS * 2 ** (attempt - 1);\n const jitter = 0.1 * (Math.random() * 2 - 1);\n const backoff = base * (1 + jitter);\n return new Promise((resolve) => setTimeout(resolve, backoff));\n}\n\n/**\n * Determine whether the given error is retriable for the method idempotency.\n * @param error - Error thrown by the request\n * @param idempotency - Method idempotency level\n * @returns True if the error should be retried\n */\nfunction isRetirable(error: unknown, idempotency: MethodOptions_IdempotencyLevel) {\n if (!(error instanceof ConnectError)) {\n return false;\n }\n\n switch (error.code) {\n case Code.ResourceExhausted:\n case Code.Unavailable:\n return true;\n case Code.Aborted:\n case Code.Internal:\n return (\n idempotency === MethodOptions_IdempotencyLevel.NO_SIDE_EFFECTS ||\n idempotency === MethodOptions_IdempotencyLevel.IDEMPOTENT\n );\n default:\n return false;\n }\n}\n\n/**\n * Create an interceptor that enhances error messages from the Operator API.\n * @internal\n * @returns Error handling interceptor\n */\nexport function errorHandlingInterceptor(): Interceptor {\n return (next) => async (req) => {\n try {\n return await next(req);\n } catch (error) {\n if (error instanceof ConnectError) {\n const { operation, resourceType } = parseMethodName(req.method.name);\n const identity = formatRequestIdentity(req.message, req.method.name);\n\n // Re-throw as ConnectError with enhanced message to avoid re-wrapping\n // Use rawMessage to avoid duplicating the error code prefix\n throw new ConnectError(\n `Failed to ${operation} ${resourceType}${identity}: ${error.rawMessage}`,\n error.code,\n error.metadata,\n );\n }\n throw error;\n }\n };\n}\n\n/**\n * @internal\n * @param methodName - RPC method name (e.g., \"CreateWorkspace\")\n * @returns Parsed operation and resource type\n */\nexport function parseMethodName(methodName: string): {\n operation: string;\n resourceType: string;\n} {\n const match = methodName.match(/^(Create|Update|Delete|Set|List|Get)(.+)$/);\n if (!match) {\n return { operation: \"perform\", resourceType: \"resource\" };\n }\n\n const [, action, resource] = match as [string, string, string];\n return { operation: action.toLowerCase(), resourceType: resource };\n}\n\n// Identifier fields surfaced in enhanced error messages. Never add fields\n// that can carry secrets or PII (tokens, scripts, query args, secret values,\n// emails), and never add a suffix that could match them (e.g. \"Key\" would\n// match future key material).\n//\n// Platform-wide naming conventions: on every API, a top-level string field\n// with one of these names or suffixes is a resource identifier.\nconst IDENTITY_KEYS = new Set([\"name\", \"id\"]);\nconst IDENTITY_KEY_SUFFIXES = [\"Name\", \"Id\", \"Namespace\"];\n// Key read from nested resource messages (e.g. the type in a create request).\n// Only materialized protobuf messages (marked by $typeName) qualify: map and\n// Struct fields materialize without one, and their entries can carry values\n// the SDK does not control (e.g. metadata labels merged from the remote).\nconst NESTED_IDENTITY_KEY = \"name\";\n// API-specific identifier fields, scoped to the RPC methods that define them\n// so a same-named field on an unrelated API is never surfaced by accident.\nconst METHOD_IDENTITY_KEYS: Readonly<Record<string, readonly string[]>> = {\n GetMetadata: [\"trn\"],\n SetMetadata: [\"trn\"],\n AddCustomDomain: [\"domain\"],\n GetCustomDomain: [\"domain\"],\n RemoveCustomDomain: [\"domain\"],\n CreateWorkflowJobFunctionExecutionPolicy: [\"executionPolicyKey\"],\n UpdateWorkflowJobFunctionExecutionPolicy: [\"executionPolicyKey\"],\n GetWorkflowJobFunctionExecutionPolicyByKey: [\"executionPolicyKey\"],\n};\n\nfunction isIdentityKey(key: string, methodName: string): boolean {\n if (key.startsWith(\"$\")) {\n return false;\n }\n return (\n IDENTITY_KEYS.has(key) ||\n IDENTITY_KEY_SUFFIXES.some((suffix) => key.endsWith(suffix)) ||\n (METHOD_IDENTITY_KEYS[methodName]?.includes(key) ?? false)\n );\n}\n\n/**\n * Format an allowlisted identity suffix for enhanced error messages.\n *\n * Only resource identifiers are included — the rest of the request payload\n * can carry credentials and must never reach terminal or CI logs.\n * @param message - Request message to extract identifiers from\n * @param methodName - RPC method name used to resolve method-scoped identifiers\n * @returns Identity suffix like \" (namespaceName: x, type.name: y)\", or an empty string\n */\nfunction formatRequestIdentity(message: unknown, methodName: string): string {\n if (typeof message !== \"object\" || message === null) {\n return \"\";\n }\n const parts: string[] = [];\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\" && value !== \"\" && isIdentityKey(key, methodName)) {\n parts.push(`${key}: ${value}`);\n } else if (\n !key.startsWith(\"$\") &&\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof (value as Record<string, unknown>).$typeName === \"string\"\n ) {\n const nestedName = (value as Record<string, unknown>)[NESTED_IDENTITY_KEY];\n if (typeof nestedName === \"string\" && nestedName !== \"\") {\n parts.push(`${key}.${NESTED_IDENTITY_KEY}: ${nestedName}`);\n }\n }\n }\n return parts.length === 0 ? \"\" : ` (${parts.join(\", \")})`;\n}\n\nexport const MAX_PAGE_SIZE = 1000;\n\n/**\n * Fetch all paginated resources by repeatedly calling the given function.\n * @template T\n * @param fn - Page fetcher returning items and next page token\n * @returns All fetched items\n */\nexport async function fetchAll<T>(\n fn: (pageToken: string, maxPageSize: number) => Promise<[T[], string]>,\n) {\n const items: T[] = [];\n let pageToken = \"\";\n\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const [batch, nextPageToken] = await fn(pageToken, MAX_PAGE_SIZE);\n items.push(...batch);\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!nextPageToken) break;\n pageToken = nextPageToken;\n }\n return items;\n}\n\n/**\n * @internal\n * @param error - Error value to inspect\n * @returns Whether the error is a Connect NotFound error\n */\nexport function isNotFoundError(error: unknown): boolean {\n return error instanceof ConnectError && error.code === Code.NotFound;\n}\n\n/**\n * Fetch all paginated resources, treating an absent resource group as empty.\n * @template T\n * @param fn - Page fetcher returning items and next page token\n * @returns Items fetched before pagination completes or the fetcher raises NotFound\n */\nexport async function fetchAllTolerant<T>(\n fn: (pageToken: string, maxPageSize: number) => Promise<[T[], string]>,\n): Promise<T[]> {\n return await fetchAll(async (pageToken, maxPageSize) => {\n try {\n return await fn(pageToken, maxPageSize);\n } catch (error) {\n if (isNotFoundError(error)) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n}\n\n/**\n * Fetch a single resource, treating NotFound as an absent value.\n * @template T\n * @param fn - Resource getter\n * @returns Fetched resource, or undefined when the getter raises NotFound\n */\nexport async function getOrNull<T>(fn: () => Promise<T>): Promise<T | undefined> {\n try {\n return await fn();\n } catch (error) {\n if (isNotFoundError(error)) {\n return undefined;\n }\n throw error;\n }\n}\n\ninterface FetchPagedOptions {\n /** Maximum number of items to return. 0 or undefined means unlimited. */\n limit?: number;\n}\n\n/**\n * Fetch paginated resources with an optional upper bound on the number of\n * items returned. When `limit` is 0 or undefined the function behaves\n * like `fetchAll` and returns every page. When `limit` is positive the\n * function stops once enough items are collected, requesting smaller\n * pages as it approaches the boundary.\n * @template T\n * @param fn - Page fetcher returning items and next page token\n * @param options - Pagination options\n * @returns Fetched items (length <= limit when limit > 0)\n */\nexport async function fetchPaged<T>(\n fn: (pageToken: string, pageSize: number) => Promise<[T[], string]>,\n options?: FetchPagedOptions,\n): Promise<T[]> {\n const limit = options?.limit;\n const unbounded = limit === undefined || limit === 0;\n const items: T[] = [];\n let pageToken = \"\";\n\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const pageSize = unbounded ? MAX_PAGE_SIZE : Math.min(limit - items.length, MAX_PAGE_SIZE);\n if (!unbounded && pageSize <= 0) break;\n\n const [batch, nextPageToken] = await fn(pageToken, pageSize);\n items.push(...batch);\n if (!unbounded && items.length >= limit) break;\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!nextPageToken) break;\n pageToken = nextPageToken;\n }\n\n if (!unbounded && items.length > limit) {\n return items.slice(0, limit);\n }\n return items;\n}\n\n/**\n * Fetch user info from the Tailor Platform userinfo endpoint.\n * @param accessToken - Access token for the current user\n * @param config - Optional platform connection settings\n * @returns Parsed user info\n */\nexport async function fetchUserInfo(accessToken: string, config?: PlatformClientConfig) {\n const userInfoUrl = new URL(\"/auth/platform/userinfo\", getPlatformBaseUrl(config)).href;\n const resp = await fetch(userInfoUrl, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"User-Agent\": await userAgent(),\n },\n });\n if (!resp.ok) {\n throw new Error(`Failed to fetch user info: ${resp.statusText}`);\n }\n\n const rawJson = await resp.json();\n // strip unknown keys\n const schema = z.object({\n sub: z.string(),\n email: z.string(),\n });\n return schema.parse(rawJson);\n}\n\n// Converting \"name:url\" patterns to actual Static Website URLs\n/**\n * Options for `resolveStaticWebsiteUrls`.\n */\nexport type ResolveStaticWebsiteUrlsOptions = {\n /**\n * Names of static websites that are defined locally in the current\n * configuration. When the platform-side lookup for a name in this set\n * fails specifically with a `NotFound` error, the warning is suppressed\n * and the original `name:url[/path]` pattern is returned unresolved\n * instead of being dropped.\n *\n * Use this from plan-phase callers to avoid noisy warnings on the first\n * deployment, where the static website will be created later in the same\n * apply run. Other failure modes (\"URL not yet assigned\", transient RPC\n * errors, permission errors) are intentionally not suppressed so that\n * real platform problems still surface during planning.\n */\n expectedLocalNames?: ReadonlySet<string>;\n};\n\n/**\n * Resolve \"name:url\" patterns to actual Static Website URLs.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param urls - URLs or name:url patterns\n * @param context - Logging context (e.g., \"CORS\", \"OAuth2 redirect URIs\")\n * @param options - Optional behavior overrides\n * @returns Resolved URLs (or the original pattern for entries marked as\n * expected-but-not-yet-deployed via `options.expectedLocalNames`)\n */\nexport async function resolveStaticWebsiteUrls(\n client: OperatorClient,\n workspaceId: string,\n urls: string[] | undefined,\n context: string, // for logging context (e.g., \"CORS\", \"OAuth2 redirect URIs\")\n options: ResolveStaticWebsiteUrlsOptions = {},\n): Promise<string[]> {\n if (!urls) {\n return [];\n }\n\n const { expectedLocalNames } = options;\n\n const results = await Promise.all(\n urls.map(async (url) => {\n const urlPattern = /:url(\\/.*)?$/;\n const match = url.match(urlPattern);\n\n if (match && match.index !== undefined) {\n const siteName = url.substring(0, match.index);\n const pathSuffix = match[1] || \"\";\n\n try {\n const response = await client.getStaticWebsite({\n workspaceId,\n name: siteName,\n });\n\n if (response.staticwebsite?.url) {\n return [response.staticwebsite.url + pathSuffix];\n }\n logger.warn(\n `Static website \"${siteName}\" has no URL assigned yet. Excluding from ${context}.`,\n );\n return [];\n } catch (error) {\n if (isNotFoundError(error) && expectedLocalNames?.has(siteName)) {\n return [url];\n }\n logger.warn(\n `Static website \"${siteName}\" not found for ${context} configuration. Excluding from ${context}.`,\n );\n return [];\n }\n }\n return [url];\n }),\n );\n\n return results.flat();\n}\n\n/**\n * Fetch an OAuth2 access token for a machine user.\n * @param url - OAuth2 server base URL\n * @param clientId - Client ID for the machine user\n * @param clientSecret - Client secret for the machine user\n * @returns Access token\n */\nexport async function fetchMachineUserToken(url: string, clientId: string, clientSecret: string) {\n const tokenEndpoint = new URL(\"/oauth2/token\", url).href;\n const formData = new URLSearchParams();\n formData.append(\"grant_type\", \"client_credentials\");\n formData.append(\"client_id\", clientId);\n formData.append(\"client_secret\", clientSecret);\n\n const request = {\n method: \"POST\",\n headers: {\n \"User-Agent\": await userAgent(),\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: formData,\n };\n const resp = await withConnectTimeoutRetry(\"machine user token request\", () =>\n fetch(tokenEndpoint, request),\n );\n if (!resp.ok) {\n const body = await resp.text().catch(() => \"\");\n throw new Error(\n `Failed to fetch machine user token: ${resp.status} ${resp.statusText} ${body.slice(0, 500)}`,\n );\n }\n const rawJson = await resp.json();\n\n // strip unknown keys\n const schema = z.object({\n token_type: z.string(),\n access_token: z.string(),\n expires_in: z.number(),\n });\n return schema.parse(rawJson);\n}\n\nfunction isUndiciConnectTimeout(error: unknown): boolean {\n if (!(error instanceof TypeError)) {\n return false;\n }\n const cause = error.cause;\n return cause instanceof Error && \"code\" in cause && cause.code === \"UND_ERR_CONNECT_TIMEOUT\";\n}\n\n/**\n * Retry a request that failed before the connection was established.\n *\n * Only `UND_ERR_CONNECT_TIMEOUT` is retried: the request provably never reached\n * the server, so replaying it cannot duplicate a server-side effect.\n * @param label - Request description for the retry debug log\n * @param send - Sends the request; called once per attempt\n * @returns The first successful result\n */\nasync function withConnectTimeoutRetry<T>(label: string, send: () => Promise<T>): Promise<T> {\n for (let attempt = 1; ; attempt++) {\n try {\n return await send();\n } catch (error) {\n if (!isUndiciConnectTimeout(error) || attempt >= MAX_RETRY_ATTEMPTS) {\n throw error;\n }\n logger.debug(\n `retry: ${label} attempt ${attempt} failed with UND_ERR_CONNECT_TIMEOUT; retrying`,\n );\n await waitRetryBackoff(attempt);\n }\n }\n}\n\n/**\n * Fetch an OAuth2 token for a platform machine user via client_credentials grant.\n * @param clientId - Client ID for the platform machine user\n * @param clientSecret - Client secret for the platform machine user\n * @param config - Optional platform connection settings\n * @returns OAuth2 token\n */\nexport async function fetchPlatformMachineUserToken(\n clientId: string,\n clientSecret: string,\n config?: PlatformClientConfig,\n) {\n const server = getPlatformBaseUrl(config);\n // A new client per attempt: OAuth2Client caches its discovery promise even when\n // it rejects, so a reused client would replay the failure without re-requesting.\n return await withConnectTimeoutRetry(\"platform machine user token request\", () =>\n new OAuth2Client({\n clientId,\n clientSecret,\n server,\n discoveryEndpoint: oauth2DiscoveryEndpoint,\n }).clientCredentials(),\n );\n}\n\n/**\n * Close the global HTTP connection pool to prevent libuv UV_HANDLE_CLOSING\n * assertion failure on Windows at process exit (Node.js 23.x+).\n * See: https://github.com/nodejs/node/issues/56645\n *\n * The pool is reached through the global dispatcher symbol rather than the `undici`\n * package: importing that package installs its own Agent over these same globals,\n * replacing the HTTP stack Node's `fetch` already uses. The symbol is versioned per\n * Dispatcher API generation, and the newest one wins because older symbols hold a\n * wrapper around that same pool — closing both would destroy it twice.\n */\nexport async function closeConnectionPool() {\n const globals = globalThis as Record<symbol, { close?: () => Promise<void> } | undefined>;\n const dispatcher =\n globals[Symbol.for(\"undici.globalDispatcher.2\")] ??\n globals[Symbol.for(\"undici.globalDispatcher.1\")];\n if (typeof dispatcher?.close === \"function\") {\n await dispatcher.close();\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\n\n/**\n * Collect base directories for resolving plugin import paths.\n * @param configPath - Path to tailor.config.ts\n * @returns Ordered list of base directories\n */\nexport function getPluginImportBaseDirs(configPath?: string): string[] {\n if (configPath) {\n return [path.dirname(configPath)];\n }\n\n return [process.cwd()];\n}\n\n/**\n * Resolve a relative plugin import path against candidate base directories.\n * @param pluginImportPath - Relative plugin import path\n * @param baseDirs - Candidate base directories\n * @returns Absolute path if found, otherwise null\n */\nexport function resolveRelativePluginImportPath(\n pluginImportPath: string,\n baseDirs: string[],\n): string | null {\n if (!pluginImportPath.startsWith(\".\")) {\n return null;\n }\n\n for (const baseDir of baseDirs) {\n const absolutePath = path.resolve(baseDir, pluginImportPath);\n if (fs.existsSync(absolutePath)) {\n return absolutePath;\n }\n }\n\n return null;\n}\n","// Runtime guards and helpers for plugin authoring types.\n//\n// These live outside plugin/types.ts (a pure type module) because they are\n// runtime functions. The types they operate on are imported type-only.\nimport type {\n DependencyKind,\n PluginGeneratedExecutor,\n PluginGeneratedExecutorWithFile,\n} from \"./types\";\n\n/**\n * Reads a table name without assuming plugin output is a valid table object.\n * @param table - Raw table value returned by a plugin hook.\n * @returns The table name when it is a string; otherwise, undefined.\n */\nexport function getRawPluginTableName(table: unknown): string | undefined {\n const name =\n typeof table === \"object\" && table !== null && \"name\" in table ? table.name : undefined;\n return typeof name === \"string\" ? name : undefined;\n}\n\n/**\n * Collects the generation-time dependency kinds a plugin requires.\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\n/**\n * Checks if a plugin executor uses file-based resolution.\n * @param executor - The plugin executor to check.\n * @returns True if the executor uses file-based resolution.\n */\nexport function isPluginExecutorWithFile(\n executor: PluginGeneratedExecutor,\n): executor is PluginGeneratedExecutorWithFile {\n return \"resolve\" in executor && \"context\" in executor;\n}\n","/**\n * Plugin Executor Generator\n *\n * Generates TypeScript files for plugin-generated executors.\n * Supports both legacy format (inline trigger/operation) and new format (executorFile/context).\n */\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"pathe\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport {\n getPluginImportBaseDirs,\n resolveRelativePluginImportPath,\n} from \"#/cli/shared/plugin-import\";\nimport { isPluginExecutorWithFile } from \"#/plugin/guards\";\nimport {\n type PluginGeneratedExecutorLegacy,\n type PluginGeneratedExecutorWithFile,\n type PluginTriggerConfig,\n type PluginOperationConfig,\n type PluginInjectMap,\n type PluginExecutorContext,\n} from \"#/plugin/types\";\nimport { assertDefined } from \"#/utils/assert\";\nimport ml from \"#/utils/multiline\";\nimport type {\n PluginExecutorInfoExtended,\n PluginTableGenerationResult,\n SourceTableInfo,\n} from \"#/plugin/manager\";\n\n/**\n * Information needed for table import resolution.\n */\ninterface TableImportInfo {\n /** Variable name to use in generated code */\n variableName: string;\n /** Import path for the table */\n importPath: string;\n}\n\n/**\n * Generate TypeScript files for plugin-generated executors.\n * These files will be processed by the standard executor bundler.\n * @param executors - Array of plugin executor information\n * @param outputDir - Base output directory (e.g., .tailor)\n * @param tableGenerationResult - Result from plugin table generation (for import resolution)\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @param configPath - Path to tailor.config.ts (used for resolving plugin import paths)\n * @returns Array of generated file paths\n */\nexport function generatePluginExecutorFiles(\n executors: ReadonlyArray<PluginExecutorInfoExtended>,\n outputDir: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n configPath?: string,\n): string[] {\n if (executors.length === 0) {\n return [];\n }\n\n const generatedFiles: string[] = [];\n const baseDirs = getPluginImportBaseDirs(configPath);\n\n for (const info of executors) {\n const filePath = generateSingleExecutorFile(\n info,\n outputDir,\n tableGenerationResult,\n sourceTableInfoMap,\n baseDirs,\n );\n generatedFiles.push(filePath);\n\n const relativePath = path.relative(process.cwd(), filePath);\n logger.log(\n ` Plugin Executor File: ${styles.success(relativePath)} from plugin ${styles.info(info.pluginId)}`,\n );\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate a single executor file.\n * @param info - Plugin executor metadata and definition\n * @param outputDir - Base output directory (e.g., .tailor)\n * @param tableGenerationResult - Result from plugin table generation\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns Absolute path to the generated file\n */\nfunction generateSingleExecutorFile(\n info: PluginExecutorInfoExtended,\n outputDir: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n baseDirs: string[] = [],\n): string {\n const pluginDir = sanitizePluginId(info.pluginId);\n const executorOutputDir = path.join(outputDir, pluginDir, \"executors\");\n fs.mkdirSync(executorOutputDir, { recursive: true });\n\n const fileName = sanitizeExecutorFileName(info.executor.name);\n const filePath = path.join(executorOutputDir, `${fileName}.ts`);\n\n let content: string;\n if (isPluginExecutorWithFile(info.executor)) {\n content = generateExecutorFileContentNew(\n info,\n info.executor,\n outputDir,\n tableGenerationResult,\n sourceTableInfoMap,\n baseDirs,\n );\n } else {\n content = generateExecutorFileContentLegacy(info.executor);\n }\n\n fs.writeFileSync(filePath, content);\n return filePath;\n}\n\n/**\n * Generate TypeScript file content for new format executor (dynamic import).\n * Uses the executor's resolve function to dynamically import the module.\n * @param info - Plugin executor information\n * @param executor - Executor definition with resolve\n * @param outputDir - Base output directory\n * @param tableGenerationResult - Result from plugin table generation\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns TypeScript source code for executor file\n */\nfunction generateExecutorFileContentNew(\n info: PluginExecutorInfoExtended,\n executor: PluginGeneratedExecutorWithFile,\n outputDir: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n baseDirs: string[] = [],\n): string {\n const { resolve, context } = executor;\n const pluginDir = sanitizePluginId(info.pluginId);\n const executorOutputDir = path.join(outputDir, pluginDir, \"executors\");\n\n const executorImportPath = resolveExecutorImportPath(\n resolve,\n info.pluginImportPath,\n executorOutputDir,\n baseDirs,\n );\n\n // Collect table imports from context\n const tableImports = collectTableImports(\n context,\n outputDir,\n info.pluginId,\n tableGenerationResult,\n sourceTableInfoMap,\n );\n\n // Generate import statements\n const imports: string[] = [];\n\n for (const [, importInfo] of tableImports) {\n imports.push(`import { ${importInfo.variableName} } from \"${importInfo.importPath}\";`);\n }\n\n // Generate context object code\n const contextCode = generateContextCode(context, tableImports);\n\n return ml /* ts */ `\n /**\n * Auto-generated executor by plugin: ${info.pluginId}\n * DO NOT EDIT - This file is generated by @tailor-platform/sdk\n */\n ${imports.join(\"\\n\")}\n\n const { default: executorFactory } = await import(${JSON.stringify(executorImportPath)});\n if (typeof executorFactory !== \"function\") {\n throw new Error(\n \"Plugin executor module must export a default function created by withPluginContext().\",\n );\n }\n export default executorFactory(${contextCode});\n `;\n}\n\n/**\n * Collect table imports needed for context.\n * @param context - Executor context values from plugin\n * @param outputDir - Base output directory for generated files\n * @param pluginId - Plugin identifier used for output paths\n * @param tableGenerationResult - Result from plugin table generation\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @returns Map of context keys to their import information\n */\nfunction collectTableImports(\n context: PluginExecutorContext,\n outputDir: string,\n pluginId: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n): Map<string, TableImportInfo> {\n const tableImports = new Map<string, TableImportInfo>();\n const pluginDir = sanitizePluginId(pluginId);\n const executorDir = path.join(outputDir, pluginDir, \"executors\");\n\n for (const [key, value] of Object.entries(context)) {\n if (isTableObject(value)) {\n const tableName = value.name;\n const sourceInfo = sourceTableInfoMap?.get(tableName);\n const variableName = sourceInfo?.exportName ?? toCamelCase(tableName);\n\n // Check if it's a generated table\n let importPath: string;\n\n if (tableGenerationResult?.tableFilePaths.has(tableName)) {\n // It's a generated table - import from plugin types directory\n const tableFilePath = assertDefined(\n tableGenerationResult.tableFilePaths.get(tableName),\n \"table file path missing\",\n );\n const absoluteTablePath = path.join(outputDir, tableFilePath);\n importPath = path.relative(executorDir, absoluteTablePath).replace(/\\.ts$/, \"\");\n if (!importPath.startsWith(\".\")) {\n importPath = `./${importPath}`;\n }\n } else if (sourceInfo) {\n // It's a user-defined table\n const sourceFilePath = sourceInfo.filePath;\n importPath = path.relative(executorDir, sourceFilePath).replace(/\\.ts$/, \"\");\n if (!importPath.startsWith(\".\")) {\n importPath = `./${importPath}`;\n }\n } else {\n // Fallback: generate relative path assumption\n // This might need adjustment based on actual project structure\n importPath = `../../../../tailordb/${toKebabCase(tableName)}`;\n }\n\n tableImports.set(key, {\n variableName,\n importPath,\n });\n }\n }\n\n return tableImports;\n}\n\n/**\n * Generate TypeScript code for context object.\n * @param context - Executor context values from plugin\n * @param tableImports - Resolved table import information for context keys\n * @returns TypeScript object literal code\n */\nfunction generateContextCode(\n context: PluginExecutorContext,\n tableImports: Map<string, TableImportInfo>,\n): string {\n const entries: string[] = [];\n\n for (const [key, value] of Object.entries(context)) {\n if (isTableObject(value)) {\n const importInfo = tableImports.get(key);\n if (importInfo) {\n entries.push(` ${key}: ${importInfo.variableName}`);\n }\n } else if (value !== undefined) {\n entries.push(` ${key}: ${JSON.stringify(value)}`);\n }\n }\n\n return `{\\n${entries.join(\",\\n\")},\\n}`;\n}\n\n/**\n * Check if a value is a TailorDB table object.\n * @param value - Value to inspect\n * @returns True if value is a table object with name and fields\n */\nfunction isTableObject(value: unknown): value is { name: string; fields: Record<string, unknown> } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"name\" in value &&\n \"fields\" in value &&\n typeof (value as { name: unknown }).name === \"string\"\n );\n}\n\n// ============================================================================\n// Legacy format support\n// ============================================================================\n\n/**\n * Generate TypeScript file content for legacy format executor (trigger/operation).\n * @param executor - Legacy executor definition\n * @returns TypeScript source code for executor file\n */\nfunction generateExecutorFileContentLegacy(executor: PluginGeneratedExecutorLegacy): string {\n const triggerCode = generateTriggerCode(executor.trigger);\n const operationCode = generateOperationCode(executor.operation);\n\n // Extract inject from function operation\n const inject = executor.operation.kind === \"function\" ? executor.operation.inject : undefined;\n const injectDeclarations = generateInjectDeclarations(inject);\n\n const descriptionLine = executor.description\n ? `\\n description: ${JSON.stringify(executor.description)},`\n : \"\";\n\n return ml /* ts */ `\n /**\n * Auto-generated executor by plugin\n * DO NOT EDIT - This file is generated by @tailor-platform/sdk\n */\n import { createExecutor } from \"@tailor-platform/sdk\";\n ${injectDeclarations}\n export default createExecutor({\n name: ${JSON.stringify(executor.name)},${descriptionLine}\n trigger: ${triggerCode},\n operation: ${operationCode},\n });\n `;\n}\n\n/**\n * Generate const declarations for injected variables.\n * @param inject - Map of injected values keyed by variable name\n * @returns TypeScript const declarations or empty string\n */\nfunction generateInjectDeclarations(inject: PluginInjectMap | undefined): string {\n if (!inject || Object.keys(inject).length === 0) {\n return \"\";\n }\n\n const declarations = Object.entries(inject)\n .map(([name, value]) => `const ${name} = ${JSON.stringify(value)};`)\n .join(\"\\n\");\n\n return `\\n// Injected variables from plugin\\n${declarations}\\n`;\n}\n\n/**\n * Generate TypeScript code for trigger configuration.\n * @param trigger - Trigger configuration for executor\n * @returns TypeScript code for trigger object\n */\nfunction generateTriggerCode(trigger: PluginTriggerConfig): string {\n switch (trigger.kind) {\n case \"tailordb\":\n return `{\n kind: ${JSON.stringify(trigger.kind)},\n events: ${JSON.stringify(trigger.events)},\n tableName: ${JSON.stringify(trigger.tableName)},\n }`;\n\n case \"schedule\":\n return `{\n kind: \"schedule\",\n cron: ${JSON.stringify(trigger.cron)},\n timezone: ${JSON.stringify(trigger.timezone ?? \"UTC\")},\n }`;\n\n case \"incomingWebhook\":\n return `{\n kind: \"incomingWebhook\",\n }`;\n\n default:\n throw new Error(`Unknown trigger kind: ${(trigger as PluginTriggerConfig).kind}`);\n }\n}\n\n/**\n * Generate TypeScript code for operation configuration.\n * @param operation - Operation configuration for executor\n * @returns TypeScript code for operation object\n */\nfunction generateOperationCode(operation: PluginOperationConfig): string {\n switch (operation.kind) {\n case \"graphql\": {\n const appNameLine = operation.appName\n ? `\\n appName: ${JSON.stringify(operation.appName)},`\n : \"\";\n const variablesLine = operation.variables ? `\\n variables: ${operation.variables},` : \"\";\n\n return `{\n kind: \"graphql\",\n query: \\`${escapeTemplateLiteral(operation.query)}\\`,${appNameLine}${variablesLine}\n }`;\n }\n\n case \"function\":\n return `{\n kind: \"function\",\n body: ${operation.body},\n }`;\n\n case \"webhook\":\n return `{\n kind: \"webhook\",\n url: () => ${JSON.stringify(operation.url)},\n }`;\n\n case \"workflow\":\n return `{\n kind: \"workflow\",\n workflowName: ${JSON.stringify(operation.workflowName)},\n }`;\n\n default:\n throw new Error(`Unknown operation kind: ${(operation as PluginOperationConfig).kind}`);\n }\n}\n\n/**\n * Escape special characters in template literal content.\n * @param str - Raw template literal content\n * @returns Escaped string safe for template literals\n */\nfunction escapeTemplateLiteral(str: string): string {\n return str.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\");\n}\n\n// ============================================================================\n// Utility functions\n// ============================================================================\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve the import path for a plugin executor module.\n * @param resolve - Executor resolve function\n * @param pluginImportPath - Plugin's import path\n * @param executorOutputDir - Directory where the generated executor will be written\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns Import path string for the executor module\n */\nfunction resolveExecutorImportPath(\n resolve: () => Promise<{ default: unknown }>,\n pluginImportPath: string,\n executorOutputDir: string,\n baseDirs: string[],\n): string {\n const specifier = extractDynamicImportSpecifier(resolve);\n if (!specifier.startsWith(\".\")) {\n return specifier;\n }\n\n const pluginBaseDir = resolvePluginBaseDir(pluginImportPath, baseDirs);\n if (!pluginBaseDir) {\n throw new Error(\n `Unable to resolve plugin import base for \"${pluginImportPath}\". ` +\n `Tried base dirs: ${baseDirs.join(\", \") || \"(none)\"}. ` +\n `Use an absolute import specifier in resolve(), or ensure the plugin path is resolvable.`,\n );\n }\n\n const absolutePath = path.resolve(pluginBaseDir, specifier);\n let relativePath = path.relative(executorOutputDir, absolutePath).replace(/\\\\/g, \"/\");\n relativePath = stripSourceExtension(relativePath);\n if (!relativePath.startsWith(\".\")) {\n relativePath = `./${relativePath}`;\n }\n return relativePath;\n}\n\n/**\n * Extract the dynamic import specifier from a resolve function.\n * @param resolve - Executor resolve function\n * @returns The module specifier string\n */\nfunction extractDynamicImportSpecifier(resolve: () => Promise<{ default: unknown }>): string {\n const source = resolve.toString();\n const match = source.match(/import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (!match) {\n throw new Error(\n `resolve() must return a dynamic import, e.g. \\`async () => await import(\"./executors/on-create\")\\`.`,\n );\n }\n return assertDefined(match[1], \"dynamic import specifier capture group missing\");\n}\n\n/**\n * Resolve plugin base directory for relative imports.\n * @param pluginImportPath - Plugin import path\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns Directory path or null if not resolvable\n */\nfunction resolvePluginBaseDir(pluginImportPath: string, baseDirs: string[]): string | null {\n if (pluginImportPath.startsWith(\".\")) {\n const resolvedPath =\n resolveRelativePluginImportPath(pluginImportPath, baseDirs) ??\n path.resolve(baseDirs[0] ?? process.cwd(), pluginImportPath);\n if (fs.existsSync(resolvedPath)) {\n const stats = fs.statSync(resolvedPath);\n return stats.isDirectory() ? resolvedPath : path.dirname(resolvedPath);\n }\n return path.extname(resolvedPath) ? path.dirname(resolvedPath) : resolvedPath;\n }\n\n for (const baseDir of baseDirs) {\n try {\n const resolved = require.resolve(pluginImportPath, { paths: [baseDir] });\n return path.dirname(resolved);\n } catch {\n continue;\n }\n }\n return null;\n}\n\n/**\n * Strip TypeScript source extensions from import paths.\n * @param importPath - Path to normalize\n * @returns Path without .ts/.tsx extension\n */\nfunction stripSourceExtension(importPath: string): string {\n return importPath.replace(/\\.(ts|tsx)$/, \"\");\n}\n\n/**\n * Convert plugin ID to safe directory name.\n * @param pluginId - Plugin identifier (e.g., \"@scope/name\")\n * @returns Safe directory name\n */\nfunction sanitizePluginId(pluginId: string): string {\n return pluginId.replace(/^@/, \"\").replace(/\\//g, \"-\");\n}\n\n/**\n * Convert executor name to safe filename.\n * @param executorName - Executor name\n * @returns Safe filename without extension\n */\nfunction sanitizeExecutorFileName(executorName: string): string {\n const baseName = path.basename(executorName);\n const withoutExtension = baseName.replace(/\\.[^/.]+$/, \"\");\n const sanitized = withoutExtension.replace(/[^a-zA-Z0-9_-]/g, \"-\");\n if (!sanitized) {\n throw new Error(`Invalid executor name: \"${executorName}\"`);\n }\n return sanitized;\n}\n\n/**\n * Convert string to camelCase.\n * @param str - Input string to convert\n * @returns camelCase string\n */\nfunction toCamelCase(str: string): string {\n const result = str.replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : \"\"));\n return result.charAt(0).toLowerCase() + result.slice(1);\n}\n\n/**\n * Convert string to kebab-case.\n * @param str - Input string to convert\n * @returns kebab-case string\n */\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n","/**\n * Plugin Table Generator\n *\n * Generates TypeScript files for plugin-generated TailorDB tables.\n * These files can be imported by plugin executors to reference generated tables.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport ml from \"#/utils/multiline\";\nimport type { PluginGeneratedTableInfo, PluginTableGenerationResult } from \"#/plugin/manager\";\nimport type { PluginGeneratedTable } from \"#/plugin/types\";\n\ntype FieldMetadata = {\n required?: boolean;\n index?: boolean;\n unique?: boolean;\n description?: string;\n allowedValues?: ReadonlyArray<{ value: string }>;\n};\n\ntype FieldDefinition = {\n type?: string;\n _metadata?: FieldMetadata;\n metadata?: FieldMetadata;\n};\n\nfunction isFieldDefinition(value: unknown): value is FieldDefinition {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * Generate TypeScript files for plugin-generated tables.\n * These files export the table definition and can be imported by executor files.\n * @param tables - Array of plugin table information\n * @param outputDir - Base output directory (e.g., .tailor)\n * @returns Generation result with file paths\n */\nexport function generatePluginTableFiles(\n tables: ReadonlyArray<PluginGeneratedTableInfo>,\n outputDir: string,\n): PluginTableGenerationResult {\n const tableFilePaths = new Map<string, string>();\n const generatedFiles: string[] = [];\n\n if (tables.length === 0) {\n return { tableFilePaths, generatedFiles };\n }\n\n const seenTableNames = new Map<string, PluginGeneratedTableInfo>();\n\n for (const info of tables) {\n const existing = seenTableNames.get(info.table.name);\n if (existing) {\n throw new Error(\n `Duplicate plugin-generated table name \"${info.table.name}\" detected. ` +\n `First: plugin \"${existing.pluginId}\" (kind: \"${existing.kind}\", source: \"${existing.sourceTableName}\"), ` +\n `Second: plugin \"${info.pluginId}\" (kind: \"${info.kind}\", source: \"${info.sourceTableName}\"). ` +\n `Plugin-generated table names must be unique.`,\n );\n }\n seenTableNames.set(info.table.name, info);\n\n const pluginDir = sanitizePluginId(info.pluginId);\n const tableOutputDir = path.join(outputDir, pluginDir, \"types\");\n fs.mkdirSync(tableOutputDir, { recursive: true });\n\n const fileName = `${toKebabCase(info.table.name)}.ts`;\n const filePath = path.join(tableOutputDir, fileName);\n const content = generateTableFileContent(info);\n\n fs.writeFileSync(filePath, content);\n generatedFiles.push(filePath);\n\n // Store relative path from outputDir for import resolution\n const relativePath = path.relative(outputDir, filePath);\n tableFilePaths.set(info.table.name, relativePath);\n\n const displayPath = path.relative(process.cwd(), filePath);\n logger.log(\n ` Plugin Table File: ${styles.success(displayPath)} (${styles.dim(info.kind)}) from plugin ${styles.info(info.pluginId)}`,\n );\n }\n\n return { tableFilePaths, generatedFiles };\n}\n\n/**\n * Generate TypeScript file content for a single table.\n * @param info - Plugin table information\n * @returns TypeScript source code\n */\nfunction generateTableFileContent(info: PluginGeneratedTableInfo): string {\n const { table, pluginId, sourceTableName, kind } = info;\n const variableName = toCamelCase(table.name);\n const fieldsCode = generateFieldsCode(table);\n\n return ml /* ts */ `\n /**\n * Auto-generated table by plugin: ${pluginId}\n * Source: ${sourceTableName}\n * Kind: ${kind}\n *\n * DO NOT EDIT - This file is generated by @tailor-platform/sdk\n */\n import { db } from \"@tailor-platform/sdk\";\n\n export const ${variableName} = db.table(${JSON.stringify(table.name)}, ${fieldsCode});\n\n export type ${table.name} = typeof ${variableName};\n `;\n}\n\n/**\n * Generate TypeScript code for field definitions.\n * This creates a simplified version of the table's fields.\n * @param table - TailorDB table\n * @returns TypeScript code for fields object\n */\nfunction generateFieldsCode(table: PluginGeneratedTable): string {\n const fieldEntries: string[] = [];\n\n for (const [fieldName, field] of Object.entries(table.fields)) {\n if (!isFieldDefinition(field)) continue;\n const fieldCode = generateSingleFieldCode(field);\n if (fieldCode) {\n fieldEntries.push(` ${fieldName}: ${fieldCode}`);\n }\n }\n\n return `{\\n${fieldEntries.join(\",\\n\")},\\n}`;\n}\n\n/**\n * Map from TailorDB table to SDK method name.\n */\nconst typeToMethodMap: Record<string, string> = {\n string: \"string\",\n integer: \"int\",\n float: \"float\",\n boolean: \"bool\",\n uuid: \"uuid\",\n datetime: \"datetime\",\n date: \"date\",\n time: \"time\",\n enum: \"enum\",\n nested: \"nested\",\n};\n\n/**\n * Generate TypeScript code for a single field definition.\n * @param field - Field definition object\n * @returns TypeScript code for the field\n */\nfunction generateSingleFieldCode(field: FieldDefinition): string | null {\n const fieldType = field.type;\n if (!fieldType) {\n return null;\n }\n\n const method = typeToMethodMap[fieldType] ?? fieldType;\n const metadata: FieldMetadata = field._metadata ?? field.metadata ?? {};\n\n // Build options object\n const optionParts: string[] = [];\n if (metadata.required === false) {\n optionParts.push(\"optional: true\");\n }\n\n const optionsArg = optionParts.length > 0 ? `{ ${optionParts.join(\", \")} }` : \"\";\n\n // Handle enum type with values\n if (fieldType === \"enum\") {\n // Extract enum values from allowedValues array\n const allowedValues = metadata.allowedValues;\n let enumValues: string[] = [];\n if (Array.isArray(allowedValues)) {\n enumValues = allowedValues.map((v: { value: string }) => v.value);\n }\n\n let code = `db.enum(${JSON.stringify(enumValues)}${optionsArg ? `, ${optionsArg}` : \"\"})`;\n if (metadata.index) {\n code += \".index()\";\n }\n if (metadata.unique) {\n code += \".unique()\";\n }\n if (metadata.description) {\n code += `.description(${JSON.stringify(metadata.description)})`;\n }\n return code;\n }\n\n // Build method chain for other types\n let code = `db.${method}(${optionsArg})`;\n\n // Add index if present\n if (metadata.index) {\n code += \".index()\";\n }\n\n // Add unique if present\n if (metadata.unique) {\n code += \".unique()\";\n }\n\n // Add description if present\n if (metadata.description) {\n code += `.description(${JSON.stringify(metadata.description)})`;\n }\n\n return code;\n}\n\n/**\n * Convert plugin ID to safe directory name.\n * @param pluginId - Plugin identifier (e.g., \"@tailor-platform/change-history\")\n * @returns Safe directory name (e.g., \"tailor-platform-change-history\")\n */\nfunction sanitizePluginId(pluginId: string): string {\n return pluginId.replace(/^@/, \"\").replace(/\\//g, \"-\");\n}\n\n/**\n * Convert string to kebab-case.\n * @param str - Input string\n * @returns kebab-case string\n */\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\n/**\n * Convert string to camelCase.\n * @param str - Input string\n * @returns camelCase string\n */\nfunction toCamelCase(str: string): string {\n const result = str.replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : \"\"));\n return result.charAt(0).toLowerCase() + result.slice(1);\n}\n","import type { Plugin } from \"rolldown\";\n\ntype DepCollectorResult = {\n plugin: Plugin;\n getResult: () => string[];\n};\n\n/**\n * Create a rolldown plugin that collects all resolved module paths during a build.\n * The plugin is purely observational and does not modify any code or behavior.\n * Collected paths exclude node_modules and generated entry files.\n * node_modules changes (package upgrades) are not tracked per-bundle;\n * lockfile hash and SDK version changes invalidate the entire cache.\n * @returns An object containing the plugin and a getResult function that returns sorted, deduplicated paths\n */\nexport function createDepCollectorPlugin(): DepCollectorResult {\n const collectedPaths = new Set<string>();\n\n const plugin: Plugin = {\n name: \"cache-dep-collector\",\n load: {\n filter: {\n id: {\n // Match all file types (not just JS/TS) so that JSON, CJS,\n // and other imported files are tracked for cache invalidation.\n include: [/\\.[^/]+$/],\n },\n },\n handler(id) {\n if (!id.includes(\"node_modules\") && !id.endsWith(\".entry.js\")) {\n collectedPaths.add(id);\n }\n return null;\n },\n },\n };\n\n function getResult(): string[] {\n return Array.from(collectedPaths).toSorted();\n }\n\n return { plugin, getResult };\n}\n","import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\n\n/**\n * Compute the SHA-256 hex digest of an arbitrary string.\n * @param content - The string content to hash\n * @returns Hex-encoded SHA-256 hash\n */\nfunction hashContent(content: string): string {\n return crypto.createHash(\"sha256\").update(content, \"utf-8\").digest(\"hex\");\n}\n\n/**\n * Read a file and return its SHA-256 hex digest.\n * @param filePath - Absolute path to the file\n * @returns Hex-encoded SHA-256 hash of the file content\n */\nfunction hashFile(filePath: string): string {\n const content = fs.readFileSync(filePath);\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n// A path that does not exist hashes to a fixed marker rather than throwing, so\n// a dependency set may include files a build only probed for. Creating such a\n// file later changes the marker to a content hash, which invalidates the entry.\nconst MISSING_FILE_MARKER = \"<missing>\";\n\n/**\n * Compute a deterministic SHA-256 hash for multiple files.\n *\n * Paths are sorted alphabetically before hashing so that the result\n * is independent of the order the paths are supplied (e.g. glob ordering).\n * Each file's individual hash is concatenated and then hashed again. A path\n * that does not exist contributes a fixed marker instead of a content hash.\n * @param filePaths - Array of absolute file paths\n * @returns Hex-encoded SHA-256 hash representing all files\n */\nfunction hashFiles(filePaths: string[]): string {\n const sorted = filePaths.toSorted();\n const combined = sorted.map((fp) => hashFileOrMissing(fp)).join(\"\");\n return hashContent(combined);\n}\n\nfunction hashFileOrMissing(filePath: string): string {\n try {\n return hashFile(filePath);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return MISSING_FILE_MARKER;\n }\n throw error;\n }\n}\n\nexport { hashContent, hashFile, hashFiles };\n","import * as path from \"pathe\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { createDepCollectorPlugin } from \"./dep-collector-plugin\";\nimport { hashContent, hashFile, hashFiles } from \"./hasher\";\nimport type { CacheStore } from \"./store\";\nimport type { Plugin } from \"rolldown\";\n\ntype BundleKind =\n | \"resolver\"\n | \"executor\"\n | \"workflow-job\"\n | \"auth-hook\"\n | \"http-adapter-input\"\n | \"http-adapter-output\";\n\ntype BundleCacheRestoreParams = {\n kind: BundleKind;\n namespace?: string;\n name: string;\n /** Optional hash of non-file context (e.g., env variables) to include in cache validation. */\n contextHash?: string;\n};\n\ntype BundleCacheSaveParams = {\n kind: BundleKind;\n namespace?: string;\n name: string;\n sourceFile: string;\n content: string;\n dependencyPaths: string[];\n /** Optional hash of non-file context (e.g., env variables) to include in cache key computation. */\n contextHash?: string;\n};\n\n/**\n * Cache strategy that determines whether a bundled output can be\n * restored from cache or needs rebuilding.\n */\ntype BundleCache = {\n /** Attempt to restore cached bundle content. Returns the code string if cache is valid, undefined otherwise. */\n tryRestore(params: BundleCacheRestoreParams): string | undefined;\n /** Save bundle content and its metadata to the cache. */\n save(params: BundleCacheSaveParams): void;\n};\n\nfunction buildCacheKey(kind: string, name: string, namespace?: string): string {\n return namespace ? `${kind}:${namespace}:${name}` : `${kind}:${name}`;\n}\n\nfunction combineHash(fileHash: string, contextHash?: string): string {\n if (!contextHash) return fileHash;\n return hashContent(fileHash + contextHash);\n}\n\ntype ComputeBundlerContextHashParams = {\n sourceFile: string;\n extraContext: string;\n tsconfig?: string;\n inlineSourcemap?: boolean;\n bundleLogLevel?: string;\n prefix?: string;\n};\n\n/**\n * Compute a context hash for cache invalidation across bundlers.\n *\n * Combines the source file path, a caller-supplied extra context string\n * (e.g. serialized workflow start-call bindings, or an HTTP adapter's method\n * list), tsconfig hash, sourcemap mode, bundle log level, and an optional\n * prefix (e.g., serialized env variables) into a single SHA-256 hash.\n * @param params - Context hash computation parameters\n * @returns SHA-256 hex digest of the combined context\n */\nfunction computeBundlerContextHash(params: ComputeBundlerContextHashParams): string {\n const { sourceFile, extraContext, tsconfig, inlineSourcemap, bundleLogLevel, prefix } = params;\n return hashContent(\n (prefix ?? \"\") +\n path.resolve(sourceFile) +\n extraContext +\n (tsconfig ? hashFile(tsconfig) : \"\") +\n String(inlineSourcemap ?? false) +\n (bundleLogLevel ?? \"\"),\n );\n}\n\ntype WithCacheParams = {\n cache: BundleCache | undefined;\n kind: BundleKind;\n namespace?: string;\n name: string;\n sourceFile: string;\n contextHash: string | undefined;\n build: (plugins: Plugin[], trackDependency: (filePath: string) => void) => Promise<string>;\n};\n\n/**\n * Run a build with optional cache restore/save around it.\n * When caching is active, attempts to restore from cache first,\n * and saves the build result (with collected dependencies) on a cache miss.\n * @param params - Cache and build parameters\n * @returns The bundled code string\n */\nasync function withCache(params: WithCacheParams): Promise<string> {\n const { cache, kind, namespace, name, sourceFile, contextHash, build } = params;\n\n if (!cache) {\n return await build([], () => {});\n }\n\n const content = cache.tryRestore({ kind, namespace, name, contextHash });\n if (content !== undefined) {\n logger.debug(` ${styles.dim(\"cached\")}: ${name}`);\n return content;\n }\n\n // Files a build reads without rolldown loading them as modules — tsconfigs\n // consulted for path aliases — still have to invalidate the entry.\n const extraDependencies = new Set<string>();\n const { plugin, getResult } = createDepCollectorPlugin();\n const code = await build([plugin], (filePath) => extraDependencies.add(filePath));\n\n cache.save({\n kind,\n namespace,\n name,\n sourceFile,\n content: code,\n dependencyPaths: [...getResult(), ...extraDependencies],\n contextHash,\n });\n\n return code;\n}\n\n/**\n * Create a bundle cache backed by the given store.\n * @param store - The cache store for persistence\n * @returns A BundleCache instance\n */\nfunction createBundleCache(store: CacheStore): BundleCache {\n function tryRestore(params: BundleCacheRestoreParams): string | undefined {\n const cacheKey = buildCacheKey(params.kind, params.name, params.namespace);\n const entry = store.getEntry(cacheKey);\n\n if (!entry) {\n return undefined;\n }\n\n // Recompute hash of all stored dependency paths. A path that has appeared or\n // disappeared since the entry was saved changes the hash, so it lands on the\n // mismatch below rather than needing its own branch.\n let currentHash: string;\n try {\n currentHash = combineHash(hashFiles(entry.dependencyPaths), params.contextHash);\n } catch {\n return undefined;\n }\n\n if (currentHash !== entry.inputHash) {\n return undefined;\n }\n\n const content = store.restoreBundleContent(cacheKey);\n const output = entry.outputFiles.find((file) => file.outputPath === cacheKey);\n if (content === undefined || !output || hashContent(content) !== output.contentHash) {\n return undefined;\n }\n return content;\n }\n\n function save(params: BundleCacheSaveParams): void {\n const { kind, namespace, name, sourceFile, content, dependencyPaths, contextHash } = params;\n const cacheKey = buildCacheKey(kind, name, namespace);\n // Always include sourceFile in dependency paths so that changes to the\n // source file itself are detected even when dep-collector only finds\n // node_modules imports (which are filtered out).\n const allDeps = dependencyPaths.includes(sourceFile)\n ? dependencyPaths\n : [sourceFile, ...dependencyPaths];\n\n // Mirror tryRestore()'s tolerance: a non-ENOENT read error (e.g. EISDIR)\n // should give up on caching this entry rather than fail the build.\n let inputHash: string;\n try {\n inputHash = combineHash(hashFiles(allDeps), contextHash);\n } catch {\n return;\n }\n\n const contentHash = hashContent(content);\n\n store.storeBundleContent(cacheKey, content);\n\n store.setEntry(cacheKey, {\n kind: \"bundle\",\n inputHash,\n dependencyPaths: allDeps,\n outputFiles: [{ outputPath: cacheKey, contentHash }],\n createdAt: new Date().toISOString(),\n });\n }\n\n return { tryRestore, save };\n}\n\nexport { computeBundlerContextHash, createBundleCache, withCache };\nexport type { BundleCache };\n","import { assertDefined } from \"#/utils/assert\";\nimport type {\n Expression,\n CallExpression,\n StaticMemberExpression,\n ObjectPropertyKind,\n ObjectProperty,\n ArrowFunctionExpression,\n Function as FunctionExpression,\n} from \"@oxc-project/types\";\n\n/** A generic AST node for walking purposes */\nexport type ASTNode = Record<string, unknown>;\n\nexport interface Replacement {\n start: number;\n end: number;\n text: string;\n}\n\nexport interface StartCallInfo {\n identifierName: string;\n callRange: { start: number; end: number };\n argsText: string;\n optionsText?: string;\n}\n\nexport interface FoundProperty {\n key: ObjectProperty[\"key\"];\n value: Expression;\n start: number;\n end: number;\n}\n\n/**\n * Read an import or export name from an OXC identifier or string-literal node.\n * @param node - Import/export name node\n * @returns Module binding name, or undefined for an unsupported node\n */\nexport function getModuleExportName(node: unknown): string | undefined {\n if (!node || typeof node !== \"object\") return undefined;\n const exportName = node as { name?: string; value?: unknown };\n if (exportName.name) return exportName.name;\n return typeof exportName.value === \"string\" ? exportName.value : undefined;\n}\n\n/**\n * Check if a module source is from the Tailor SDK package (including subpaths)\n * @param source - Module source string\n * @returns True if the source is from the Tailor SDK package\n */\nexport function isTailorSdkSource(source: string): boolean {\n return /^@tailor-platform\\/sdk(\\/|$)/.test(source);\n}\n\n/**\n * Get the source string from a dynamic import or require call\n * @param node - AST node to inspect\n * @returns Resolved import/require source string or null\n */\nexport function getImportSource(node: Expression | null | undefined): string | null {\n if (!node) return null;\n // await import(\"@tailor-platform/sdk\")\n if (node.type === \"ImportExpression\") {\n const importExpr = node;\n const source = importExpr.source;\n if (source.type === \"Literal\" && typeof source.value === \"string\") {\n return source.value;\n }\n }\n // require(\"@tailor-platform/sdk\")\n if (node.type === \"CallExpression\") {\n const callExpr = node;\n if (callExpr.callee.type === \"Identifier\" && callExpr.callee.name === \"require\") {\n const arg = callExpr.arguments[0];\n if (\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n arg &&\n \"type\" in arg &&\n arg.type === \"Literal\" &&\n \"value\" in arg &&\n typeof arg.value === \"string\"\n ) {\n return arg.value;\n }\n }\n }\n return null;\n}\n\nfunction argumentSourceText(arg: unknown, sourceText: string): string | undefined {\n if (arg && typeof arg === \"object\" && \"start\" in arg && \"end\" in arg) {\n return sourceText.slice(arg.start as number, arg.end as number);\n }\n return undefined;\n}\n\n/**\n * Get metadata for a static `identifier.start(...)` call.\n * @param node - AST node to inspect\n * @param sourceText - Source code text\n * @returns Start call metadata, or null when the node is not a start call\n */\nexport function getStartCallInfo(\n node: ASTNode | null | undefined,\n sourceText: string,\n): StartCallInfo | null {\n if (!node || typeof node !== \"object\" || node.type !== \"CallExpression\") {\n return null;\n }\n\n const callExpr = node as unknown as CallExpression;\n const callee = callExpr.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n const memberExpr = callee as unknown as StaticMemberExpression;\n if (\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n memberExpr.computed ||\n memberExpr.property.name !== \"start\" ||\n memberExpr.object.type !== \"Identifier\"\n ) {\n return null;\n }\n\n return {\n identifierName: memberExpr.object.name,\n callRange: { start: callExpr.start, end: callExpr.end },\n argsText: argumentSourceText(callExpr.arguments[0], sourceText) ?? \"\",\n optionsText: argumentSourceText(callExpr.arguments[1], sourceText),\n };\n}\n\n/**\n * Unwrap AwaitExpression to get the inner expression\n * @param node - AST expression node\n * @returns Inner expression if node is an AwaitExpression\n */\nexport function unwrapAwait(node: Expression | null | undefined): Expression | null | undefined {\n if (node?.type === \"AwaitExpression\") {\n return node.argument;\n }\n return node;\n}\n\n/**\n * Check if a node is a string literal\n * @param node - AST expression node\n * @returns True if node is a string literal\n */\nexport function isStringLiteral(\n node: Expression | null | undefined,\n): node is Expression & { type: \"Literal\"; value: string } {\n // Note: oxc uses \"Literal\" for all literals, distinguishing by value type\n return node?.type === \"Literal\" && typeof (node as { value?: unknown }).value === \"string\";\n}\n\n/**\n * Check if a node is a function expression (arrow or regular)\n * @param node - AST expression node\n * @returns True if node is a function expression\n */\nexport function isFunctionExpression(\n node: Expression | null | undefined,\n): node is ArrowFunctionExpression | FunctionExpression {\n return node?.type === \"ArrowFunctionExpression\" || node?.type === \"FunctionExpression\";\n}\n\n/**\n * Find a property in an object expression\n * @param properties - Object properties to search\n * @param name - Property name to find\n * @returns Found property info or null\n */\nexport function findProperty(properties: ObjectPropertyKind[], name: string): FoundProperty | null {\n for (const prop of properties) {\n // Note: oxc uses \"Property\" for object properties\n if (prop.type === \"Property\") {\n const objProp = prop;\n const keyName =\n objProp.key.type === \"Identifier\"\n ? objProp.key.name\n : objProp.key.type === \"Literal\"\n ? (objProp.key as { value?: string }).value\n : null;\n if (keyName === name) {\n return {\n key: objProp.key,\n value: objProp.value,\n start: objProp.start,\n end: objProp.end,\n };\n }\n }\n }\n return null;\n}\n\n/**\n * Apply string replacements to source code\n * Replacements are applied from end to start to maintain positions\n * Ranges must not overlap; applying an overlapping range on top of an\n * already-shifted string would splice at stale offsets and corrupt the output,\n * so overlap is rejected up front\n * @param source - Original source code\n * @param replacements - Replacements to apply\n * @returns Transformed source code\n */\nexport function applyReplacements(source: string, replacements: Replacement[]): string {\n const sorted = replacements.toSorted((a, b) => b.start - a.start);\n for (let i = 0; i + 1 < sorted.length; i++) {\n const current = assertDefined(sorted[i], `replacement missing at index ${i}`);\n const previous = assertDefined(sorted[i + 1], `replacement missing at index ${i + 1}`);\n if (previous.end > current.start) {\n throw new Error(\n `applyReplacements: overlapping replacement ranges ` +\n `[${previous.start}, ${previous.end}) and [${current.start}, ${current.end})`,\n );\n }\n }\n let result = source;\n for (const r of sorted) {\n result = result.slice(0, r.start) + r.text + result.slice(r.end);\n }\n return result;\n}\n\n/**\n * Find the end of a statement including any trailing newline\n * @param source - Source code\n * @param position - Start position of the statement\n * @returns Index of the end of the statement including trailing newline\n */\nexport function findStatementEnd(source: string, position: number): number {\n let i = position;\n // Skip any trailing semicolons and whitespace on the same line\n while (i < source.length && (source[i] === \";\" || source[i] === \" \" || source[i] === \"\\t\")) {\n i++;\n }\n // Include the newline if present\n if (i < source.length && source[i] === \"\\n\") {\n i++;\n }\n return i;\n}\n","import { type ASTNode, isTailorSdkSource, getImportSource, unwrapAwait } from \"./ast-utils\";\nimport type {\n Program,\n ImportDeclaration,\n VariableDeclaration,\n CallExpression,\n StaticMemberExpression,\n} from \"@oxc-project/types\";\n\n/**\n * Collect all import bindings for a specific function from the Tailor SDK package\n * Returns a Set of local names that refer to the function\n * @param program - Parsed TypeScript program\n * @param functionName - Function name to collect bindings for\n * @returns Set of local names bound to the SDK function\n */\nexport function collectSdkBindings(program: Program, functionName: string): Set<string> {\n const bindings = new Set<string>();\n\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n\n const nodeType = node.type as string | undefined;\n\n // Static imports: import { createWorkflowJob } from \"@tailor-platform/sdk\"\n if (nodeType === \"ImportDeclaration\") {\n const importDecl = node as unknown as ImportDeclaration;\n const source = importDecl.source.value;\n if (typeof source === \"string\" && isTailorSdkSource(source)) {\n for (const specifier of importDecl.specifiers) {\n // import { createWorkflowJob } from \"@tailor-platform/sdk\"\n // import { createWorkflowJob as create } from \"@tailor-platform/sdk\"\n if (specifier.type === \"ImportSpecifier\") {\n const importSpec = specifier;\n const imported =\n importSpec.imported.type === \"Identifier\"\n ? importSpec.imported.name\n : (importSpec.imported as { value?: string }).value;\n if (imported === functionName) {\n bindings.add(importSpec.local.name);\n }\n }\n // import sdk from \"@tailor-platform/sdk\" → sdk.createWorkflowJob\n // import * as sdk from \"@tailor-platform/sdk\" → sdk.createWorkflowJob\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable typescript/no-unnecessary-condition\n else if (\n specifier.type === \"ImportDefaultSpecifier\" ||\n specifier.type === \"ImportNamespaceSpecifier\"\n // oxlint-enable typescript/no-unnecessary-condition\n ) {\n const spec = specifier;\n // Store namespace/default with special prefix to track member access\n bindings.add(`__namespace__:${spec.local.name}`);\n }\n }\n }\n }\n\n // Dynamic imports and require:\n // const sdk = await import(\"@tailor-platform/sdk\")\n // const sdk = require(\"@tailor-platform/sdk\")\n // const { createWorkflowJob } = await import(\"@tailor-platform/sdk\")\n // const { createWorkflowJob } = require(\"@tailor-platform/sdk\")\n if (nodeType === \"VariableDeclaration\") {\n const varDecl = node as unknown as VariableDeclaration;\n for (const decl of varDecl.declarations) {\n const init = unwrapAwait(decl.init);\n const source = getImportSource(init);\n\n if (source && isTailorSdkSource(source)) {\n const id = decl.id;\n\n // const sdk = await import(...) / const sdk = require(...)\n if (id.type === \"Identifier\") {\n bindings.add(`__namespace__:${id.name}`);\n }\n // const { createWorkflowJob } = await import(...) / require(...)\n // const { createWorkflowJob: create } = await import(...) / require(...)\n else if (id.type === \"ObjectPattern\") {\n const objPattern = id;\n for (const prop of objPattern.properties) {\n if (prop.type === \"Property\") {\n const bindingProp = prop;\n const keyName =\n bindingProp.key.type === \"Identifier\"\n ? bindingProp.key.name\n : (bindingProp.key as { value?: string }).value;\n if (keyName === functionName) {\n const localName =\n bindingProp.value.type === \"Identifier\" ? bindingProp.value.name : keyName;\n bindings.add(localName);\n }\n }\n }\n }\n }\n }\n }\n\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return bindings;\n}\n\n/**\n * Check if a CallExpression is a call to a specific SDK function\n * @param node - AST node to inspect\n * @param bindings - Collected SDK bindings\n * @param functionName - SDK function name\n * @returns True if node is a call to the SDK function\n */\nexport function isSdkFunctionCall(\n node: ASTNode,\n bindings: Set<string>,\n functionName: string,\n): node is ASTNode & { type: \"CallExpression\" } {\n if (node.type !== \"CallExpression\") return false;\n\n const callExpr = node as unknown as CallExpression;\n const callee = callExpr.callee;\n\n // Direct call: createWorkflowJob(...) or create(...)\n if (callee.type === \"Identifier\") {\n const identifier = callee;\n return bindings.has(identifier.name);\n }\n\n // Member access: sdk.createWorkflowJob(...)\n // Note: oxc uses MemberExpression with computed: false for static member access\n if (callee.type === \"MemberExpression\") {\n const memberExpr = callee as unknown as StaticMemberExpression;\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!memberExpr.computed) {\n const object = memberExpr.object;\n const property = memberExpr.property;\n if (\n object.type === \"Identifier\" &&\n bindings.has(`__namespace__:${object.name}`) &&\n property.name === functionName\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n","import { assertDefined } from \"#/utils/assert\";\nimport { type ASTNode, isStringLiteral, isFunctionExpression, findProperty } from \"./ast-utils\";\nimport { collectSdkBindings, isSdkFunctionCall } from \"./sdk-binding-collector\";\nimport type { Program, CallExpression } from \"@oxc-project/types\";\n\nexport interface JobLocation {\n name: string;\n exportName?: string;\n nameRange: { start: number; end: number };\n bodyValueRange: { start: number; end: number };\n // Range of the entire variable declaration statement (for removal)\n statementRange?: { start: number; end: number };\n}\n\n/**\n * Find all workflow jobs by detecting createWorkflowJob calls from `@tailor-platform/sdk`\n * @param program - Parsed TypeScript program\n * @param _sourceText - Source code text (currently unused)\n * @returns Detected job locations\n */\nexport function findAllJobs(program: Program, _sourceText: string): JobLocation[] {\n const jobs: JobLocation[] = [];\n const bindings = collectSdkBindings(program, \"createWorkflowJob\");\n\n function walk(node: ASTNode | null | undefined, parents: ASTNode[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Detect createWorkflowJob(...) calls\n if (isSdkFunctionCall(node, bindings, \"createWorkflowJob\")) {\n const callExpr = node as unknown as CallExpression;\n const args = callExpr.arguments;\n const firstArg = args[0];\n if (args.length >= 1 && firstArg?.type === \"ObjectExpression\") {\n const configObj = assertDefined(firstArg, \"createWorkflowJob first argument missing\");\n const nameProp = findProperty(configObj.properties, \"name\");\n const bodyProp = findProperty(configObj.properties, \"body\");\n\n if (\n nameProp &&\n isStringLiteral(nameProp.value) &&\n bodyProp &&\n isFunctionExpression(bodyProp.value)\n ) {\n // Find the outermost enclosing statement and export name\n // Iterate from closest parent (end of array) to farthest (start of array)\n let statementRange: { start: number; end: number } | undefined;\n let exportName: string | undefined;\n for (let i = parents.length - 1; i >= 0; i--) {\n const parent = assertDefined(parents[i], `parent at index ${i} missing`);\n if (parent.type === \"VariableDeclarator\") {\n const declarator = parent as unknown as {\n id?: { type?: string; name?: string };\n };\n if (declarator.id?.type === \"Identifier\") {\n exportName = declarator.id.name;\n }\n }\n // Keep track of the outermost statement (ExportNamedDeclaration > VariableDeclaration)\n if (parent.type === \"ExportNamedDeclaration\" || parent.type === \"VariableDeclaration\") {\n statementRange = {\n start: parent.start as number,\n end: parent.end as number,\n };\n // Don't break - continue to find ExportNamedDeclaration if it exists\n }\n }\n\n jobs.push({\n name: nameProp.value.value,\n exportName,\n nameRange: { start: nameProp.start, end: nameProp.end },\n bodyValueRange: {\n start: bodyProp.value.start,\n end: bodyProp.value.end,\n },\n statementRange,\n });\n }\n }\n }\n\n const newParents = [...parents, node];\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null, newParents));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode, newParents);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return jobs;\n}\n","import { assertDefined } from \"#/utils/assert\";\nimport { type ASTNode, isStringLiteral, findProperty } from \"./ast-utils\";\nimport { collectSdkBindings, isSdkFunctionCall } from \"./sdk-binding-collector\";\nimport type { Program, CallExpression } from \"@oxc-project/types\";\n\nexport interface WorkflowLocation {\n name: string;\n exportName?: string;\n isDefaultExport?: boolean;\n}\n\n/**\n * Find all workflows by detecting createWorkflow calls from `@tailor-platform/sdk`\n * @param program - Parsed TypeScript program\n * @param _sourceText - Source code text (currently unused)\n * @returns Detected workflows\n */\nexport function findAllWorkflows(program: Program, _sourceText: string): WorkflowLocation[] {\n const workflows: WorkflowLocation[] = [];\n const bindings = collectSdkBindings(program, \"createWorkflow\");\n\n function walk(node: ASTNode | null | undefined, parents: ASTNode[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Detect createWorkflow(...) calls\n if (isSdkFunctionCall(node, bindings, \"createWorkflow\")) {\n const callExpr = node as unknown as CallExpression;\n const args = callExpr.arguments;\n const firstArg = args[0];\n if (args.length >= 1 && firstArg?.type === \"ObjectExpression\") {\n const configObj = assertDefined(firstArg, \"createWorkflow first argument missing\");\n const nameProp = findProperty(configObj.properties, \"name\");\n\n if (nameProp && isStringLiteral(nameProp.value)) {\n // Find export name from parent declarations\n let exportName: string | undefined;\n let isDefaultExport = false;\n for (let i = parents.length - 1; i >= 0; i--) {\n const parent = assertDefined(parents[i], `parent at index ${i} missing`);\n if (parent.type === \"VariableDeclarator\") {\n const declarator = parent as unknown as {\n id?: { type?: string; name?: string };\n };\n if (declarator.id?.type === \"Identifier\") {\n exportName = declarator.id.name;\n break;\n }\n }\n // Check for export default createWorkflow(...)\n if (parent.type === \"ExportDefaultDeclaration\") {\n isDefaultExport = true;\n }\n }\n\n workflows.push({\n name: nameProp.value.value,\n exportName,\n isDefaultExport,\n });\n }\n }\n }\n\n const newParents = [...parents, node];\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null, newParents));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode, newParents);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return workflows;\n}\n","import * as fs from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport { loadFilesWithIgnores, type FileLoadConfig } from \"#/cli/services/file-loader\";\nimport { getModuleExportName, type ASTNode } from \"#/cli/services/workflow/ast-utils\";\nimport { findAllJobs } from \"#/cli/services/workflow/job-detector\";\nimport { findAllWorkflows } from \"#/cli/services/workflow/workflow-detector\";\nimport { logger } from \"#/cli/shared/logger\";\n\nexport interface StartTarget {\n kind: \"job\" | \"workflow\";\n name: string;\n}\n\nexport interface StartModuleBindings {\n sourceFile: string;\n localBindings: Map<string, StartTarget>;\n exports: Map<string, StartTarget>;\n}\n\nexport interface StartContext {\n modules: Map<string, StartModuleBindings>;\n authNamespace?: string;\n}\n\n/**\n * Normalize a source module path for start-call binding lookup.\n * @param filePath - Source file path or extensionless relative import path\n * @returns Absolute path without a JavaScript or TypeScript extension\n */\nexport function normalizeFilePath(filePath: string): string {\n return path.resolve(filePath.replace(/[?#].*$/, \"\")).replace(/\\.(ts|mts|cts|js|mjs|cjs)$/, \"\");\n}\n\nfunction createModuleBindings(\n sourceFile: string,\n program: ReturnType<typeof parseSync>[\"program\"],\n source: string,\n) {\n const localBindings = new Map<string, StartTarget>();\n const exports = new Map<string, StartTarget>();\n\n for (const workflow of findAllWorkflows(program, source)) {\n const target = { kind: \"workflow\", name: workflow.name } as const;\n if (workflow.exportName) localBindings.set(workflow.exportName, target);\n if (workflow.isDefaultExport) exports.set(\"default\", target);\n }\n\n for (const job of findAllJobs(program, source)) {\n if (job.exportName) {\n localBindings.set(job.exportName, { kind: \"job\", name: job.name });\n }\n }\n\n for (const statement of program.body as unknown as ASTNode[]) {\n if (statement.type === \"ExportDefaultDeclaration\") {\n const declaration = statement.declaration as ASTNode | undefined;\n if (declaration?.type === \"Identifier\") {\n const target = localBindings.get(declaration.name as string);\n if (target) exports.set(\"default\", target);\n }\n continue;\n }\n\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const declaration = statement.declaration as ASTNode | undefined;\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of declaration.declarations as ASTNode[]) {\n const id = declarator.id as ASTNode | undefined;\n if (id?.type !== \"Identifier\") continue;\n const localName = id.name as string;\n const target = localBindings.get(localName);\n if (target) exports.set(localName, target);\n }\n }\n\n if (statement.source) continue;\n for (const specifier of (statement.specifiers as ASTNode[] | undefined) ?? []) {\n const localName = getModuleExportName(specifier.local);\n const exportedName = getModuleExportName(specifier.exported);\n if (!localName || !exportedName) continue;\n const target = localBindings.get(localName);\n if (target) exports.set(exportedName, target);\n }\n }\n\n return { sourceFile, localBindings, exports } satisfies StartModuleBindings;\n}\n\n/**\n * Build start-call context from configured workflow source files.\n * @param workflowConfig - Workflow file loading configuration\n * @param authNamespace - Auth service namespace (optional, used for string-literal invoker expansion)\n * @param baseDir - Directory the workflow config's file patterns are resolved against (defaults to process.cwd())\n * @returns Module-local workflow and job binding metadata\n */\nexport async function buildStartContext(\n workflowConfig: FileLoadConfig | undefined,\n authNamespace?: string,\n baseDir = process.cwd(),\n): Promise<StartContext> {\n const modules = new Map<string, StartModuleBindings>();\n if (!workflowConfig) return { modules, authNamespace };\n\n for (const file of loadFilesWithIgnores(workflowConfig, baseDir)) {\n try {\n const source = await fs.promises.readFile(file, \"utf-8\");\n const { program, errors } = parseSync(file, source);\n if (errors.length > 0) {\n logger.warn(\n `Failed to parse workflow file ${file}: ${errors.map((e) => e.message).join(\"; \")}`,\n { mode: \"stream\" },\n );\n continue;\n }\n modules.set(normalizeFilePath(file), createModuleBindings(file, program, source));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(`Failed to process workflow file ${file}: ${errorMessage}`, {\n mode: \"stream\",\n });\n }\n }\n\n return { modules, authNamespace };\n}\n\nfunction sortedTargets(bindings: Map<string, StartTarget>) {\n return [...bindings]\n .toSorted(([a], [b]) => a.localeCompare(b))\n .map(([binding, target]) => [binding, target.kind, target.name]);\n}\n\n/**\n * Serialize start-call context to a deterministic cache input.\n * @param context - Start-call context to serialize\n * @returns Deterministic string, or an empty string when context is absent\n */\nexport function serializeStartContext(context: StartContext | undefined): string {\n if (!context) return \"\";\n const modules = [...context.modules]\n .toSorted(([a], [b]) => a.localeCompare(b))\n .map(([file, bindings]) => [\n file,\n sortedTargets(bindings.localBindings),\n sortedTargets(bindings.exports),\n ]);\n return JSON.stringify(modules) + (context.authNamespace ?? \"\");\n}\n","import { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport { logger } from \"#/cli/shared/logger\";\nimport {\n normalizeFilePath,\n type StartContext,\n type StartModuleBindings,\n type StartTarget,\n} from \"#/cli/shared/start-context\";\nimport {\n type ASTNode,\n type Replacement,\n type StartCallInfo,\n applyReplacements,\n getModuleExportName,\n getStartCallInfo,\n} from \"./ast-utils\";\nimport type { Program } from \"@oxc-project/types\";\nimport type { Plugin } from \"rolldown\";\n\nexport interface ResolvedStartCall extends StartCallInfo {\n kind: \"job\" | \"workflow\";\n targetName: string;\n}\n\nconst START_CALL_RE = /\\.start(?:\\s|\\/\\*[\\s\\S]*?\\*\\/|\\/\\/[^\\n]*\\n)*\\(/;\n\n/**\n * Fast pre-check for whether `code` contains a `.start(` call, tolerating\n * whitespace, newlines, and comments between `.start` and `(` that a plain\n * substring check would miss.\n * @param code - Source text to scan\n * @returns Whether `code` contains a `.start(` call\n */\nexport function hasStartCall(code: string): boolean {\n return START_CALL_RE.test(code);\n}\n\nconst NORMALIZER_IDENTIFIER = \"__tailor_normalizeStartOptions\";\n\n/**\n * Build the source text of the injected normalizer helper.\n *\n * Renames an `invoker` in the start options to the `authInvoker` form the\n * platform RPC expects: a plain string (machine user name) becomes\n * `{ namespace, machineUserName }`, while an object form passes through\n * as-is. Any other options value is unchanged. The auth namespace is baked\n * in at bundle time.\n * @param authNamespace - Auth service namespace to embed\n * @returns Source line defining the helper\n */\nfunction buildNormalizerHelperSource(authNamespace: string): string {\n return `const ${NORMALIZER_IDENTIFIER} = (o) => { if (!o) return o; const { invoker, ...rest } = o; return typeof invoker === \"string\" ? { ...rest, authInvoker: { namespace: ${JSON.stringify(authNamespace)}, machineUserName: invoker } } : typeof invoker === \"object\" ? { ...rest, authInvoker: invoker } : o; };\\n`;\n}\n\nfunction collectBindingNames(node: ASTNode | null | undefined, names: Set<string>): void {\n if (!node || typeof node !== \"object\") return;\n\n switch (node.type) {\n case \"Identifier\":\n names.add(node.name as string);\n return;\n case \"ObjectPattern\":\n for (const property of node.properties as ASTNode[]) {\n collectBindingNames(\n property.type === \"RestElement\"\n ? (property.argument as ASTNode)\n : (property.value as ASTNode),\n names,\n );\n }\n return;\n case \"ArrayPattern\":\n for (const element of node.elements as Array<ASTNode | null>) {\n collectBindingNames(element, names);\n }\n return;\n case \"AssignmentPattern\":\n collectBindingNames(node.left as ASTNode, names);\n return;\n case \"RestElement\":\n collectBindingNames(node.argument as ASTNode, names);\n return;\n case \"TSParameterProperty\":\n collectBindingNames(node.parameter as ASTNode, names);\n }\n}\n\nfunction declarationNode(statement: ASTNode): ASTNode | undefined {\n return statement.type === \"ExportNamedDeclaration\" ||\n statement.type === \"ExportDefaultDeclaration\"\n ? (statement.declaration as ASTNode | undefined)\n : statement;\n}\n\nfunction collectBlockBindings(statements: ASTNode[], names: Set<string>): void {\n for (const statement of statements) {\n const declaration = declarationNode(statement);\n if (!declaration) continue;\n\n if (declaration.type === \"VariableDeclaration\") {\n if (declaration.kind === \"var\") continue;\n for (const declarator of declaration.declarations as ASTNode[]) {\n collectBindingNames(declarator.id as ASTNode, names);\n }\n } else if (\n declaration.type === \"FunctionDeclaration\" ||\n declaration.type === \"ClassDeclaration\"\n ) {\n collectBindingNames(declaration.id as ASTNode | undefined, names);\n }\n }\n}\n\nfunction collectFunctionVarBindings(root: ASTNode, names: Set<string>): void {\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n if (\n node !== root &&\n (node.type === \"FunctionDeclaration\" ||\n node.type === \"FunctionExpression\" ||\n node.type === \"ArrowFunctionExpression\" ||\n node.type === \"StaticBlock\")\n ) {\n return;\n }\n if (node.type === \"VariableDeclaration\" && node.kind === \"var\") {\n for (const declarator of node.declarations as ASTNode[]) {\n collectBindingNames(declarator.id as ASTNode, names);\n }\n }\n for (const key of Object.keys(node)) {\n if (key === \"parent\") continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walk(item as ASTNode | null);\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(root);\n}\n\nfunction collectScopeBindings(node: ASTNode): Set<string> | undefined {\n const names = new Set<string>();\n\n if (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"FunctionExpression\" ||\n node.type === \"ArrowFunctionExpression\"\n ) {\n collectBindingNames(node.id as ASTNode | undefined, names);\n for (const parameter of node.params as ASTNode[]) {\n collectBindingNames(parameter, names);\n }\n collectFunctionVarBindings(node, names);\n return names;\n }\n\n if (node.type === \"BlockStatement\") {\n collectBlockBindings(node.body as ASTNode[], names);\n return names;\n }\n\n if (node.type === \"CatchClause\") {\n collectBindingNames(node.param as ASTNode | undefined, names);\n return names;\n }\n\n if (\n node.type === \"ForStatement\" ||\n node.type === \"ForInStatement\" ||\n node.type === \"ForOfStatement\"\n ) {\n const declaration = (node.init ?? node.left) as ASTNode | undefined;\n if (declaration?.type === \"VariableDeclaration\" && declaration.kind !== \"var\") {\n for (const declarator of declaration.declarations as ASTNode[]) {\n collectBindingNames(declarator.id as ASTNode, names);\n }\n }\n return names;\n }\n\n return undefined;\n}\n\nfunction addShadowedBindings(\n shadowedNames: ReadonlySet<string>,\n bindings: Set<string> | undefined,\n targetNames: ReadonlySet<string>,\n): ReadonlySet<string> {\n if (!bindings) return shadowedNames;\n const relevantBindings = [...bindings].filter((name) => targetNames.has(name));\n return relevantBindings.length === 0\n ? shadowedNames\n : new Set([...shadowedNames, ...relevantBindings]);\n}\n\nfunction walkBindingAware(\n program: Program,\n targetNames: ReadonlySet<string>,\n visitor: (\n node: ASTNode,\n shadowedNames: ReadonlySet<string>,\n parentNode?: ASTNode,\n parentKey?: string,\n ) => void,\n): void {\n function walk(\n node: ASTNode | null | undefined,\n shadowedNames: ReadonlySet<string>,\n parentNode?: ASTNode,\n parentKey?: string,\n ): void {\n if (!node || typeof node !== \"object\" || node.type === \"ImportDeclaration\") return;\n\n const nestedShadowedNames =\n node.type === \"Program\"\n ? shadowedNames\n : addShadowedBindings(shadowedNames, collectScopeBindings(node), targetNames);\n visitor(node, nestedShadowedNames, parentNode, parentKey);\n\n for (const key of Object.keys(node)) {\n if (key === \"parent\") continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n walk(item as ASTNode | null, nestedShadowedNames, node, key);\n }\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode, nestedShadowedNames, node, key);\n }\n }\n }\n\n walk(program as unknown as ASTNode, new Set());\n}\n\nfunction resolveRelativeImport(\n context: StartContext,\n currentFilePath: string,\n importSource: string,\n): StartModuleBindings | undefined {\n if (!importSource.startsWith(\".\")) return undefined;\n const currentDirectory = path.dirname(currentFilePath.replace(/[?#].*$/, \"\"));\n const modulePath = normalizeFilePath(path.resolve(currentDirectory, importSource));\n return context.modules.get(modulePath) ?? context.modules.get(path.join(modulePath, \"index\"));\n}\n\nfunction collectLocalTargets(\n program: Program,\n context: StartContext,\n currentFilePath: string,\n): Map<string, StartTarget> {\n const targets = new Map<string, StartTarget>();\n const currentModule = context.modules.get(normalizeFilePath(currentFilePath));\n if (currentModule) {\n for (const [localName, target] of currentModule.localBindings) {\n targets.set(localName, target);\n }\n }\n\n for (const statement of program.body) {\n if (statement.type !== \"ImportDeclaration\" || statement.importKind === \"type\") continue;\n const importSource = statement.source.value;\n if (typeof importSource !== \"string\") continue;\n const importedModule = resolveRelativeImport(context, currentFilePath, importSource);\n if (!importedModule) continue;\n\n for (const specifier of statement.specifiers) {\n if (specifier.type === \"ImportNamespaceSpecifier\") continue;\n if (specifier.type === \"ImportSpecifier\" && specifier.importKind === \"type\") continue;\n\n const importedName =\n specifier.type === \"ImportDefaultSpecifier\"\n ? \"default\"\n : getModuleExportName(specifier.imported);\n if (!importedName) continue;\n const target = importedModule.exports.get(importedName);\n if (!target) continue;\n targets.set(specifier.local.name, target);\n }\n }\n\n return targets;\n}\n\nfunction detectStartCallsWithTargets(\n program: Program,\n sourceText: string,\n targets: Map<string, StartTarget>,\n): ResolvedStartCall[] {\n const calls: ResolvedStartCall[] = [];\n const targetNames = new Set(targets.keys());\n\n walkBindingAware(program, targetNames, (node, shadowedNames) => {\n const startCall = getStartCallInfo(node, sourceText);\n if (!startCall || shadowedNames.has(startCall.identifierName)) return;\n const target = targets.get(startCall.identifierName);\n if (target) {\n calls.push({ ...startCall, kind: target.kind, targetName: target.name });\n }\n });\n\n return calls;\n}\n\nexport function detectResolvedStartCalls(\n program: Program,\n sourceText: string,\n context: StartContext,\n currentFilePath: string,\n): ResolvedStartCall[] {\n return detectStartCallsWithTargets(\n program,\n sourceText,\n collectLocalTargets(program, context, currentFilePath),\n );\n}\n\nexport function transformStartCalls(\n source: string,\n startContext: StartContext,\n currentFilePath: string,\n): string {\n const { program } = parseSync(\"input.ts\", source);\n const localTargets = collectLocalTargets(program, startContext, currentFilePath);\n const { authNamespace } = startContext;\n const allStartCalls = detectStartCallsWithTargets(program, source, localTargets);\n const nestedStartCalls: Array<{ call: ResolvedStartCall; parent: ResolvedStartCall }> = [];\n const startCalls = allStartCalls.filter((call) => {\n const parent = allStartCalls.find(\n (other) =>\n other !== call &&\n other.callRange.start <= call.callRange.start &&\n call.callRange.end <= other.callRange.end,\n );\n if (!parent) return true;\n nestedStartCalls.push({ call, parent });\n return false;\n });\n\n for (const { call, parent } of nestedStartCalls) {\n logger.warn(\n `Nested start call \"${call.identifierName}.start(...)\" inside \"${parent.identifierName}.start(...)\" cannot be converted. Move it to a separate statement and pass the result instead.`,\n );\n }\n\n const replacements: Replacement[] = [];\n // Whether any workflow start invoker was wrapped with the runtime\n // normalizer. Used to decide whether to inject the helper at the top.\n let needsNormalizerHelper = false;\n\n for (const call of startCalls) {\n let transformedCall: string;\n if (call.kind === \"workflow\") {\n let optionsPart = \"\";\n if (call.optionsText !== undefined) {\n if (authNamespace) {\n optionsPart = `, ${NORMALIZER_IDENTIFIER}(${call.optionsText})`;\n needsNormalizerHelper = true;\n } else {\n optionsPart = `, ${call.optionsText}`;\n }\n }\n transformedCall = `tailor.workflow.startWorkflow(${JSON.stringify(call.targetName)}, ${call.argsText || \"undefined\"}${optionsPart})`;\n } else {\n const optionsPart = call.optionsText !== undefined ? `, ${call.optionsText}` : \"\";\n transformedCall = `tailor.workflow.execJobFunction(${JSON.stringify(call.targetName)}, ${call.argsText || \"undefined\"}${optionsPart})`;\n }\n replacements.push({\n start: call.callRange.start,\n end: call.callRange.end,\n text: transformedCall,\n });\n }\n\n const transformed = applyReplacements(source, replacements);\n return needsNormalizerHelper && authNamespace\n ? buildNormalizerHelperSource(authNamespace) + transformed\n : transformed;\n}\n\nexport function createStartTransformPlugin(\n startContext: StartContext | undefined,\n): Plugin | undefined {\n if (!startContext || startContext.modules.size === 0) return undefined;\n\n return {\n name: \"start-transform\",\n transform: {\n filter: { id: { include: [/\\.(ts|mts|cts|js|mjs|cjs)$/] } },\n handler(code, id) {\n if (!hasStartCall(code)) return null;\n return { code: transformStartCalls(code, startContext, id) };\n },\n },\n };\n}\n","import { CLIError } from \"#/cli/shared/errors\";\nimport { getNodeBuiltinMessage, isNodeBuiltinImport } from \"#/utils/node-builtins\";\nimport type * as rolldown from \"rolldown\";\n\n// rolldown externalizes an import it cannot resolve and reports it as a\n// warning, so a bundle that still contains the bare specifier would otherwise\n// deploy as a success and only fail once the platform runs it. `logLevel`\n// cannot stay `\"silent\"` here: rolldown's level gate drops warnings before\n// `onLog` is ever consulted, so the escalation only sees the log at `\"warn\"`.\n// Every other log stays suppressed by never delegating to `defaultHandler`.\nconst ESCALATED_LOG_CODE = \"UNRESOLVED_IMPORT\";\n\nexport interface BundleLogOptions {\n /** Absolute path of the tsconfig handed to rolldown, when one was resolved. */\n tsconfig?: string;\n}\n\ninterface BundleLogRolldownOptions {\n logLevel: \"warn\";\n onLog: NonNullable<rolldown.InputOptions[\"onLog\"]>;\n}\n\nexport interface BundleLog {\n options: BundleLogRolldownOptions;\n assertAllResolved(): void;\n}\n\n/**\n * Collect unresolved imports while keeping every other rolldown log suppressed.\n * @param options - Context used to explain which tsconfig was in effect\n * @returns Rolldown options and a post-build assertion\n */\nexport function createBundleLog(options: BundleLogOptions = {}): BundleLog {\n const unresolvedImports = new Map<string, rolldown.RollupLog>();\n return {\n options: {\n logLevel: \"warn\",\n onLog: (_level, log) => {\n if (log.code !== ESCALATED_LOG_CODE) return;\n unresolvedImports.set(JSON.stringify([log.exporter, log.id]), log);\n },\n },\n assertAllResolved() {\n if (unresolvedImports.size > 0) {\n throw unresolvedImportError([...unresolvedImports.values()], options.tsconfig);\n }\n },\n };\n}\n\nfunction unresolvedImportError(logs: rolldown.RollupLog[], tsconfig: string | undefined): Error {\n const imports = logs.map(formatUnresolvedImport);\n const message =\n imports.length === 1\n ? `Could not resolve ${imports[0]}.`\n : `Could not resolve ${imports.length} imports.`;\n const details = imports.length === 1 ? undefined : imports.map((item) => `- ${item}`).join(\"\\n\");\n const suggestion = unresolvedImportSuggestion(logs, tsconfig);\n return CLIError({\n code: \"UNRESOLVED_IMPORT\",\n message,\n details,\n suggestion,\n });\n}\n\nfunction unresolvedImportSuggestion(\n logs: rolldown.RollupLog[],\n tsconfig: string | undefined,\n): string {\n const nodeSuggestions = logs\n .map((log) => log.exporter)\n .filter((specifier): specifier is string => specifier !== undefined)\n .filter(isNodeBuiltinImport)\n .map(getNodeBuiltinMessage);\n const hasOtherImports = logs.some(\n (log) => log.exporter === undefined || !isNodeBuiltinImport(log.exporter),\n );\n const pathSuggestion = tsconfig\n ? `Check that each import path is correct, and that a \\`compilerOptions.paths\\` entry covering it is declared in the importing file's own tsconfig.json or an ancestor. The build used \"${tsconfig}\".`\n : \"No tsconfig.json was found, so `compilerOptions.paths` aliases were not applied. Add a tsconfig.json declaring the aliases these files import.\";\n return [...new Set([...nodeSuggestions, ...(hasOtherImports ? [pathSuggestion] : [])])].join(\n \"\\n\",\n );\n}\n\nfunction formatUnresolvedImport(log: rolldown.RollupLog): string {\n const specifier = log.exporter ?? \"an imported module\";\n // A virtual entry's id carries a leading `\\0`, which renders as a stray\n // control character; name the bundler's generated entry instead.\n const importerId = log.id?.startsWith(\"\\0\")\n ? `a generated entry (${log.id.slice(1)})`\n : log.id && `\"${log.id}\"`;\n const importer = importerId ? ` imported from ${importerId}` : \"\";\n return `\"${specifier}\"${importer}`;\n}\n","import { isLogLevel, LOG_LEVELS } from \"#/parser/app-config/log-level\";\nimport type { LogLevel, LogLevelInput } from \"#/configure/config/types\";\nimport type { TreeshakingOptions } from \"rolldown\";\n\nconst INFO_LEVEL_CONSOLE_METHODS = [\n \"console.info\",\n \"console.table\",\n \"console.dir\",\n \"console.dirxml\",\n \"console.count\",\n \"console.countReset\",\n \"console.time\",\n \"console.timeLog\",\n \"console.timeEnd\",\n \"console.group\",\n \"console.groupCollapsed\",\n \"console.groupEnd\",\n \"console.clear\",\n] as const;\n\n// `console.log` is treated as a DEBUG-level method to stay consistent with the\n// platform's OpenTelemetry severity mapping, where the deployment runtime emits\n// `console.log` at DEBUG severity rather than INFO.\nconst DEBUG_LEVEL_CONSOLE_METHODS = [\"console.debug\", \"console.log\", \"console.trace\"] as const;\n\nconst WARN_LEVEL_CONSOLE_METHODS = [\"console.warn\"] as const;\n\n// `console.assert` is intentionally excluded: on the deployment runtime\n// (deno_core/V8) only log/debug/info/warn/error are wrapped with a log\n// severity, so `console.assert` sits outside the platform's severity system\n// and is never dropped by the log-level treeshaking.\nconst ERROR_LEVEL_CONSOLE_METHODS = [\"console.error\"] as const;\n\n// `@tailor-platform/sdk/runtime`'s `logger` wrapper calls\n// `(globalThis as {...}).tailor.logger.*` (see runtime/logger.ts); the `as`\n// cast is erased by the time treeshaking runs, so the callee this matches\n// against is the `globalThis.tailor.logger.*` member chain, not `tailor.logger.*`.\nconst DEBUG_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.debug\"] as const;\n\nconst INFO_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.info\"] as const;\n\nconst WARN_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.warn\"] as const;\n\nconst ERROR_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.error\"] as const;\n\nconst MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL: Record<LogLevel, readonly string[]> = {\n DEBUG: [],\n INFO: [...DEBUG_LEVEL_CONSOLE_METHODS, ...DEBUG_LEVEL_LOGGER_METHODS],\n WARN: [\n ...DEBUG_LEVEL_CONSOLE_METHODS,\n ...INFO_LEVEL_CONSOLE_METHODS,\n ...DEBUG_LEVEL_LOGGER_METHODS,\n ...INFO_LEVEL_LOGGER_METHODS,\n ],\n ERROR: [\n ...DEBUG_LEVEL_CONSOLE_METHODS,\n ...INFO_LEVEL_CONSOLE_METHODS,\n ...WARN_LEVEL_CONSOLE_METHODS,\n ...DEBUG_LEVEL_LOGGER_METHODS,\n ...INFO_LEVEL_LOGGER_METHODS,\n ...WARN_LEVEL_LOGGER_METHODS,\n ],\n SILENT: [\n ...DEBUG_LEVEL_CONSOLE_METHODS,\n ...INFO_LEVEL_CONSOLE_METHODS,\n ...WARN_LEVEL_CONSOLE_METHODS,\n ...ERROR_LEVEL_CONSOLE_METHODS,\n ...DEBUG_LEVEL_LOGGER_METHODS,\n ...INFO_LEVEL_LOGGER_METHODS,\n ...WARN_LEVEL_LOGGER_METHODS,\n ...ERROR_LEVEL_LOGGER_METHODS,\n ],\n};\n\nexport function normalizeBundleLogLevel(value: string): LogLevel | undefined {\n const normalized = value.trim().toUpperCase();\n return isLogLevel(normalized) ? normalized : undefined;\n}\n\nexport function resolveBundleLogLevel(configValue?: LogLevelInput): LogLevel {\n if (configValue === undefined) return \"DEBUG\";\n const resolved = normalizeBundleLogLevel(configValue);\n if (resolved) return resolved;\n\n throw new Error(`Invalid logLevel \"${configValue}\". Expected one of: ${LOG_LEVELS.join(\", \")}`);\n}\n\nexport function manualPureFunctionsForLogLevel(logLevel: LogLevel): readonly string[] {\n return MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL[logLevel];\n}\n\nexport function createLogLevelTreeshakeOptions(logLevel: LogLevel): TreeshakingOptions {\n const manualPureFunctions = manualPureFunctionsForLogLevel(logLevel);\n return manualPureFunctions.length > 0 ? { manualPureFunctions } : {};\n}\n","import type { TreeshakingOptions } from \"rolldown\";\n\nconst BASE_FUNCTION_TREESHAKE_OPTIONS = {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n} as const satisfies TreeshakingOptions;\n\nexport function mergeFunctionTreeshakeOptions(\n fragments: readonly TreeshakingOptions[],\n): TreeshakingOptions {\n const merged: TreeshakingOptions = {};\n const manualPureFunctions = new Set<string>();\n\n for (const fragment of fragments) {\n Object.assign(merged, fragment);\n for (const name of fragment.manualPureFunctions ?? []) {\n manualPureFunctions.add(name);\n }\n }\n\n if (manualPureFunctions.size > 0) {\n merged.manualPureFunctions = [...manualPureFunctions];\n } else {\n delete merged.manualPureFunctions;\n }\n\n return merged;\n}\n\nexport function composeFunctionTreeshakeOptions(\n fragments: readonly TreeshakingOptions[] = [],\n): TreeshakingOptions {\n return mergeFunctionTreeshakeOptions([BASE_FUNCTION_TREESHAKE_OPTIONS, ...fragments]);\n}\n","import type * as rolldown from \"rolldown\";\n\n// Match the exact `process.env.__TAILOR_PLATFORM_BUNDLE` member-expression: the\n// leading lookbehind rejects a longer owner (`foo.process.env…`) or identifier,\n// the trailing `\\b` rejects a longer key (`…_BUNDLE_MODE`).\nconst GATE = /(?<![\\w$.])process\\.env\\.__TAILOR_PLATFORM_BUNDLE\\b/g;\n\n// Fold the gate to `true` so the minifier DCEs the test-only workflow\n// registry/serialize runner. Apply in every bundler that builds runnable\n// functions; a missed path leaves the env read in place and fails loudly on the\n// Platform's Web runtime (no `process`), which an e2e catches. rolldown exposes\n// no `define`, so this is a transform-level replace rather than a define.\n//\n// The fold above only proves the branch dead after transform+parse; rolldown\n// still resolves every top-level import a module contains before it can shake\n// the dead branch out of the output. `createWorkflowJob`'s test-only invoker\n// wrapper (test-env-key.ts, reachable from every bundler through the public\n// `createWorkflowJob` export) needs `node:async_hooks` for correct scoping\n// across concurrent local job invocations, but that specifier is never\n// available on the Platform runtime and is unreachable there once the gate\n// folds — so resolve it as external rather than failing the build over an\n// import that never survives to the bundled output.\nexport const platformBundleDefinePlugin: rolldown.Plugin = {\n name: \"tailor-platform-bundle-define\",\n transform(code) {\n if (!code.includes(\"process.env.__TAILOR_PLATFORM_BUNDLE\")) return null;\n return { code: code.replace(GATE, \"true\") };\n },\n resolveId(source) {\n if (source === \"node:async_hooks\") return { id: source, external: true };\n return null;\n },\n};\n","import { resolveTSConfig } from \"pkg-types\";\nimport { logger } from \"#/cli/shared/logger\";\n\n// resolveTSConfigWithFallback is called once per bundler/service, so a\n// single generate/apply run can call it multiple times for the same baseDir\n// (once per resolver/executor/tailordb/etc. config sharing that directory).\n// Track which baseDirs have already warned so each one only warns once per run.\nconst warnedBaseDirs = new Set<string>();\n\n/**\n * Resolve the nearest tsconfig.json for baseDir, falling back to the tsconfig\n * resolved from the invocation cwd when baseDir's own ancestry has none.\n * @param baseDir - Directory to resolve the tsconfig against\n * @returns Absolute path to the resolved tsconfig.json, or undefined if none was found\n */\nexport async function resolveTSConfigWithFallback(baseDir: string): Promise<string | undefined> {\n const tsconfig = await tryResolve(baseDir);\n if (tsconfig || baseDir === process.cwd()) {\n return tsconfig;\n }\n\n // v1 compatibility fallback: pre-existing configs may rely on a tsconfig\n // discoverable from the invocation cwd rather than baseDir. Remove this\n // fallback in v2, once such configs are expected to have migrated.\n const fallback = await tryResolve(process.cwd());\n if (fallback && !warnedBaseDirs.has(baseDir)) {\n warnedBaseDirs.add(baseDir);\n logger.warn(\n `No tsconfig found from \"${baseDir}\"; falling back to the tsconfig resolved from ` +\n `process.cwd(). Move (or extend) a tsconfig into this directory before ` +\n `v2, when this fallback will be removed.`,\n );\n }\n return fallback;\n}\n\nasync function tryResolve(dir: string): Promise<string | undefined> {\n try {\n return await resolveTSConfig(dir);\n } catch {\n return undefined;\n }\n}\n","import { type Cache, createPathsMatcher, getTsconfig } from \"get-tsconfig\";\nimport * as path from \"pathe\";\nimport type * as rolldown from \"rolldown\";\n\n// A bundler hands rolldown a single tsconfig, so its normal resolution applies\n// one `paths` table to every module in the graph. When that resolution misses an\n// import from another TypeScript project, this plugin retries it against the\n// importing file's nearest tsconfig, matching the runtime hook's lookup.\n//\n// Strictly a last resort. rolldown's `order: \"post\"` only orders this hook\n// against other plugins — it still runs ahead of the builtin resolver, and a\n// non-null return wins outright. So the handler asks rolldown to resolve the\n// specifier first and bails out when that succeeds, which keeps a real\n// node_modules package ahead of a `\"*\"` catch-all alias.\n\ntype ResolutionContext = {\n matcher: (specifier: string) => string[];\n};\n\n/**\n * The lookup cache {@link createTsconfigPathsPlugin} maintains internally by\n * default. Share one instance across every bundle in a CLI run (via the\n * `cache` option) so bundling many items — hundreds of resolvers, say — reads\n * and parses each ancestor tsconfig once instead of once per item.\n *\n * `get-tsconfig`'s `Cache` is a plain `Map`; concurrent bundles racing to\n * populate the same key recompute the same deterministic value and simply\n * overwrite each other, so sharing it across `withBundleConcurrency` workers\n * is safe.\n */\nexport interface TsconfigLookupCache {\n tsconfigCache: Cache;\n contextCache: Map<string, ResolutionContext | null>;\n}\n\n/**\n * Create a {@link TsconfigLookupCache} to share across every bundle in a CLI run.\n * @returns A fresh, empty lookup cache\n */\nexport function createTsconfigLookupCache(): TsconfigLookupCache {\n return { tsconfigCache: new Map(), contextCache: new Map() };\n}\n\nexport interface TsconfigPathsPluginOptions {\n /**\n * Source file a bundler's virtual entry was built from. A virtual entry has no\n * directory of its own to resolve against, so an entry that inlines the user's\n * own import statements must name the file they came from.\n */\n virtualEntrySourceFile?: string;\n /**\n * Called with each file path the tsconfig lookup depends on, including config\n * candidates that do not exist yet and package metadata used to resolve an\n * `extends` target. A cached bundler must treat these as inputs: tsconfigs are\n * never loaded as modules, so nothing else notices when an ancestor's `paths`\n * table changes or a nearer tsconfig.json appears.\n */\n onTsconfigRead?: (tsconfigPath: string) => void;\n /**\n * Lookup cache to share across multiple bundles in one CLI run. Defaults to\n * a fresh cache scoped to this plugin instance when omitted.\n */\n cache?: TsconfigLookupCache;\n}\n\n/**\n * Create the rolldown plugin that falls back to tsconfig `paths` aliases from\n * the importing file's own nearest tsconfig.\n * @param options - Resolution context for bundlers whose entry inlines user code\n * @returns Rolldown plugin to add to a bundler's plugin list\n */\nexport function createTsconfigPathsPlugin(\n options: TsconfigPathsPluginOptions = {},\n): rolldown.Plugin {\n const { tsconfigCache, contextCache } = options.cache ?? createTsconfigLookupCache();\n\n return {\n name: \"tailor-tsconfig-paths\",\n resolveId: {\n order: \"post\",\n async handler(source, importer) {\n if (!importer) return null;\n if (source.startsWith(\".\") || source.startsWith(\"/\") || source.startsWith(\"\\0\")) {\n return null;\n }\n\n const resolutionBasis = importer.startsWith(\"\\0\")\n ? options.virtualEntrySourceFile\n : importer;\n if (!resolutionBasis) return null;\n\n // Deliberately ahead of the resolvability check below: the lookup reports\n // the tsconfigs this import depends on, and a caching bundler needs them\n // even when the import resolves without any alias today. Editing those\n // tsconfigs later can change the outcome.\n const resolution = getResolutionContext(\n path.dirname(resolutionBasis),\n tsconfigCache,\n contextCache,\n options.onTsconfigRead,\n );\n if (!resolution) return null;\n\n const candidates = resolution.matcher(source);\n if (candidates.length === 0) return null;\n\n const alreadyResolvable = await this.resolve(source, importer, { skipSelf: true });\n if (alreadyResolvable) return null;\n\n // Each mapped candidate goes back through rolldown as an absolute\n // specifier, so extension substitution, directory index files and\n // `package.json` `main`/`exports` all behave exactly as they do for a\n // relative import. Probing the filesystem here instead would have to\n // restate those rules and would drift from them.\n for (const candidate of candidates) {\n const resolved = await this.resolve(candidate, importer, { skipSelf: true });\n if (resolved) return resolved;\n }\n return null;\n },\n },\n };\n}\n\nfunction getResolutionContext(\n startDir: string,\n tsconfigCache: Cache,\n contextCache: Map<string, ResolutionContext | null>,\n onTsconfigRead?: (tsconfigPath: string) => void,\n): ResolutionContext | null {\n const cached = contextCache.get(startDir);\n if (cached !== undefined) {\n // A shared cache (see TsconfigLookupCache) may have resolved this exact\n // startDir already for a different bundle; that bundle's own dependency\n // list must not become this caller's, so still report every tsconfig\n // reachable from tsconfigCache — a superset is safe (extra invalidation\n // at worst), missing one is not (a stale bundle never rebuilds).\n reportTsconfigDependencies(tsconfigCache, onTsconfigRead);\n return cached;\n }\n\n const tsconfig = getTsconfig(startDir, \"tsconfig.json\", tsconfigCache);\n reportTsconfigDependencies(tsconfigCache, onTsconfigRead);\n const paths = tsconfig?.config.compilerOptions?.paths;\n const matcher = paths && Object.keys(paths).length > 0 ? createPathsMatcher(tsconfig) : null;\n const resolution = matcher ? { matcher } : null;\n\n contextCache.set(startDir, resolution);\n return resolution;\n}\n\nfunction reportTsconfigDependencies(\n cache: Cache,\n onTsconfigRead?: (tsconfigPath: string) => void,\n): void {\n if (!onTsconfigRead) return;\n\n const directories = new Set<string>();\n const dependencies = new Set<string>();\n for (const [key, value] of cache) {\n const dependencyPath = dependencyPathFromCacheKey(key);\n if (!dependencyPath) continue;\n if (key.startsWith(\"statSync:\") && isDirectoryStat(value)) {\n directories.add(dependencyPath);\n } else {\n dependencies.add(dependencyPath);\n }\n }\n for (const dependencyPath of dependencies) {\n if (!directories.has(dependencyPath)) onTsconfigRead(dependencyPath);\n }\n}\n\nfunction dependencyPathFromCacheKey(key: string): string | undefined {\n const readFilePrefix = \"readFileSync:\";\n const readFileSuffix = \":utf8\";\n if (key.startsWith(readFilePrefix) && key.endsWith(readFileSuffix)) {\n return key.slice(readFilePrefix.length, -readFileSuffix.length);\n }\n for (const prefix of [\"existsSync:\", \"statSync:\"]) {\n if (key.startsWith(prefix)) return key.slice(prefix.length);\n }\n return undefined;\n}\n\nfunction isDirectoryStat(value: unknown): boolean {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"isDirectory\" in value &&\n typeof value.isDirectory === \"function\" &&\n value.isDirectory()\n );\n}\n","import * as path from \"pathe\";\nimport type { Plugin } from \"rolldown\";\n\ntype VirtualEntry = {\n input: string;\n plugin: Plugin;\n};\n\n/**\n * Create an in-memory rolldown entry module with a deterministic ID.\n * @param name - Logical entry name\n * @param code - Entry module source\n * @param sourceType - Parser type for the generated module\n * @param resolutionBasis - Source file whose directory resolves generated imports\n * @returns Rolldown input and plugin for loading the entry\n */\nexport function createVirtualEntry(\n name: string,\n code: string,\n sourceType: \"js\" | \"ts\" = \"js\",\n resolutionBasis?: string,\n): VirtualEntry {\n const input = `tailor-entry:${name}.${sourceType}`;\n const resolvedId = `\\0${input}`;\n\n return {\n input,\n plugin: {\n name: \"tailor-virtual-entry\",\n async resolveId(source, importer) {\n if (source === input && importer === undefined) return resolvedId;\n if (\n importer !== resolvedId ||\n !resolutionBasis ||\n source.startsWith(\".\") ||\n path.isAbsolute(source) ||\n source.startsWith(\"\\0\")\n ) {\n return null;\n }\n return this.resolve(source, resolutionBasis, { skipSelf: true });\n },\n load(id) {\n return id === resolvedId ? code : null;\n },\n },\n };\n}\n\n/**\n * Resolve bare imports in a generated on-disk entry from its owning project.\n *\n * Generated entries live under the CLI output directory, which may be outside\n * the project selected by a config path. Resolving their injected dependencies\n * from that output directory would ignore the selected project's installation.\n * @param entryPath - Absolute path of the generated entry\n * @param projectDir - Directory whose dependencies the generated entry uses\n * @returns Rolldown plugin that rebases generated bare imports\n */\nexport function createGeneratedEntryResolverPlugin(entryPath: string, projectDir: string): Plugin {\n const normalizedEntryPath = path.resolve(entryPath);\n const resolutionBasis = path.join(path.resolve(projectDir), \"__tailor_sdk_generated_entry__.js\");\n\n return {\n name: \"tailor-generated-entry-resolver\",\n async resolveId(source, importer) {\n if (\n importer === undefined ||\n path.resolve(importer) !== normalizedEntryPath ||\n source.startsWith(\".\") ||\n path.isAbsolute(source) ||\n source.startsWith(\"\\0\")\n ) {\n return null;\n }\n return this.resolve(source, resolutionBasis, { skipSelf: true });\n },\n };\n}\n","import * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { createStartTransformPlugin } from \"#/cli/services/workflow/start-transformer\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\n/**\n * Options for bundling auth hooks\n */\nexport interface BundleAuthHooksOptions {\n /** Absolute path to the config file that exports the auth definition */\n configPath: string;\n /** Auth namespace name */\n authName: string;\n /** Dot-path expression to reach the handler from the config's default export */\n handlerAccessPath: string;\n /** Environment variables to inject into the hook args */\n env?: Record<string, string | number | boolean>;\n /** Start context for workflow/job transformations */\n startContext?: StartContext;\n /** Optional bundle cache for skipping unchanged builds */\n cache?: BundleCache;\n /** Whether to enable inline sourcemaps */\n inlineSourcemap?: boolean;\n /** Controls which console calls are kept in bundled code */\n bundleLogLevel?: LogLevel;\n /** Directory the tsconfig is resolved against */\n baseDir: string;\n /** Optional tsconfig lookup cache shared across bundles in this CLI run */\n tsconfigCache?: TsconfigLookupCache;\n}\n\n/**\n * Bundle a single auth hook handler.\n *\n * Follows the same pattern as the executor bundler:\n * 1. Generate an in-memory entry module that re-exports the handler as `main`\n * 2. Bundle with rolldown + tree-shaking\n * @param options - Bundle options\n * @returns Map of function name to bundled code\n */\nexport async function bundleAuthHooks(\n options: BundleAuthHooksOptions,\n): Promise<Map<string, string>> {\n const {\n configPath,\n authName,\n handlerAccessPath,\n env = {},\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n baseDir,\n tsconfigCache,\n } = options;\n\n logger.newline();\n logger.log(`Bundling auth hook for ${styles.info(`\"${authName}\"`)}`);\n\n const absoluteConfigPath = path.resolve(configPath);\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n const functionName = `auth-hook--${authName}--before-login`;\n\n const serializedStartContext = serializeStartContext(startContext);\n\n // Include sorted env variables as a prefix so that env changes invalidate the cache\n const sortedEnvPrefix = JSON.stringify(\n Object.fromEntries(Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))),\n );\n const contextHash = computeBundlerContextHash({\n sourceFile: absoluteConfigPath,\n extraContext: serializedStartContext,\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n prefix: sortedEnvPrefix,\n });\n\n const code = await withCache({\n cache,\n kind: \"auth-hook\",\n name: functionName,\n sourceFile: absoluteConfigPath,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const entryContent = ml /* js */ `\n import _config from \"${absoluteConfigPath}\";\n const __auth_hook_function = _config.${handlerAccessPath};\n export async function main(args) {\n const env = ${JSON.stringify(env)};\n return await __auth_hook_function({ ...args, env });\n }\n `;\n const entry = createVirtualEntry(\n `auth-hook:${functionName}`,\n entryContent,\n \"js\",\n absoluteConfigPath,\n );\n\n const startPlugin = createStartTransformPlugin(startContext);\n const plugins: rolldown.Plugin[] = [entry.plugin];\n if (startPlugin) {\n plugins.push(startPlugin);\n }\n plugins.push(\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n transform: {\n define: {\n \"process.env.TAILOR_APP_LOG_LEVEL\": JSON.stringify(bundleLogLevel),\n },\n },\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n return result.output[0].code;\n },\n });\n\n logger.log(`${styles.success(\"Bundled\")} auth hook for ${styles.info(`\"${authName}\"`)}`);\n\n const bundledCode = new Map<string, string>();\n bundledCode.set(functionName, code);\n return bundledCode;\n}\n","import { parseSync } from \"oxc-parser\";\n\nconst MAX_GENERATED_CODE_LENGTH = 2_000;\n\nfunction formatGeneratedCode(expr: string): string {\n if (expr.length <= MAX_GENERATED_CODE_LENGTH) {\n return `Generated code:\\n${expr}`;\n }\n return (\n `Generated code (truncated to ${MAX_GENERATED_CODE_LENGTH} of ${expr.length} characters):\\n` +\n `${expr.slice(0, MAX_GENERATED_CODE_LENGTH)}\\n...`\n );\n}\n\n/**\n * Assert that a generated script expression is syntactically valid JavaScript.\n * Invalid generated code would otherwise surface much later as a confusing\n * bundler or platform-side syntax error, far from the definition that caused it.\n * @param expr - Generated JavaScript expression\n * @param context - What generated the expression, used to label the error\n * @returns The expression unchanged when it parses successfully\n */\nexport function assertParsableExpression(expr: string, context: string): string {\n const { errors } = parseSync(\"generated-expr.js\", `(${expr}\\n);`);\n if (errors.length === 0) {\n return expr;\n }\n const details = errors.map((error) => ` - ${error.message}`).join(\"\\n\");\n throw new Error(\n `Generated ${context} script is not valid JavaScript.\\n` +\n `Parse errors:\\n${details}\\n` +\n formatGeneratedCode(expr),\n );\n}\n","import type { ScriptExprKind } from \"./types\";\n\n// Identifier the table-level wrapper (buildTypeScripts in type-script.ts) binds\n// tailorPrincipalMap's result to, at most once per table, so per-hook exprs\n// below can reference it instead of re-embedding the full mapping on every hook.\nexport const PRINCIPAL_VAR = \"_principal\";\n\n/**\n * Build the call-argument list a script expression is invoked with, keyed by the\n * kind of hook/validator it wraps. Shared by every caller that assembles a\n * `(${normalized})(${callArgs})` script expression - both `field.ts` and the CLI's\n * hook-precompilation bundler - so the two never drift apart.\n * @param kind - Kind of hook/validator the expression is for\n * @returns The literal source of the arguments (an object literal for every kind\n * except `typeValidate`, which also appends a trailing `__issues` argument)\n */\nexport function buildHookCallArgs(kind: ScriptExprKind): string {\n switch (kind) {\n case \"validate\":\n return `{ value: _value }`;\n case \"hooks.create\":\n return `{ input: _value, invoker: ${PRINCIPAL_VAR}, now: _now }`;\n case \"hooks.update\":\n return `{ input: _value, oldValue: _oldValue, invoker: ${PRINCIPAL_VAR}, now: _now }`;\n case \"typeHook.create\":\n case \"typeHook.update\":\n return `{ input: _input, oldRecord: _oldRecord, invoker: ${PRINCIPAL_VAR}, now: _now }`;\n case \"typeValidate\":\n return `{ newRecord: _newRecord, oldRecord: _oldRecord, invoker: ${PRINCIPAL_VAR} }, __issues`;\n default:\n throw new Error(`Unknown script expr kind: ${kind satisfies never}`);\n }\n}\n","import type { PrecompiledScriptExprKey, PrecompiledScriptExprMap, ScriptExprKind } from \"./types\";\n\nconst PRECOMPILED_EXPR_KEY: PrecompiledScriptExprKey =\n \"tailor-platform/sdk:precompiled-script-expr\";\nconst PRECOMPILED_EXPR_SYMBOL = Symbol.for(PRECOMPILED_EXPR_KEY);\n\ntype AnyFunction = (...args: never[]) => unknown;\n\nconst precompiledExprs = new WeakMap<AnyFunction, PrecompiledScriptExprMap>();\n\n/**\n * Store a precompiled script expression for a function.\n * Keyed by role so one function reused across roles keeps a distinct expression per role.\n * @param fn - Hook or validator function the expression was compiled from.\n * @param kind - Role the expression was compiled for.\n * @param expr - Precompiled script expression.\n */\nexport function setPrecompiledScriptExpr(fn: AnyFunction, kind: ScriptExprKind, expr: string) {\n const entry = precompiledExprs.get(fn) ?? {};\n entry[kind] = expr;\n precompiledExprs.set(fn, entry);\n}\n\n/**\n * Read a precompiled script expression for a function.\n * @param fn - Hook or validator function the expression was compiled from.\n * @param kind - Role the expression was compiled for.\n * @returns Precompiled script expression if attached for that role.\n */\nexport function getPrecompiledScriptExpr(\n fn: AnyFunction,\n kind: ScriptExprKind,\n): string | undefined {\n const pinnedExprs = Object.hasOwn(fn, PRECOMPILED_EXPR_SYMBOL)\n ? (fn as unknown as Record<symbol, unknown>)[PRECOMPILED_EXPR_SYMBOL]\n : undefined;\n if (typeof pinnedExprs === \"object\" && pinnedExprs !== null && Object.hasOwn(pinnedExprs, kind)) {\n const pinnedExpr = (pinnedExprs as Partial<Record<ScriptExprKind, unknown>>)[kind];\n if (typeof pinnedExpr === \"string\") {\n return pinnedExpr;\n }\n }\n return precompiledExprs.get(fn)?.[kind];\n}\n","import { parseSync } from \"oxc-parser\";\nimport { assertParsableExpression } from \"#/utils/script-expr\";\nimport { buildHookCallArgs } from \"./hook-args-object\";\nimport { getPrecompiledScriptExpr } from \"./hooks-validate-precompiled-expr\";\nimport type {\n TailorAnyDBField,\n DBFieldMetadata,\n RawRelationConfig,\n} from \"#/configure/services/tailordb/types\";\nimport type { OperatorFieldConfig, ScriptExprKind } from \"#/parser/service/tailordb/types\";\nimport type { TailorDBTypeRaw as TailorDBTypeSchemaOutput } from \"#/types/tailordb.generated\";\n\ntype FieldScriptContext = {\n tableName: string;\n fieldPath: readonly string[];\n};\n\ntype ScriptFunction = (...args: never[]) => unknown;\n\ntype ScriptContextKind = Extract<ScriptExprKind, \"hooks.create\" | \"hooks.update\" | \"validate\">;\n\nconst NIL_UUID = \"00000000-0000-0000-0000-000000000000\";\n\n/**\n * Per-source field expressions for {@link makePrincipalExpr}. Each value is a JS\n * snippet evaluated against the raw server payload bound to `$raw`.\n */\ninterface PrincipalFieldExprs {\n /**\n * Raw type accessor. `raw` is matched against `USER_TYPE_*` when normalizing;\n * `fallback` (defaulting to `raw`) supplies the type for non-matching values,\n * which lets sources whose primary field is empty fall back to a secondary.\n */\n type: { raw: string; fallback?: string };\n /** Raw id accessor. */\n id: string;\n workspaceId: string;\n attributes: string;\n attributeList: string;\n}\n\ninterface MakePrincipalExprOptions {\n source: string;\n fields: PrincipalFieldExprs;\n normalize: boolean;\n requireId?: boolean;\n}\n\n/**\n * Build the server→SDK principal mapping expression shared across services.\n *\n * All principal-bearing call sites (`caller`, `actor`, `invoker`) must agree on\n * the `TailorPrincipal | null` shape, so they are generated here rather than\n * hand-written per service.\n * @param options - Mapping source and field expressions\n * @param options.source - Expression yielding the raw server payload (e.g. `user`)\n * @param options.fields - Per-source accessors for each principal field\n * @param options.normalize - When true, map `USER_TYPE_*` to SDK type literals and\n * return `null` for unspecified types or the nil-UUID id; when false, the\n * payload is already in SDK shape and only `null` pass-through is applied\n * @param options.requireId - When true, missing ids are also mapped to `null`\n * @returns A JS expression string evaluating to `TailorPrincipal | null`\n */\nexport function makePrincipalExpr(options: MakePrincipalExprOptions): string {\n const { source, fields, normalize, requireId = false } = options;\n const body = /* js */ `{\n id,\n type,\n workspaceId: ${fields.workspaceId},\n attributes: ${fields.attributes},\n attributeList: ${fields.attributeList},\n }`;\n if (!normalize) {\n return /* js */ `(($raw) => {\n if (!$raw) {\n return null;\n }\n const id = ${fields.id};\n const type = ${fields.type.raw};\n return ${body};\n})(${source})`;\n }\n const missingIdGuard = requireId ? \" || !id\" : \"\";\n return /* js */ `(($raw) => {\n if (!$raw) {\n return null;\n }\n const type = ${fields.type.raw} === \"USER_TYPE_USER\"\n ? \"user\"\n : ${fields.type.raw} === \"USER_TYPE_MACHINE_USER\"\n ? \"machine_user\"\n : ${fields.type.fallback ?? fields.type.raw};\n const id = ${fields.id};\n if (!type || type === \"USER_TYPE_UNSPECIFIED\" || id === \"${NIL_UUID}\"${missingIdGuard}) {\n return null;\n }\n return ${body};\n})(${source})`;\n}\n\n// Since there's naming difference between platform and SDK, use this mapping in\n// all scripts to provide variables that match `TailorPrincipal | null`.\nexport const tailorPrincipalMap = makePrincipalExpr({\n source: \"user\",\n normalize: true,\n fields: {\n type: { raw: \"$raw?.type\" },\n id: \"$raw.id\",\n workspaceId: \"$raw.workspace_id ?? $raw.workspaceId\",\n attributes: \"$raw.attribute_map ?? $raw.attributeMap ?? {}\",\n attributeList: \"$raw.attributes ?? []\",\n },\n});\n\n/**\n * Parse `wrapped` and return the first property of the top-level parenthesized\n * object expression, or `undefined` if it does not parse as one.\n * @param wrapped - Source wrapped as `({ ... })`\n * @returns The first object property, or `undefined`\n */\nconst firstObjectProperty = (wrapped: string) => {\n const parseResult = parseSync(\"stringify-function.ts\", wrapped, { sourceType: \"module\" });\n if (parseResult.errors.length > 0) {\n return undefined;\n }\n const expressionStatement = parseResult.program.body[0];\n const objectExpression =\n expressionStatement?.type === \"ExpressionStatement\" &&\n expressionStatement.expression.type === \"ParenthesizedExpression\"\n ? expressionStatement.expression.expression\n : undefined;\n return objectExpression?.type === \"ObjectExpression\" ? objectExpression.properties[0] : undefined;\n};\n\n/**\n * Convert a function to a string representation.\n * Handles method shorthand syntax (e.g., `create() { ... }`) by converting it to\n * an anonymous function expression (e.g., `function () { ... }`), including\n * `async` and generator variants and shorthand bodies that themselves contain\n * arrow functions. The result is anonymous (rather than reusing the method\n * name) so a body that references an outer variable of the same name is not\n * shadowed by the generated function's own binding.\n * @param fn - Function to stringify\n * @returns Stringified function source\n */\n// oxlint-disable-next-line typescript/no-unsafe-function-type\nexport const stringifyFunction = (fn: Function): string => {\n const src = fn.toString().trim();\n // `src` is already a valid function/arrow expression (e.g. `function () {}`,\n // `() => {}`) if it parses as an object property value as-is; leave it untouched.\n if (firstObjectProperty(`({m: ${src}})`)) {\n return src;\n }\n // Otherwise, method shorthand (e.g. `create() {}`, `async create() {}`) is\n // only valid inside an object literal, so parse it as an object property to\n // detect and convert it via the AST rather than guessing from source text.\n const wrapped = `({${src}})`;\n const property = firstObjectProperty(wrapped);\n\n if (property?.type === \"Property\" && property.method && property.computed) {\n throw new Error(\n \"Computed-key method shorthand cannot be converted to a TailorDB script expression. \" +\n \"Use an arrow function or function expression instead.\",\n );\n }\n if (\n property?.type === \"Property\" &&\n property.method &&\n property.value.type === \"FunctionExpression\"\n ) {\n const { async, generator } = property.value;\n const body = wrapped.slice(property.value.start, property.value.end);\n return `${async ? \"async \" : \"\"}function${generator ? \"*\" : \"\"} ${body}`;\n }\n return src;\n};\n\nfunction formatScriptContext(kind: ScriptContextKind, context: FieldScriptContext | undefined) {\n if (!context) {\n return kind === \"validate\" ? kind : \"hooks\";\n }\n return `${kind} for ${context.tableName}.${context.fieldPath.join(\".\")}`;\n}\n\n/**\n * Convert a hook or validator function to a script expression.\n * @param fn - Hook or validator function\n * @param kind - Label naming the source of the expression in conversion errors\n * @param context - Optional field context for conversion errors\n * @returns JavaScript expression calling the function\n */\nconst convertToScriptExpr = (\n fn: ScriptFunction,\n kind: ScriptContextKind,\n context: FieldScriptContext | undefined,\n): string => {\n const precompiledExpr = getPrecompiledScriptExpr(fn, kind);\n if (precompiledExpr) {\n return precompiledExpr;\n }\n const normalized = stringifyFunction(fn);\n return assertParsableExpression(\n `(${normalized})(${buildHookCallArgs(kind)})`,\n formatScriptContext(kind, context),\n );\n};\n\n// oxlint-disable-next-line typescript/no-unsafe-function-type\nexport const convertTypeHookToExpr = (fn: Function, op: \"create\" | \"update\"): string => {\n const kind = `typeHook.${op}` as const;\n const precompiledExpr = getPrecompiledScriptExpr(fn as (...args: never[]) => unknown, kind);\n if (precompiledExpr) {\n return precompiledExpr;\n }\n const normalized = stringifyFunction(fn);\n return assertParsableExpression(`(${normalized})(${buildHookCallArgs(kind)})`, \"type-hook\");\n};\n\n// oxlint-disable-next-line typescript/no-unsafe-function-type\nexport const convertTypeValidateToExpr = (fn: Function): string => {\n const precompiledExpr = getPrecompiledScriptExpr(\n fn as (...args: never[]) => unknown,\n \"typeValidate\",\n );\n if (precompiledExpr) {\n return precompiledExpr;\n }\n const normalized = stringifyFunction(fn);\n return assertParsableExpression(\n `(${normalized})(${buildHookCallArgs(\"typeValidate\")})`,\n \"type-validate\",\n );\n};\n\n/**\n * Parse TailorDBField into OperatorFieldConfig.\n * This transforms user-defined functions into script expressions.\n * @param field - TailorDB field definition\n * @param context - Optional field context for conversion errors\n * @returns Parsed operator field configuration\n */\nexport function parseFieldConfig(\n field: TailorDBTypeSchemaOutput[\"fields\"][string],\n context?: FieldScriptContext,\n): OperatorFieldConfig {\n const metadata = field.metadata as DBFieldMetadata;\n const fieldType = field.type;\n // Access rawRelation via getter (if available)\n const rawRelation = (field as unknown as { rawRelation?: RawRelationConfig }).rawRelation;\n\n if (context && context.fieldPath.length > 1 && metadata.default !== undefined) {\n throw new Error(\n `Field \"${context.fieldPath.join(\".\")}\" on table \"${context.tableName}\": ` +\n `.default() cannot be used on nested inner fields`,\n );\n }\n\n if (context && context.fieldPath.length > 1 && metadata.hooks) {\n throw new Error(\n `Field \"${context.fieldPath.join(\".\")}\" on table \"${context.tableName}\": ` +\n `.hooks() cannot be used on nested inner fields`,\n );\n }\n\n const nestedFields = field.fields as Record<string, TailorAnyDBField> | undefined;\n return {\n type: fieldType,\n ...metadata,\n rawRelation,\n ...(fieldType === \"nested\" && nestedFields && Object.keys(nestedFields).length > 0\n ? {\n fields: Object.entries(nestedFields).reduce(\n (acc, [key, nestedField]) => {\n acc[key] = parseFieldConfig(\n nestedField,\n context && {\n ...context,\n fieldPath: [...context.fieldPath, key],\n },\n );\n return acc;\n },\n {} as Record<string, OperatorFieldConfig>,\n ),\n }\n : {}),\n validate: metadata.validate?.map((fn) => ({\n script: {\n expr: convertToScriptExpr(fn, \"validate\", context),\n },\n errorMessage: \"\",\n })),\n hooks: metadata.hooks\n ? {\n create: metadata.hooks.create\n ? {\n expr: convertToScriptExpr(\n metadata.hooks.create as ScriptFunction,\n \"hooks.create\",\n context,\n ),\n }\n : undefined,\n update: metadata.hooks.update\n ? {\n expr: convertToScriptExpr(\n metadata.hooks.update as ScriptFunction,\n \"hooks.update\",\n context,\n ),\n }\n : undefined,\n }\n : undefined,\n serial: metadata.serial\n ? {\n start: metadata.serial.start,\n maxValue: metadata.serial.maxValue,\n format: \"format\" in metadata.serial ? metadata.serial.format : undefined,\n }\n : undefined,\n };\n}\n","type NormalizedPermit = \"allow\" | \"deny\";\n\nexport interface NormalizedActionPermission<Condition> {\n conditions: Condition[];\n permit: NormalizedPermit;\n description?: string;\n}\n\n/**\n * Check whether a permission rule uses the object format (`{ conditions, permit?, description? }`).\n * @param p - A raw permission rule\n * @returns Whether the rule is in object format\n */\nfunction isObjectPermissionFormat(\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 isSingleConditionFormat(cond: readonly unknown[]): boolean {\n return cond.length >= 2 && typeof cond[1] === \"string\"; // Check if middle element is an operator\n}\n\nfunction normalizeOperand(operand: unknown): unknown {\n if (operand === null) {\n throw new Error(\"Invalid permission operand: null\");\n }\n if (typeof operand === \"object\" && !Array.isArray(operand)) {\n if (\"user\" in operand) {\n const user = operand.user;\n return { user: user === \"id\" ? \"_id\" : user };\n }\n }\n return operand;\n}\n\n/**\n * Build the permission normalizer shared by the services that accept the\n * condition-triple permission formats (object form, single-condition\n * shorthand, and condition-array shorthand).\n *\n * The services differ only in their operator vocabulary and in the type they\n * give the normalized conditions, so both are parameters.\n * @param operatorMap - Service-specific map from source operators to normalized names\n * @returns `normalizeConditions` and `normalizeActionPermission` for the service\n */\nexport function createPermissionNormalizer<Operator extends string, Condition>(\n operatorMap: Record<Operator, string>,\n) {\n type RawCondition = readonly [unknown, Operator, unknown];\n\n function normalizeConditions(conditions: readonly RawCondition[]): Condition[] {\n return conditions.map((cond) => {\n const [left, operator, right] = cond;\n return [normalizeOperand(left), operatorMap[operator], normalizeOperand(right)];\n }) as Condition[];\n }\n\n function normalizeActionPermission(permission: unknown): NormalizedActionPermission<Condition> {\n // object format\n if (isObjectPermissionFormat(permission)) {\n const conditions = permission.conditions as RawCondition | readonly RawCondition[];\n return {\n conditions: normalizeConditions(\n isSingleConditionFormat(conditions)\n ? [conditions as RawCondition]\n : (conditions as readonly RawCondition[]),\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 // Single condition shorthand, with an optional trailing permit boolean\n if (isSingleConditionFormat(permission)) {\n const [op1, operator, op2, permit] = [...permission, true] as [\n unknown,\n Operator,\n unknown,\n boolean,\n ];\n return {\n conditions: normalizeConditions([[op1, operator, op2]]),\n permit: permit ? \"allow\" : \"deny\",\n };\n }\n\n // Array of conditions format, with an optional permit boolean among the items\n const conditions: RawCondition[] = [];\n let permit = true;\n for (const item of permission as readonly unknown[]) {\n if (typeof item === \"boolean\") {\n permit = item;\n continue;\n }\n conditions.push(item as RawCondition);\n }\n\n return {\n conditions: normalizeConditions(conditions),\n permit: permit ? \"allow\" : \"deny\",\n };\n }\n\n return { normalizeConditions, normalizeActionPermission };\n}\n\n/**\n * Whether an object-format rule omits `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 such rules to nudge authors toward setting `permit`\n * explicitly.\n * @param rule - A raw permission rule\n * @returns Whether the rule is object-format with `permit` omitted\n */\nexport function hasOmittedPermit(rule: unknown): boolean {\n return isObjectPermissionFormat(rule) && rule.permit === undefined;\n}\n","import { createPermissionNormalizer, hasOmittedPermit } from \"#/parser/service/permission\";\nimport type {\n StandardTailorTypePermission,\n StandardTailorTypeGqlPermission,\n StandardActionPermission,\n StandardPermissionCondition,\n StandardGqlPermissionPolicy,\n Permissions,\n} from \"#/parser/service/tailordb/types\";\nimport type { GqlOperations, RawPermissions } from \"#/types/tailordb.generated\";\n\n// Raw permission types for normalize function parameters\ntype PermissionOperator = \"=\" | \"!=\" | \"in\" | \"not in\" | \"hasAny\" | \"not hasAny\";\n\ntype PermissionCondition = readonly [unknown, PermissionOperator, unknown];\n\nconst { normalizeConditions, normalizeActionPermission: normalizeRawActionPermission } =\n createPermissionNormalizer<PermissionOperator, StandardPermissionCondition>({\n \"=\": \"eq\",\n \"!=\": \"ne\",\n in: \"in\",\n \"not in\": \"nin\",\n hasAny: \"hasAny\",\n \"not hasAny\": \"nhasAny\",\n });\n\ntype GqlPermissionPolicy = {\n conditions: readonly PermissionCondition[];\n actions: \"all\" | readonly GqlPermissionAction[];\n permit?: boolean;\n description?: string;\n};\n\ntype GqlPermissionAction = \"read\" | \"create\" | \"update\" | \"delete\" | \"aggregate\" | \"bulkUpsert\";\n\n/**\n * Normalize record-level permissions into a standard structure.\n * @param permission - Tailor table permission\n * @returns Normalized record permissions\n */\nfunction normalizePermission(\n permission: NonNullable<RawPermissions[\"record\"]>,\n): StandardTailorTypePermission {\n const keys = Object.keys(permission) as Array<keyof typeof permission>;\n return keys.reduce((acc, action) => {\n acc[action] = permission[action].map((p) => normalizeActionPermission(p));\n return acc;\n // oxlint-disable-next-line no-explicit-any\n }, {} as any);\n}\n\n/**\n * Normalize GraphQL permissions into a standard structure.\n * @param permission - Tailor GQL permission\n * @returns Normalized GQL permissions\n */\nexport function normalizeGqlPermission(\n permission: NonNullable<RawPermissions[\"gql\"]>,\n): StandardTailorTypeGqlPermission {\n return (permission as readonly GqlPermissionPolicy[]).map((policy) => normalizeGqlPolicy(policy));\n}\n\nfunction normalizeGqlPolicy(policy: GqlPermissionPolicy): StandardGqlPermissionPolicy {\n return {\n conditions: normalizeConditions(policy.conditions),\n actions: policy.actions === \"all\" ? [\"all\"] : policy.actions,\n permit: policy.permit ? \"allow\" : \"deny\",\n description: policy.description,\n } as StandardGqlPermissionPolicy;\n}\n\n/**\n * Parse raw permissions into normalized permissions.\n * This is the main entry point for permission parsing in the parser layer.\n * @param rawPermissions - Raw permissions definition\n * @returns Normalized permissions\n */\nexport function parsePermissions(rawPermissions: RawPermissions): Permissions {\n return {\n ...(rawPermissions.record && {\n record: normalizePermission(rawPermissions.record),\n }),\n ...(rawPermissions.gql && {\n gql: normalizeGqlPermission(rawPermissions.gql),\n }),\n };\n}\n\n/**\n * Normalize a single action permission into the standard format.\n * @param permission - Raw permission definition\n * @returns Normalized action permission\n */\nexport function normalizeActionPermission(permission: unknown): StandardActionPermission {\n return normalizeRawActionPermission(permission);\n}\n\n/**\n * Find object-format permission rules that omit `permit` (which defaults to\n * `deny` there, unlike the array shorthand), so the CLI can warn about them.\n * @param rawPermissions - Raw permissions definition\n * @returns Dotted locations of offending rules, e.g. `record.read[0]`, `gql[1]`\n */\nexport function findOmittedPermitRules(rawPermissions: RawPermissions): string[] {\n const locations: string[] = [];\n\n const record = rawPermissions.record;\n if (record) {\n for (const action of Object.keys(record) as Array<keyof typeof record>) {\n record[action].forEach((rule: unknown, index: number) => {\n if (hasOmittedPermit(rule)) {\n locations.push(`record.${String(action)}[${index}]`);\n }\n });\n }\n }\n\n // GQL policies are always object form, so no isObjectFormat guard is needed.\n const gql = rawPermissions.gql;\n if (gql) {\n (gql as readonly GqlPermissionPolicy[]).forEach((policy, index) => {\n if (policy.permit === undefined) {\n locations.push(`gql[${index}]`);\n }\n });\n }\n\n return locations;\n}\n\n/**\n * Check whether GraphQL exposure is fully disabled for a table, given its\n * effective gqlOperations (the table's own setting, falling back to the\n * TailorDB namespace default). `undefined` means the default of all\n * operations enabled, so it is never considered fully disabled.\n * @param gqlOperations - Effective, normalized gqlOperations configuration\n * @returns Whether create, update, delete, and read are all explicitly disabled\n */\nexport function isGqlOperationsFullyDisabled(gqlOperations: GqlOperations | undefined): boolean {\n if (!gqlOperations) {\n return false;\n }\n return (\n gqlOperations.create === false &&\n gqlOperations.update === false &&\n gqlOperations.delete === false &&\n gqlOperations.read === false\n );\n}\n\n/**\n * Missing permission configuration detected for a TailorDB table.\n */\nexport interface MissingTypePermissionConfig {\n /** Whether record-level permission (`.permission()`) is missing */\n missingPermission: boolean;\n /** Whether GraphQL permission (`.gqlPermission()`) is missing while GraphQL exposure is enabled */\n missingGqlPermission: boolean;\n}\n\n/**\n * Find missing permission configuration for a TailorDB table.\n *\n * Record-level permission is always required: TailorDB denies all record\n * operations for a table without it, regardless of whether the table is\n * exposed via GraphQL. GraphQL permission is required whenever GraphQL\n * exposure is enabled for the table (the default, unless every operation is\n * explicitly disabled via `gqlOperations`).\n * @param rawPermissions - Raw permissions definition for the table\n * @param effectiveGqlOperations - The table's own gqlOperations, falling back to the namespace default\n * @returns Which permission configuration, if any, is missing\n */\nexport function findMissingPermissionConfig(\n rawPermissions: RawPermissions,\n effectiveGqlOperations: GqlOperations | undefined,\n): MissingTypePermissionConfig {\n return {\n missingPermission: !rawPermissions.record,\n missingGqlPermission:\n !rawPermissions.gql && !isGqlOperationsFullyDisabled(effectiveGqlOperations),\n };\n}\n","import * as inflection from \"inflection\";\nimport { isPluginGeneratedTable } from \"#/parser/service/tailordb/type-source\";\nimport { convertTypeHookToExpr, convertTypeValidateToExpr, parseFieldConfig } from \"./field\";\nimport { parsePermissions } from \"./permission\";\nimport {\n validateRelationConfig,\n processRelationMetadata,\n buildRelationInfo,\n applyRelationMetadataToFieldConfig,\n} from \"./relation\";\nimport type { TailorDBField } from \"#/configure/services/tailordb/types\";\nimport type {\n TypeSourceInfo,\n ParsedField,\n ParsedRelationship,\n TailorDBType,\n} from \"#/parser/service/tailordb/types\";\nimport type { TailorDBTypeRaw as TailorDBTypeSchemaOutput } from \"#/types/tailordb.generated\";\n\n/**\n * Parse multiple TailorDB tables, build relationships, and validate uniqueness.\n * This is the main entry point for parsing TailorDB tables.\n * @param rawTypes - Raw TailorDB tables keyed by name\n * @param namespace - TailorDB namespace name\n * @param typeSourceInfo - Optional table source information\n * @returns Parsed tables\n */\nexport function parseTypes(\n rawTypes: Record<string, TailorDBTypeSchemaOutput>,\n namespace: string,\n typeSourceInfo?: TypeSourceInfo,\n): Record<string, TailorDBType> {\n const types = createRecord<TailorDBType>();\n const allTableNames = new Set(Object.keys(rawTypes));\n\n for (const [tableName, type] of Object.entries(rawTypes)) {\n types[tableName] = parseTailorDBType(type, allTableNames, rawTypes, typeSourceInfo);\n }\n\n buildBackwardRelationships(types, namespace, typeSourceInfo);\n validatePluralFormUniqueness(types, namespace, typeSourceInfo);\n\n return types;\n}\n\n/**\n * Parse a TailorDBTypeSchemaOutput into a TailorDBType.\n * @param type - TailorDB table to parse\n * @param allTableNames - Set of all TailorDB table names\n * @param rawTypes - All raw TailorDB tables keyed by name\n * @param typeSourceInfo - Optional table source information\n * @returns Parsed TailorDB table\n */\nfunction parseTailorDBType(\n type: TailorDBTypeSchemaOutput,\n allTableNames: Set<string>,\n rawTypes: Record<string, TailorDBTypeSchemaOutput>,\n typeSourceInfo?: TypeSourceInfo,\n): TailorDBType {\n const metadata = type.metadata;\n const pluralForm = metadata.settings?.pluralForm || inflection.pluralize(type.name);\n const typeLocation = formatTypeSourceLocation(getTypeSourceInfo(typeSourceInfo, type.name));\n\n const fields = createRecord<ParsedField>();\n const forwardRelationships = createRecord<ParsedRelationship>();\n\n for (const [fieldName, fieldDef] of Object.entries(type.fields) as [\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- TailorDBField requires generic type parameters\n TailorDBField<any, any>,\n ][]) {\n const context = { tableName: type.name, fieldName, allTableNames };\n let fieldConfig = parseFieldConfig(fieldDef, {\n tableName: type.name,\n fieldPath: [fieldName],\n });\n const rawRelation = fieldConfig.rawRelation;\n\n // Process relation if rawRelation is present\n if (rawRelation) {\n validateRelationConfig(rawRelation, context);\n\n // Validate that n-1/manyToOne relations cannot have explicit unique\n const isNToOne = [\"n-1\", \"manyToOne\", \"N-1\"].includes(rawRelation.type);\n if (isNToOne && fieldConfig.unique) {\n throw new Error(\n `Field \"${fieldName}\" on table \"${type.name}\": cannot set unique on n-1 (manyToOne) relation. ` +\n `Use 1-1 (oneToOne) relation instead, or remove the unique constraint.`,\n );\n }\n\n const relationMetadata = processRelationMetadata(rawRelation, context, fieldConfig.array);\n fieldConfig = applyRelationMetadataToFieldConfig(fieldConfig, relationMetadata);\n }\n\n // Validate that index/unique are not set on array fields\n if (fieldConfig.array && fieldConfig.index) {\n throw new Error(\n `Field \"${fieldName}\" on table \"${type.name}\": index cannot be set on array fields`,\n );\n }\n if (fieldConfig.array && fieldConfig.unique) {\n throw new Error(\n `Field \"${fieldName}\" on table \"${type.name}\": unique cannot be set on array fields`,\n );\n }\n\n const parsedField: ParsedField = { name: fieldName, config: fieldConfig };\n\n // Build relation info for forward/backward relationships\n const relationInfo = rawRelation ? buildRelationInfo(rawRelation, context) : undefined;\n if (relationInfo) {\n parsedField.relation = { ...relationInfo };\n const forwardName = relationInfo.forwardName;\n\n if (forwardName.length === 0) {\n throw new Error(\n `Forward relation name for field \"${fieldName}\" on table \"${type.name}\"${typeLocation} cannot be empty. ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a non-empty name.`,\n );\n }\n\n const existingForward = forwardRelationships[forwardName];\n if (existingForward) {\n throw new Error(\n `Forward relation name \"${forwardName}\" on table \"${type.name}\"${typeLocation} is duplicated ` +\n `between fields \"${existingForward.targetField}\" and \"${fieldName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a unique name.`,\n );\n }\n if (Object.hasOwn(type.fields, forwardName)) {\n const message =\n forwardName === fieldName\n ? `Forward relation name \"${forwardName}\" on table \"${type.name}\"${typeLocation} is the same as its own relation field \"${fieldName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a different name.`\n : `Forward relation name \"${forwardName}\" from field \"${fieldName}\" on table \"${type.name}\"${typeLocation} ` +\n `conflicts with existing field \"${forwardName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a different name.`;\n throw new Error(message);\n }\n if (Object.hasOwn(metadata.files, forwardName)) {\n throw new Error(\n `Forward relation name \"${forwardName}\" from field \"${fieldName}\" on table \"${type.name}\"${typeLocation} ` +\n `conflicts with files field \"${forwardName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a different name.`,\n );\n }\n\n const targetType = rawTypes[relationInfo.targetType];\n forwardRelationships[forwardName] = {\n name: forwardName,\n targetType: relationInfo.targetType,\n targetField: fieldName,\n sourceField: relationInfo.key,\n isArray: false,\n description: targetType?.metadata.description || \"\",\n };\n }\n\n fields[fieldName] = parsedField;\n }\n\n return {\n name: type.name,\n pluralForm,\n description: metadata.description,\n fields,\n forwardRelationships,\n backwardRelationships: createRecord<ParsedRelationship>(),\n settings: metadata.settings ?? {},\n permissions: parsePermissions(metadata.permissions),\n indexes: metadata.indexes,\n files: metadata.files,\n ...(metadata.typeHook && {\n typeHookExpr: {\n ...(typeof metadata.typeHook.create === \"function\" && {\n create: convertTypeHookToExpr(metadata.typeHook.create, \"create\"),\n }),\n ...(typeof metadata.typeHook.update === \"function\" && {\n update: convertTypeHookToExpr(metadata.typeHook.update, \"update\"),\n }),\n },\n }),\n ...(typeof metadata.typeValidate === \"function\" && {\n typeValidateExpr: convertTypeValidateToExpr(metadata.typeValidate),\n }),\n };\n}\n\n/**\n * Build backward relationships between parsed tables.\n * Also validates that backward relation names are unique within each table.\n * @param types - Parsed tables\n * @param namespace - TailorDB namespace name\n * @param typeSourceInfo - Optional table source information\n */\nfunction buildBackwardRelationships(\n types: Record<string, TailorDBType>,\n namespace: string,\n typeSourceInfo?: TypeSourceInfo,\n): void {\n // Track backward name sources for duplicate detection\n // Map: targetTypeName -> backwardName -> array of source info\n const backwardNameSources: Record<\n string,\n Record<string, { sourceType: string; fieldName: string }[]>\n > = Object.create(null);\n\n // Initialize tracking for all tables\n for (const tableName of Object.keys(types)) {\n backwardNameSources[tableName] = Object.create(null) as Record<\n string,\n { sourceType: string; fieldName: string }[]\n >;\n }\n\n // Build backward relationships and track sources\n for (const [tableName, type] of Object.entries(types)) {\n for (const [otherTypeName, otherType] of Object.entries(types)) {\n for (const [fieldName, field] of Object.entries(otherType.fields)) {\n if (field.relation && field.relation.targetType === tableName) {\n let backwardName = field.relation.backwardName;\n\n if (!backwardName) {\n const lowerName = inflection.camelize(otherTypeName, true);\n backwardName = field.relation.unique\n ? inflection.singularize(lowerName)\n : inflection.pluralize(lowerName);\n }\n\n // Track the source of this backward name\n const tableBackwardNames = backwardNameSources[tableName];\n if (tableBackwardNames === undefined) {\n throw new Error(`backward name sources not initialized for table: ${tableName}`);\n }\n if (!tableBackwardNames[backwardName]) {\n tableBackwardNames[backwardName] = [];\n }\n const sources = tableBackwardNames[backwardName];\n if (sources === undefined) {\n throw new Error(`backward name sources entry not initialized for: ${backwardName}`);\n }\n sources.push({\n sourceType: otherTypeName,\n fieldName,\n });\n\n type.backwardRelationships[backwardName] = {\n name: backwardName,\n targetType: otherTypeName,\n targetField: fieldName,\n sourceField: field.relation.key,\n isArray: !field.relation.unique,\n description: otherType.description || \"\",\n };\n }\n }\n }\n }\n\n // Check for duplicates and collect errors\n const errors: string[] = [];\n\n for (const [targetTypeName, backwardNames] of Object.entries(backwardNameSources)) {\n const targetType = types[targetTypeName];\n if (targetType === undefined) {\n throw new Error(`type not found: ${targetTypeName}`);\n }\n const targetTypeSourceInfo = getTypeSourceInfo(typeSourceInfo, targetTypeName);\n const targetLocation = formatTypeSourceLocation(targetTypeSourceInfo);\n\n for (const [backwardName, sources] of Object.entries(backwardNames)) {\n // Check for duplicate backward relation names\n if (sources.length > 1) {\n const sourceList = sources\n .map((s) => {\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, s.sourceType);\n const location = formatTypeSourceLocation(sourceInfo);\n return `${s.sourceType}.${s.fieldName}${location}`;\n })\n .join(\", \");\n errors.push(\n `Backward relation name \"${backwardName}\" on table \"${targetTypeName}\" is duplicated from: ${sourceList}. ` +\n `Use the \"backward\" option in .relation() to specify unique names.`,\n );\n }\n\n // Check for conflict with existing fields\n if (Object.hasOwn(targetType.fields, backwardName)) {\n const source = sources[0];\n if (source === undefined) {\n throw new Error(`no source found for backward name: ${backwardName}`);\n }\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, source.sourceType);\n const sourceLocation = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Backward relation name \"${backwardName}\" from ${source.sourceType}.${source.fieldName}${sourceLocation} ` +\n `conflicts with existing field \"${backwardName}\" on table \"${targetTypeName}\"${targetLocation}. ` +\n `Use the \"backward\" option in .relation() to specify a different name.`,\n );\n }\n\n // Check for conflict with files fields\n if (targetType.files && Object.hasOwn(targetType.files, backwardName)) {\n const source = sources[0];\n if (source === undefined) {\n throw new Error(`no source found for backward name: ${backwardName}`);\n }\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, source.sourceType);\n const sourceLocation = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Backward relation name \"${backwardName}\" from ${source.sourceType}.${source.fieldName}${sourceLocation} ` +\n `conflicts with files field \"${backwardName}\" on table \"${targetTypeName}\"${targetLocation}. ` +\n `Use the \"backward\" option in .relation() to specify a different name.`,\n );\n }\n\n if (Object.hasOwn(targetType.forwardRelationships, backwardName)) {\n const source = sources[0];\n if (source === undefined) {\n throw new Error(`no source found for backward name: ${backwardName}`);\n }\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, source.sourceType);\n const sourceLocation = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Relation name \"${backwardName}\" on table \"${targetTypeName}\"${targetLocation} is used by both ` +\n `a forward relationship and a backward relationship from ${source.sourceType}.${source.fieldName}${sourceLocation}. ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) or the \"backward\" option in .relation() to specify unique names.`,\n );\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(\n `Backward relation name conflicts detected in TailorDB service \"${namespace}\".\\n` +\n `${errors.map((e) => ` - ${e}`).join(\"\\n\")}`,\n );\n }\n}\n\n/**\n * Validate GraphQL query field name uniqueness.\n * Checks for:\n * 1. Each table's singular query name != plural query name\n * 2. No duplicate query names across all tables\n * @param types - Parsed tables\n * @param namespace - TailorDB namespace name\n * @param typeSourceInfo - Optional table source information\n */\nfunction validatePluralFormUniqueness(\n types: Record<string, TailorDBType>,\n namespace: string,\n typeSourceInfo?: TypeSourceInfo,\n): void {\n const errors: string[] = [];\n\n // Check 1: Each table's singular and plural query names must be different\n for (const [, parsedType] of Object.entries(types)) {\n const singularQuery = inflection.camelize(parsedType.name, true);\n const pluralQuery = inflection.camelize(parsedType.pluralForm, true);\n\n if (singularQuery === pluralQuery) {\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, parsedType.name);\n const location = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Table \"${parsedType.name}\"${location} has identical singular and plural query names \"${singularQuery}\". ` +\n `Use db.table([\"${parsedType.name}\", \"UniquePluralForm\"], {...}) to set a unique pluralForm.`,\n );\n }\n }\n\n // Check 2: All query names must be unique across tables\n const queryNameToSource = new Map<string, { tableName: string; kind: string }[]>();\n\n for (const parsedType of Object.values(types)) {\n const singularQuery = inflection.camelize(parsedType.name, true);\n const pluralQuery = inflection.camelize(parsedType.pluralForm, true);\n\n const singularSources = queryNameToSource.get(singularQuery) ?? [];\n singularSources.push({\n tableName: parsedType.name,\n kind: \"singular\",\n });\n queryNameToSource.set(singularQuery, singularSources);\n\n if (singularQuery !== pluralQuery) {\n const pluralSources = queryNameToSource.get(pluralQuery) ?? [];\n pluralSources.push({\n tableName: parsedType.name,\n kind: \"plural\",\n });\n queryNameToSource.set(pluralQuery, pluralSources);\n }\n }\n\n const duplicates = [...queryNameToSource].filter(([, sources]) => sources.length > 1);\n\n for (const [queryName, sources] of duplicates) {\n const sourceList = sources\n .map((s) => {\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, s.tableName);\n const location = formatTypeSourceLocation(sourceInfo);\n return `\"${s.tableName}\"${location} (${s.kind})`;\n })\n .join(\", \");\n errors.push(`GraphQL query field \"${queryName}\" conflicts between: ${sourceList}`);\n }\n\n if (errors.length > 0) {\n throw new Error(\n `GraphQL field name conflicts detected in TailorDB service \"${namespace}\".\\n` +\n `${errors.map((e) => ` - ${e}`).join(\"\\n\")}`,\n );\n }\n}\n\nfunction getTypeSourceInfo(\n typeSourceInfo: TypeSourceInfo | undefined,\n tableName: string,\n): TypeSourceInfo[string] | undefined {\n return typeSourceInfo && Object.hasOwn(typeSourceInfo, tableName)\n ? typeSourceInfo[tableName]\n : undefined;\n}\n\nfunction formatTypeSourceLocation(sourceInfo: TypeSourceInfo[string] | undefined): string {\n if (!sourceInfo) {\n return \"\";\n }\n return isPluginGeneratedTable(sourceInfo)\n ? ` (plugin: ${sourceInfo.pluginId})`\n : ` (${sourceInfo.filePath})`;\n}\n\nfunction createRecord<T>(): Record<string, T> {\n return Object.create(null) as Record<string, T>;\n}\n","import { parseSync } from \"oxc-parser\";\nimport { ES_BUILTINS } from \"#/utils/es-builtins\";\nimport type { BindingPattern, Node, ParamPattern } from \"@oxc-project/types\";\n\n/** Fields that contain TypeScript type annotations (not runtime references). */\nexport const TS_TYPE_FIELDS = new Set([\n \"typeAnnotation\",\n \"typeParameters\",\n \"returnType\",\n \"superTypeArguments\",\n \"typeArguments\",\n]);\n\n/**\n * Recursively extract binding names from a destructuring pattern node.\n * @param pattern - The binding pattern AST node.\n * @param bindings - Set to collect binding names into.\n */\nfunction collectBindingsFromPattern(pattern: BindingPattern, bindings: Set<string>): void {\n switch (pattern.type) {\n case \"Identifier\":\n bindings.add(pattern.name);\n break;\n case \"ObjectPattern\":\n for (const prop of pattern.properties) {\n if (prop.type === \"RestElement\") {\n collectBindingsFromPattern(prop.argument, bindings);\n } else {\n collectBindingsFromPattern(prop.value, bindings);\n }\n }\n break;\n case \"ArrayPattern\":\n for (const elem of pattern.elements) {\n if (elem) {\n if (elem.type === \"RestElement\") {\n collectBindingsFromPattern(elem.argument, bindings);\n } else {\n collectBindingsFromPattern(elem, bindings);\n }\n }\n }\n break;\n case \"AssignmentPattern\":\n collectBindingsFromPattern(pattern.left, bindings);\n break;\n }\n}\n\nfunction isBindingPattern(param: ParamPattern): param is BindingPattern {\n return param.type !== \"TSParameterProperty\";\n}\n\n/**\n * A function-scope boundary (function declaration/expression, arrow\n * function, or the module root). Declarations resolve within the scope they\n * are collected into; references are checked against this chain at the end,\n * once every scope's bindings have been fully collected. Block-level\n * scoping (`let`/`const`/`catch` shadowing within an `if`/`for`/`{}`) is not\n * modeled — such bindings are attached to their nearest enclosing function\n * scope, which is safe for detecting a forbidden global reachable from\n * outside the block but does not detect one shadowed only within it.\n */\ninterface Scope {\n bindings: Set<string>;\n parent: Scope | null;\n}\n\nfunction isBoundInScope(scope: Scope, name: string): boolean {\n for (let s: Scope | null = scope; s; s = s.parent) {\n if (s.bindings.has(name)) return true;\n }\n return false;\n}\n\nconst NEGATIVE_EQUALITY_OPERATORS = new Set([\"!==\", \"!=\"]);\nconst POSITIVE_EQUALITY_OPERATORS = new Set([\"===\", \"==\"]);\n\n/**\n * Read the static string value of a string literal or a template literal with\n * no interpolated expressions (e.g. `` `object` ``, which minifiers use in\n * place of `\"object\"` — both are the same string at runtime).\n * @param node - Candidate literal AST node.\n * @returns The literal's string value, or undefined if `node` isn't one.\n */\nfunction staticStringValue(node: Node): string | undefined {\n if (node.type === \"Literal\" && typeof node.value === \"string\") return node.value;\n if (\n node.type === \"TemplateLiteral\" &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0]?.value.cooked ?? undefined;\n }\n return undefined;\n}\n\n/**\n * If `expr` is a `typeof x === \"...\"` / `typeof x !== \"...\"` comparison that\n * is only true while `x` is declared, return `x`'s name. `typeof` never\n * throws on an undeclared identifier, so `typeof x !== \"undefined\" && x` (and\n * `typeof x === \"<anything but undefined>\" && x`) cannot actually reference\n * `x` when it is undeclared — this is the cross-environment global-detection\n * idiom used by es-toolkit, lodash, core-js, etc. The opposite direction —\n * `typeof x === \"undefined\" && x` or `typeof x !== \"<anything but\n * undefined>\" && x` — is true precisely when `x` is NOT safely usable (or\n * says nothing about it), so it must not be treated as a guard. Loose\n * equality (`==`/`!=`) is included because minifiers rewrite `===`/`!==`\n * against a `typeof` result to the loose form (the result is always a\n * string, so the two are equivalent there).\n * @param expr - Candidate comparison AST node.\n * @returns The guarded identifier's name, or undefined if `expr` doesn't guard one.\n */\nfunction typeofGuardTarget(expr: Node): string | undefined {\n if (expr.type !== \"BinaryExpression\") return undefined;\n const { left, right, operator } = expr;\n const [typeofSide, literalSide] =\n left.type === \"UnaryExpression\" &&\n left.operator === \"typeof\" &&\n left.argument.type === \"Identifier\"\n ? [left, right]\n : right.type === \"UnaryExpression\" &&\n right.operator === \"typeof\" &&\n right.argument.type === \"Identifier\"\n ? [right, left]\n : [undefined, undefined];\n if (!typeofSide) return undefined;\n const literalValue = staticStringValue(literalSide);\n if (literalValue === undefined) return undefined;\n const comparesToUndefined = literalValue === \"undefined\";\n const isSafe =\n (NEGATIVE_EQUALITY_OPERATORS.has(operator) && comparesToUndefined) ||\n (POSITIVE_EQUALITY_OPERATORS.has(operator) && !comparesToUndefined);\n if (!isSafe) return undefined;\n return (typeofSide.argument as { name: string }).name;\n}\n\n/**\n * Check whether `node` is `guardedName` itself, or a member-expression chain\n * rooted at it (`x.y`, `x.y[z]`), as in `typeof x !== \"undefined\" && x.y`.\n * Computed property expressions along the chain are still walked for their\n * own free variables (e.g. the `z` in `x.y[z]`) — only the guarded root\n * identifier is treated as safe.\n * @param node - Candidate right-hand side of a `typeof`-guarded `&&`.\n * @param guardedName - The identifier name the `typeof` check guards.\n * @param walk - The AST walker, used to visit computed property expressions.\n * @returns Whether `node` is entirely covered by the guard.\n */\nfunction walkGuardedChain(\n node: Node,\n guardedName: string,\n walk: (n: Node | null | undefined) => void,\n): boolean {\n if (node.type === \"Identifier\") {\n return node.name === guardedName;\n }\n if (node.type === \"MemberExpression\") {\n if (!walkGuardedChain(node.object, guardedName, walk)) return false;\n if (node.computed) walk(node.property);\n return true;\n }\n return false;\n}\n\n/**\n * Parse a code string with oxc-parser and return identifiers that are referenced\n * but never bound anywhere in the snippet (free variables), excluding ES builtins.\n * @param code - Valid JavaScript code to analyze.\n * @returns Set of undefined variable names.\n */\nexport function findUndefinedReferences(code: string): Set<string> {\n const { program, errors } = parseSync(\"_.js\", code);\n if (errors.length > 0) {\n const details = errors.map((error) => ` - ${error.message}`).join(\"\\n\");\n throw new Error(`Failed to parse code for free-variable analysis.\\nParse errors:\\n${details}`);\n }\n const references: { name: string; scope: Scope }[] = [];\n const rootScope: Scope = { bindings: new Set(), parent: null };\n let currentScope: Scope = rootScope;\n\n const walk = (node: Node | null | undefined): void => {\n if (!node) return;\n\n switch (node.type) {\n case \"VariableDeclarator\":\n collectBindingsFromPattern(node.id, currentScope.bindings);\n walk(node.init);\n return;\n\n case \"ImportDeclaration\":\n for (const specifier of node.specifiers) {\n currentScope.bindings.add(specifier.local.name);\n }\n return;\n\n case \"FunctionDeclaration\":\n case \"FunctionExpression\": {\n if (node.type === \"FunctionDeclaration\" && node.id) {\n currentScope.bindings.add(node.id.name);\n }\n const functionScope: Scope = { bindings: new Set(), parent: currentScope };\n if (node.type === \"FunctionExpression\" && node.id) {\n functionScope.bindings.add(node.id.name);\n }\n for (const param of node.params) {\n if (isBindingPattern(param)) {\n collectBindingsFromPattern(param, functionScope.bindings);\n }\n }\n const outerScope = currentScope;\n currentScope = functionScope;\n for (const param of node.params) {\n if (isBindingPattern(param)) walk(param);\n }\n walk(node.body);\n currentScope = outerScope;\n return;\n }\n\n case \"ArrowFunctionExpression\": {\n const functionScope: Scope = { bindings: new Set(), parent: currentScope };\n for (const param of node.params) {\n if (isBindingPattern(param)) {\n collectBindingsFromPattern(param, functionScope.bindings);\n }\n }\n const outerScope = currentScope;\n currentScope = functionScope;\n for (const param of node.params) {\n if (isBindingPattern(param)) walk(param);\n }\n walk(node.body);\n currentScope = outerScope;\n return;\n }\n\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n if (node.id) currentScope.bindings.add(node.id.name);\n walk(node.superClass);\n walk(node.body);\n return;\n\n case \"CatchClause\":\n if (node.param) collectBindingsFromPattern(node.param, currentScope.bindings);\n walk(node.body);\n return;\n\n case \"MemberExpression\":\n walk(node.object);\n if (node.computed) walk(node.property);\n return;\n\n case \"UnaryExpression\":\n if (node.operator === \"typeof\" && node.argument.type === \"Identifier\") {\n return;\n }\n walk(node.argument);\n return;\n\n case \"LogicalExpression\": {\n const guardedName = node.operator === \"&&\" ? typeofGuardTarget(node.left) : undefined;\n walk(node.left);\n if (guardedName && walkGuardedChain(node.right, guardedName, walk)) {\n return;\n }\n walk(node.right);\n return;\n }\n\n case \"Property\":\n if (node.computed) walk(node.key);\n walk(node.value);\n return;\n\n case \"MethodDefinition\":\n case \"TSAbstractMethodDefinition\":\n case \"PropertyDefinition\":\n case \"TSAbstractPropertyDefinition\":\n case \"AccessorProperty\":\n case \"TSAbstractAccessorProperty\":\n for (const decorator of node.decorators) walk(decorator.expression);\n if (node.computed) walk(node.key);\n walk(node.value);\n return;\n\n case \"LabeledStatement\":\n walk(node.body);\n return;\n\n case \"Identifier\":\n references.push({ name: node.name, scope: currentScope });\n return;\n\n default:\n break;\n }\n\n // Generic child walk for all other node types, skipping TS type-annotation fields\n const rec = node as unknown as Record<string, unknown>;\n for (const [key, value] of Object.entries(rec)) {\n if (key === \"type\" || TS_TYPE_FIELDS.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) walk(item as Node);\n } else if (value && typeof value === \"object\" && \"type\" in value) {\n walk(value as Node);\n }\n }\n };\n\n walk(program);\n\n // Free variables = references not bound in their own or any enclosing scope, minus builtins\n const freeVars = new Set<string>();\n for (const { name, scope } of references) {\n if (!isBoundInScope(scope, name) && !ES_BUILTINS.has(name)) {\n freeVars.add(name);\n }\n }\n return freeVars;\n}\n","import { readFileSync } from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport { resolve } from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { findUndefinedReferences, TS_TYPE_FIELDS } from \"#/cli/shared/free-variables\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { createTsconfigPathsPlugin } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport { stringifyFunction } from \"#/parser/service/tailordb/field\";\nimport { buildHookCallArgs } from \"#/parser/service/tailordb/hook-args-object\";\nimport {\n getPrecompiledScriptExpr,\n setPrecompiledScriptExpr,\n} from \"#/parser/service/tailordb/hooks-validate-precompiled-expr\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { assertParsableExpression } from \"#/utils/script-expr\";\nimport type { ScriptExprKind } from \"#/parser/service/tailordb/types\";\nimport type { TailorDBTypeRaw as TailorDBTypeSchemaOutput } from \"#/types/tailordb.generated\";\n\ntype ScriptFunction = (...args: unknown[]) => unknown;\n\ntype ScriptTarget = {\n fn: ScriptFunction;\n kind: ScriptExprKind;\n};\n\n/** Binding found in the source file: either an import or a top-level declaration */\nexport type SourceBinding = {\n name: string;\n /** The original source text of the import/declaration statement */\n sourceText: string;\n kind: \"import\" | \"declaration\";\n};\n\nfunction toScriptFunction(value: unknown, kind: ScriptExprKind): ScriptFunction | undefined {\n if (typeof value !== \"function\") return undefined;\n // Already pinned (e.g. a built-in SDK hook, see `db.fields.timestamps()`) - bundling\n // it again would derive a new expr from this build's `Function.prototype.toString()`\n // output and overwrite the pin.\n if (getPrecompiledScriptExpr(value as ScriptFunction, kind)) return undefined;\n return value as unknown as ScriptFunction;\n}\n\nfunction collectScriptTargets(type: TailorDBTypeSchemaOutput): ScriptTarget[] {\n const targets: ScriptTarget[] = [];\n\n const collectFieldTargets = (field: TailorDBTypeSchemaOutput[\"fields\"][string]) => {\n const metadata = field.metadata;\n\n const createHook = toScriptFunction(metadata.hooks?.create, \"hooks.create\");\n if (createHook) {\n targets.push({ fn: createHook, kind: \"hooks.create\" });\n }\n const updateHook = toScriptFunction(metadata.hooks?.update, \"hooks.update\");\n if (updateHook) {\n targets.push({ fn: updateHook, kind: \"hooks.update\" });\n }\n\n for (const validateInput of metadata.validate ?? []) {\n const validateFn = toScriptFunction(validateInput, \"validate\");\n if (validateFn) targets.push({ fn: validateFn, kind: \"validate\" });\n }\n\n if (field.type === \"nested\" && field.fields) {\n for (const nestedField of Object.values(field.fields as TailorDBTypeSchemaOutput[\"fields\"])) {\n collectFieldTargets(nestedField);\n }\n }\n };\n\n for (const field of Object.values(type.fields)) {\n collectFieldTargets(field);\n }\n\n if (type.metadata.typeHook) {\n for (const op of [\"create\", \"update\"] as const) {\n const kind = `typeHook.${op}` as const;\n const fn = toScriptFunction(type.metadata.typeHook[op], kind);\n if (fn) {\n targets.push({ fn, kind });\n }\n }\n }\n\n const typeValidateFn = toScriptFunction(type.metadata.typeValidate, \"typeValidate\");\n if (typeValidateFn) {\n targets.push({ fn: typeValidateFn, kind: \"typeValidate\" });\n }\n\n return targets;\n}\n\n/**\n * Collect all Identifier names from a TypeScript/JavaScript code string using oxc-parser.\n * @param code - Code string to analyze.\n * @returns Set of identifier names found in the code.\n */\nfunction collectIdentifierNames(code: string): Set<string> {\n const { program } = parseSync(\"_.ts\", code);\n const names = new Set<string>();\n const walk = (node: unknown): void => {\n if (!node || typeof node !== \"object\") return;\n const record = node as Record<string, unknown>;\n if (record.type === \"Identifier\" && typeof record.name === \"string\") {\n names.add(record.name);\n }\n for (const [key, value] of Object.entries(record)) {\n // Skip non-computed MemberExpression property (e.g. `length` in `value.length`)\n // but keep computed properties (e.g. `foo` in `obj[foo]`) as they are real references\n if (key === \"property\" && record.type === \"MemberExpression\" && !record.computed) continue;\n // Skip non-computed Property keys (e.g. `format` in `{ format: \"x\" }` is not a reference)\n if (key === \"key\" && record.type === \"Property\" && !record.computed) continue;\n // Skip TypeScript type annotation fields (not runtime references)\n if (TS_TYPE_FIELDS.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) walk(item);\n } else if (value && typeof value === \"object\" && \"type\" in value) {\n walk(value);\n }\n }\n };\n walk(program);\n return names;\n}\n\n/**\n * Collect top-level bindings (imports and declarations) from a TypeScript source file.\n * @param sourceFilePath - Absolute path to the source file.\n * @returns Map of binding name to SourceBinding.\n */\nexport function collectSourceBindings(sourceFilePath: string): Map<string, SourceBinding> {\n const source = readFileSync(sourceFilePath, \"utf-8\");\n const { program } = parseSync(sourceFilePath, source);\n const bindings = new Map<string, SourceBinding>();\n\n for (const stmt of program.body) {\n if (stmt.type === \"ImportDeclaration\") {\n const importDecl = stmt;\n const text = source.slice(importDecl.start, importDecl.end);\n for (const spec of importDecl.specifiers) {\n bindings.set(spec.local.name, {\n name: spec.local.name,\n sourceText: text,\n kind: \"import\",\n });\n }\n } else if (stmt.type === \"VariableDeclaration\") {\n const varDecl = stmt;\n const text = source.slice(varDecl.start, varDecl.end);\n for (const decl of varDecl.declarations) {\n if (decl.id.type === \"Identifier\") {\n bindings.set(decl.id.name, { name: decl.id.name, sourceText: text, kind: \"declaration\" });\n }\n }\n } else if (stmt.type === \"FunctionDeclaration\") {\n const funcDecl = stmt;\n if (funcDecl.id) {\n const text = source.slice(funcDecl.start, funcDecl.end);\n bindings.set(funcDecl.id.name, {\n name: funcDecl.id.name,\n sourceText: text,\n kind: \"declaration\",\n });\n }\n } else if (stmt.type === \"ExportNamedDeclaration\") {\n const exportDecl = stmt;\n const innerDecl = exportDecl.declaration;\n if (!innerDecl) continue;\n\n if (innerDecl.type === \"VariableDeclaration\") {\n const varDecl = innerDecl;\n // Slice only the inner declaration (without export keyword) so it is valid standalone\n const text = source.slice(varDecl.start, varDecl.end);\n for (const decl of varDecl.declarations) {\n if (decl.id.type === \"Identifier\") {\n bindings.set(decl.id.name, {\n name: decl.id.name,\n sourceText: text,\n kind: \"declaration\",\n });\n }\n }\n } else if (innerDecl.type === \"FunctionDeclaration\") {\n const funcDecl = innerDecl;\n if (funcDecl.id) {\n const text = source.slice(funcDecl.start, funcDecl.end);\n bindings.set(funcDecl.id.name, {\n name: funcDecl.id.name,\n sourceText: text,\n kind: \"declaration\",\n });\n }\n }\n }\n }\n\n return bindings;\n}\n\n/**\n * Resolve all bindings needed by a function, recursively including\n * dependencies of top-level declarations.\n * @param freeVars - Set of free variable names extracted from the function.\n * @param sourceBindings - Available bindings from the source file.\n * @returns Object with needed import statements and declaration texts.\n */\nexport function resolveNeededBindings(\n freeVars: Set<string>,\n sourceBindings: Map<string, SourceBinding>,\n): { imports: string[]; declarations: string[]; unresolved: string[] } {\n const neededImports = new Set<string>();\n const neededDeclarations = new Set<string>();\n const unresolved: string[] = [];\n const resolved = new Set<string>();\n\n const resolveVars = (vars: Set<string>): void => {\n for (const varName of vars) {\n if (resolved.has(varName)) continue;\n resolved.add(varName);\n\n const binding = sourceBindings.get(varName);\n if (!binding) {\n unresolved.push(varName);\n continue;\n }\n\n if (binding.kind === \"import\") {\n neededImports.add(binding.sourceText);\n } else {\n // Parse the declaration with oxc-parser (handles TypeScript) and collect\n // all Identifier names, then resolve those that match other source bindings.\n const identifiers = collectIdentifierNames(binding.sourceText);\n const referencedVars = new Set<string>();\n for (const id of identifiers) {\n if (id !== varName && sourceBindings.has(id)) {\n referencedVars.add(id);\n }\n }\n resolveVars(referencedVars);\n neededDeclarations.add(binding.sourceText);\n }\n }\n };\n\n resolveVars(freeVars);\n\n return {\n imports: [...neededImports],\n declarations: [...neededDeclarations],\n unresolved,\n };\n}\n\nfunction buildPrecompiledExpr(bundleCode: string, argsObject: string): string {\n return (\n \"(() => {\\n\" +\n \" const module = { exports: {} };\\n\" +\n \" const exports = module.exports;\\n\" +\n `${bundleCode}\\n` +\n ` return module.exports.main(${argsObject});\\n` +\n \"})()\"\n );\n}\n\n/**\n * Build entry file content from already-resolved imports and declarations.\n * @param imports - Import statement texts.\n * @param declarations - Declaration statement texts.\n * @param fnSource - The function source code.\n * @param sourceFilePath - Path to the source file for resolving relative imports.\n * @param multiArg - Whether the function accepts multiple arguments (spread via `...args`).\n * @returns Entry file content string.\n */\nexport function buildMinimalEntryFromResolved(\n imports: string[],\n declarations: string[],\n fnSource: string,\n sourceFilePath: string,\n multiArg = false,\n): string {\n const sourceDir = resolve(sourceFilePath, \"..\").replace(/\\\\/g, \"/\");\n\n // Rewrite relative import paths to absolute paths so rolldown can resolve them\n const resolvedImports = imports.map((imp) =>\n imp.replace(\n /from\\s+[\"'](\\.[^\"']+)[\"']/g,\n (_match, relPath: string) => `from \"${resolve(sourceDir, relPath).replace(/\\\\/g, \"/\")}\"`,\n ),\n );\n\n const lines = [\n ...resolvedImports,\n ...declarations,\n multiArg\n ? `export function main(...args) { return (${fnSource})(...args); }`\n : `export function main(input) { return (${fnSource})(input); }`,\n ];\n return lines.join(\"\\n\");\n}\n\nasync function bundleScriptTarget(args: {\n fn: ScriptFunction;\n kind: ScriptExprKind;\n sourceFilePath: string;\n sourceBindings: Map<string, SourceBinding>;\n tableName: string;\n targetIndex: number;\n tsconfig: string | undefined;\n}): Promise<string> {\n const { fn, kind, sourceFilePath, sourceBindings, tableName, targetIndex, tsconfig } = args;\n const context = `${kind} in ${sourceFilePath}`;\n const fnSource = stringifyFunction(fn);\n if ((kind === \"typeValidate\" || kind === \"validate\") && fn.constructor.name === \"AsyncFunction\") {\n throw new Error(\n `${context} must be synchronous — the generated validator runs synchronously, ` +\n \"so issues reported after an await are silently lost. Remove the async keyword.\",\n );\n }\n const inlineExpr = assertParsableExpression(`(${fnSource})(${buildHookCallArgs(kind)})`, context);\n\n // Check if the function has free variables that need bundling\n const freeVars = findUndefinedReferences(`const __fn = ${fnSource};`);\n if (freeVars.size === 0) {\n // No external dependencies - use inline expression without bundling\n return inlineExpr;\n }\n\n const { imports, declarations, unresolved } = resolveNeededBindings(freeVars, sourceBindings);\n if (unresolved.length > 0) {\n throw new Error(\n `${context} captures unresolvable variables (${unresolved.join(\", \")}). ` +\n \"Hooks and validators must not reference variables that cannot be resolved from the source file.\\n\" +\n ` ${kind}: ${fnSource}`,\n );\n }\n\n const entryContent = buildMinimalEntryFromResolved(\n imports,\n declarations,\n fnSource,\n sourceFilePath,\n kind === \"typeValidate\",\n );\n const entry = createVirtualEntry(\n `tailordb-script:${tableName}:${targetIndex}`,\n entryContent,\n \"ts\",\n sourceFilePath,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const buildResult = await rolldown.build({\n plugins: [\n entry.plugin,\n createTsconfigPathsPlugin({ virtualEntrySourceFile: sourceFilePath }),\n platformBundleDefinePlugin,\n ],\n input: entry.input,\n write: false,\n output: {\n format: \"cjs\",\n sourcemap: false,\n minify: true,\n codeSplitting: false,\n },\n tsconfig,\n treeshake: {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n },\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = buildResult.output[0].code;\n return assertParsableExpression(\n buildPrecompiledExpr(bundledCode, buildHookCallArgs(kind)),\n context,\n );\n}\n\n/**\n * Precompile TailorDB hooks/validators into self-contained script expressions using rolldown.\n * Uses oxc-parser AST walking to extract free variables from functions, then builds\n * minimal entry points containing only the needed imports and declarations.\n * @param type - TailorDB table schema output.\n * @param sourceFilePath - Source file where the table is defined.\n * @param tsconfig - Resolved tsconfig path, or undefined if not found.\n */\nexport async function precompileTailorDBTypeScripts(\n type: TailorDBTypeSchemaOutput,\n sourceFilePath: string,\n tsconfig: string | undefined,\n): Promise<void> {\n const targets = collectScriptTargets(type);\n if (targets.length === 0) return;\n\n // Collect source bindings once for all targets in this file\n const sourceBindings = collectSourceBindings(sourceFilePath);\n\n const results = await Promise.allSettled(\n targets.map((target, index) =>\n bundleScriptTarget({\n fn: target.fn,\n kind: target.kind,\n sourceFilePath,\n sourceBindings,\n tableName: type.name,\n targetIndex: index,\n tsconfig,\n }),\n ),\n );\n const firstError = results.find((r): r is PromiseRejectedResult => r.status === \"rejected\");\n if (firstError) {\n throw firstError.reason;\n }\n for (const [index, result] of results.entries()) {\n if (result.status === \"fulfilled\") {\n const target = assertDefined(targets[index], `bundle target at index ${index} missing`);\n setPrecompiledScriptExpr(target.fn, target.kind, result.value);\n }\n }\n}\n","import { fetchAll, isNotFoundError } from \"#/cli/shared/client\";\nimport { isPluginGeneratedTable } from \"#/parser/service/tailordb/type-source\";\nimport type { TypeSourceInfo, TypeSourceInfoEntry } from \"#/parser/service/tailordb/types\";\n\ntype LocalTailorDBService = {\n readonly namespace: string;\n readonly types: Readonly<Record<string, unknown>>;\n readonly typeSourceInfo: Readonly<TypeSourceInfo>;\n};\n\ntype TailorDBTypeNameSourceKind = \"local\" | \"external\";\n\nexport type TailorDBTypeNameSource = {\n readonly namespace: string;\n readonly tableName: string;\n readonly kind: TailorDBTypeNameSourceKind;\n readonly detail?: string;\n};\n\ntype ListTailorDBTypesArgs = {\n workspaceId: string;\n namespaceName: string;\n pageToken?: string;\n pageSize?: number;\n};\n\ntype ListTailorDBTypesResult = {\n tailordbTypes: Array<{ name: string }>;\n nextPageToken?: string;\n};\n\ntype ListTailorDBTypesClient = {\n listTailorDBTypes(args: ListTailorDBTypesArgs): Promise<ListTailorDBTypesResult>;\n};\n\nexport interface CollectLocalTailorDBTypeNameSourcesArgs {\n /** Loaded local TailorDB services. */\n tailorDBServices: ReadonlyArray<LocalTailorDBService>;\n}\n\nexport interface FetchExternalTailorDBTypeNameSourcesArgs {\n /** Client used to read TailorDB metadata. */\n client: ListTailorDBTypesClient;\n /** Workspace that owns the configured namespaces. */\n workspaceId: string;\n /** External TailorDB namespaces declared in the application config. */\n externalTailorDBNamespaces: ReadonlyArray<string>;\n}\n\ninterface AssertUniqueTailorDBTypeNamesArgs {\n /** Table-name sources to validate. */\n sources: ReadonlyArray<TailorDBTypeNameSource>;\n}\n\nexport interface AssertUniqueTailorDBTypeNamesWithExternalArgs\n extends CollectLocalTailorDBTypeNameSourcesArgs, FetchExternalTailorDBTypeNameSourcesArgs {\n /** External TailorDB services planned in the same deploy run. */\n plannedExternalTailorDBServices?: ReadonlyArray<LocalTailorDBService>;\n}\n\n/**\n * Format a TailorDB table source for validation errors.\n * @param sourceInfo - Source information captured when loading the table\n * @returns Human-readable source detail\n */\nexport function formatTailorDBTypeSourceInfo(\n sourceInfo: TypeSourceInfoEntry | undefined,\n): string | undefined {\n if (!sourceInfo) {\n return undefined;\n }\n\n if (isPluginGeneratedTable(sourceInfo)) {\n const parts = [`plugin ${sourceInfo.pluginId}`];\n if (sourceInfo.generatedTableKind) {\n parts.push(`kind ${sourceInfo.generatedTableKind}`);\n }\n if (sourceInfo.originalFilePath) {\n parts.push(`source ${sourceInfo.originalFilePath}`);\n }\n if (sourceInfo.originalExportName) {\n parts.push(`export ${sourceInfo.originalExportName}`);\n }\n return parts.join(\", \");\n }\n\n return `${sourceInfo.filePath} export ${sourceInfo.exportName}`;\n}\n\n/**\n * Collect TailorDB table-name sources from loaded local services.\n * @param args - Collection inputs\n * @returns Table-name sources for local services\n */\nfunction collectLocalTailorDBTypeNameSources(\n args: CollectLocalTailorDBTypeNameSourcesArgs,\n): TailorDBTypeNameSource[] {\n const sources: TailorDBTypeNameSource[] = [];\n\n for (const service of args.tailorDBServices) {\n for (const tableName of Object.keys(service.types)) {\n sources.push({\n namespace: service.namespace,\n tableName,\n kind: \"local\",\n detail: formatTailorDBTypeSourceInfo(service.typeSourceInfo[tableName]),\n });\n }\n }\n\n return sources;\n}\n\n/**\n * Fetch TailorDB table-name sources for external namespaces.\n * @param args - Fetch inputs\n * @returns Table-name sources for external services\n */\nexport async function fetchExternalTailorDBTypeNameSources(\n args: FetchExternalTailorDBTypeNameSourcesArgs,\n): Promise<TailorDBTypeNameSource[]> {\n const sourcesByNamespace = await Promise.all(\n args.externalTailorDBNamespaces.map(async (namespace) => {\n const sources: TailorDBTypeNameSource[] = [];\n const tailordbTypes = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { tailordbTypes, nextPageToken } = await args.client.listTailorDBTypes({\n workspaceId: args.workspaceId,\n namespaceName: namespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbTypes, nextPageToken ?? \"\"];\n } catch (error) {\n if (isNotFoundError(error)) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n\n for (const type of tailordbTypes) {\n sources.push({\n namespace,\n tableName: type.name,\n kind: \"external\",\n });\n }\n\n return sources;\n }),\n );\n\n return sourcesByNamespace.flat();\n}\n\n/**\n * Assert that TailorDB table names are unique across all supplied sources.\n * @param args - Validation inputs\n */\nfunction assertUniqueTailorDBTypeNames(args: AssertUniqueTailorDBTypeNamesArgs): void {\n const sourcesByTableName = new Map<string, TailorDBTypeNameSource[]>();\n\n for (const source of args.sources) {\n const existing = sourcesByTableName.get(source.tableName);\n if (existing) {\n existing.push(source);\n } else {\n sourcesByTableName.set(source.tableName, [source]);\n }\n }\n\n const errors: string[] = [];\n for (const [tableName, sources] of sourcesByTableName) {\n if (sources.length <= 1) {\n continue;\n }\n\n const sourceList = sources.map(formatTailorDBTypeNameSource).join(\", \");\n errors.push(`Table \"${tableName}\" is defined more than once: ${sourceList}`);\n }\n\n if (errors.length > 0) {\n throw new Error(\n \"Duplicate TailorDB table names detected.\\n\" +\n `${errors.map((error) => ` - ${error}`).join(\"\\n\")}\\n` +\n \"TailorDB table names must be unique across all TailorDB namespaces in an application.\",\n );\n }\n}\n\n/**\n * Assert local TailorDB table names are unique.\n * @param args - Validation inputs\n */\nexport function assertUniqueLocalTailorDBTypeNames(\n args: CollectLocalTailorDBTypeNameSourcesArgs,\n): void {\n assertUniqueTailorDBTypeNames({\n sources: collectLocalTailorDBTypeNameSources(args),\n });\n}\n\n/**\n * Assert TailorDB table names are unique across local and external namespaces.\n * @param args - Validation inputs\n */\nexport async function assertUniqueTailorDBTypeNamesWithExternal(\n args: AssertUniqueTailorDBTypeNamesWithExternalArgs,\n): Promise<void> {\n const localSources = collectLocalTailorDBTypeNameSources(args);\n const plannedExternalServices = args.plannedExternalTailorDBServices ?? [];\n const plannedExternalNamespaces = new Set(\n plannedExternalServices.map((service) => service.namespace),\n );\n const plannedExternalSources = collectLocalTailorDBTypeNameSources({\n tailorDBServices: plannedExternalServices,\n }).map((source) => ({\n ...source,\n kind: \"external\" as const,\n }));\n const remoteExternalNamespaces = args.externalTailorDBNamespaces.filter(\n (namespace) => !plannedExternalNamespaces.has(namespace),\n );\n const externalSources =\n remoteExternalNamespaces.length > 0\n ? await fetchExternalTailorDBTypeNameSources({\n client: args.client,\n workspaceId: args.workspaceId,\n externalTailorDBNamespaces: remoteExternalNamespaces,\n })\n : [];\n\n assertUniqueTailorDBTypeNames({\n sources: [...localSources, ...plannedExternalSources, ...externalSources],\n });\n}\n\nfunction formatTailorDBTypeNameSource(source: TailorDBTypeNameSource): string {\n const namespaceLabel =\n source.kind === \"external\"\n ? `external namespace \"${source.namespace}\"`\n : `namespace \"${source.namespace}\"`;\n\n return source.detail ? `${namespaceLabel} (${source.detail})` : namespaceLabel;\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport {\n pickTailorDBTypeSchemaKeys,\n stripTailorDBTypeBuilderHelpers,\n} from \"#/parser/service/tailordb/builder-helpers\";\nimport { parseTypes, TailorDBTypeSchema } from \"#/parser/service/tailordb/index\";\nimport {\n findMissingPermissionConfig,\n findOmittedPermitRules,\n} from \"#/parser/service/tailordb/permission\";\nimport { getRawPluginTableName } from \"#/plugin/guards\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport { precompileTailorDBTypeScripts } from \"./hooks-validate-bundler\";\nimport { formatTailorDBTypeSourceInfo } from \"./type-name-validation\";\nimport type {\n TypeSourceInfo,\n TypeSourceInfoEntry,\n TailorDBType,\n} from \"#/parser/service/tailordb/types\";\nimport type { PluginManager } from \"#/plugin/manager\";\nimport type { PluginAttachment } from \"#/plugin/types\";\nimport type {\n TailorDBServiceConfig,\n TailorDBTypeRaw as TailorDBTypeSchemaOutput,\n} from \"#/types/tailordb.generated\";\n\nexport type TailorDBService = {\n readonly namespace: string;\n readonly config: TailorDBServiceConfig;\n readonly types: Readonly<Record<string, TailorDBType>>;\n readonly typeSourceInfo: Readonly<TypeSourceInfo>;\n readonly pluginAttachments: ReadonlyMap<string, readonly PluginAttachment[]>;\n loadTypes: () => Promise<Record<string, TailorDBType> | undefined>;\n processNamespacePlugins: () => Promise<void>;\n};\n\n/**\n * Parameters for creating a TailorDBService\n */\nexport interface CreateTailorDBServiceParams {\n /** The namespace for this TailorDB service */\n namespace: string;\n /** The TailorDB service configuration */\n config: TailorDBServiceConfig;\n /** Plugin manager for processing plugins */\n pluginManager?: PluginManager;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\n/**\n * Creates a new TailorDBService instance.\n * @param params - Parameters for creating the service\n * @returns A new TailorDBService instance\n */\nexport function createTailorDBService(params: CreateTailorDBServiceParams): TailorDBService {\n const { namespace, config, pluginManager, baseDir } = params;\n type TailorDBTypesByName = Record<string, TailorDBTypeSchemaOutput>;\n const createRawTypesByName = (): TailorDBTypesByName =>\n Object.create(null) as TailorDBTypesByName;\n const rawTypes = Object.create(null) as Record<string, TailorDBTypesByName>;\n let types: Record<string, TailorDBType> = {};\n const typeSourceInfo = Object.create(null) as TypeSourceInfo;\n const pluginAttachments: Map<string, PluginAttachment[]> = new Map();\n let loadPromise: Promise<Record<string, TailorDBType> | undefined> | undefined;\n\n const registerRawType = (\n rawTypesKey: string,\n tableName: string,\n type: TailorDBTypeSchemaOutput,\n sourceInfo: TypeSourceInfoEntry,\n ): void => {\n const existingSourceInfo = Object.hasOwn(typeSourceInfo, tableName)\n ? typeSourceInfo[tableName]\n : undefined;\n if (existingSourceInfo) {\n const firstSource = formatTailorDBTypeSourceInfo(existingSourceInfo) ?? \"unknown source\";\n const secondSource = formatTailorDBTypeSourceInfo(sourceInfo) ?? \"unknown source\";\n throw new Error(\n `Duplicate TailorDB table name \"${tableName}\" detected in TailorDB service \"${namespace}\". ` +\n `First: ${firstSource}. Second: ${secondSource}. ` +\n \"TailorDB table names must be unique across all TailorDB files in a service.\",\n );\n }\n\n assertDefined(rawTypes[rawTypesKey], `raw table entry missing for key: ${rawTypesKey}`)[\n tableName\n ] = type;\n typeSourceInfo[tableName] = sourceInfo;\n };\n\n // Plugin-emitted tables are runtime values the schema has never seen, unlike\n // user tables which are parsed in loadTypeFile; validate them here so a\n // malformed table fails with the offending plugin named instead of crashing\n // (or silently passing) during permission normalization.\n const parsePluginTable = (table: unknown, origin: string): TailorDBTypeSchemaOutput => {\n const result = TailorDBTypeSchema.safeParse(pickTailorDBTypeSchemaKeys(table));\n if (!result.success) {\n const issues = result.error.issues\n .map((issue) => ` - ${issue.path.map(String).join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"\\n\");\n throw new Error(\n `TailorDB table ${origin} in TailorDB service \"${namespace}\" failed schema validation:\\n${issues}`,\n { cause: result.error },\n );\n }\n return result.data;\n };\n\n const describeGeneratedTable = (name: unknown, kind: string, pluginId: string): string => {\n const namePart = typeof name === \"string\" && name.length > 0 ? `\"${name}\" ` : \"\";\n return `${namePart}generated as \"${kind}\" by plugin \"${pluginId}\"`;\n };\n\n const doParseTypes = (): void => {\n const allTypes = createRawTypesByName();\n for (const fileTypes of Object.values(rawTypes)) {\n for (const [tableName, type] of Object.entries(fileTypes)) {\n allTypes[tableName] = type;\n }\n }\n\n types = parseTypes(allTypes, namespace, typeSourceInfo);\n };\n\n // Warn about object-format permission rules that omit `permit`. Those default\n // to \"deny\" (unlike the array shorthand, which defaults to \"allow\"), an easy\n // way to accidentally lock out access the rule was meant to grant.\n const warnOmittedPermit = (): void => {\n for (const fileTypes of Object.values(rawTypes)) {\n for (const [tableName, type] of Object.entries(fileTypes)) {\n const locations = findOmittedPermitRules(type.metadata.permissions);\n if (locations.length > 0) {\n logger.warn(\n `TailorDB table \"${tableName}\" has permission rule(s) ${locations.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 }\n }\n };\n\n // Require .permission()/.gqlPermission() to be set explicitly. TailorDB\n // fails closed for record operations without a .permission(), producing an\n // opaque \"internal error\" instead of a clear denial when only\n // .gqlPermission() is set. Catching the omission here, rather than at\n // deploy/insert time, surfaces it while the table is still local.\n const validateRequiredPermissions = (): void => {\n const errors: string[] = [];\n for (const fileTypes of Object.values(rawTypes)) {\n for (const [tableName, type] of Object.entries(fileTypes)) {\n const effectiveGqlOperations =\n type.metadata.settings?.gqlOperations ?? config.gqlOperations;\n const { missingPermission, missingGqlPermission } = findMissingPermissionConfig(\n type.metadata.permissions,\n effectiveGqlOperations,\n );\n if (!missingPermission && !missingGqlPermission) {\n continue;\n }\n const source = formatTailorDBTypeSourceInfo(typeSourceInfo[tableName]);\n const location = source ? ` (${source})` : \"\";\n if (missingPermission) {\n errors.push(\n `TailorDB table \"${tableName}\"${location} has no .permission() configured. TailorDB denies all record operations for tables without permission; call .permission(...) to grant access explicitly.`,\n );\n }\n if (missingGqlPermission) {\n errors.push(\n `TailorDB table \"${tableName}\"${location} has no .gqlPermission() configured, but GraphQL operations are enabled for it. Call .gqlPermission(...) to grant GraphQL access explicitly, or disable GraphQL exposure with .features({ gqlOperations: { create: false, update: false, delete: false, read: false } }).`,\n );\n }\n }\n }\n if (errors.length > 0) {\n throw new Error(\n `TailorDB permission configuration errors in service \"${namespace}\":\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`,\n );\n }\n };\n\n /**\n * Process plugins for a table and add generated tables to rawTypes\n * @param rawTable - The raw TailorDB table being processed\n * @param attachments - Plugin attachments for this table\n * @param sourceFilePath - The file path where the table was loaded from\n */\n const processPluginsForTable = async (\n rawTable: TailorDBTypeSchemaOutput,\n attachments: PluginAttachment[],\n sourceFilePath: string,\n ): Promise<void> => {\n if (!pluginManager) return;\n\n const { extendedTable, generatedTables, events } =\n await pluginManager.processAttachmentsForTable({\n rawTable,\n attachments,\n namespace,\n });\n\n // Validate every plugin output before registering any of it, so a failure\n // does not leave partially registered state behind.\n const extendingPluginIds = [\n ...new Set(events.filter((ev) => ev.kind === \"extended\").map((ev) => ev.pluginId)),\n ];\n const parsedExtendedTable =\n extendedTable === undefined\n ? undefined\n : parsePluginTable(\n extendedTable,\n `\"${rawTable.name}\" extended by ${extendingPluginIds.length === 1 ? \"plugin\" : \"plugins\"} ${extendingPluginIds.map((id) => `\"${id}\"`).join(\", \")}`,\n );\n const parsedGeneratedTables = generatedTables.map((generatedTable) => ({\n ...generatedTable,\n table: parsePluginTable(\n generatedTable.table,\n describeGeneratedTable(\n generatedTable.tableName,\n generatedTable.kind,\n generatedTable.pluginId,\n ),\n ),\n }));\n\n if (parsedExtendedTable) {\n assertDefined(\n rawTypes[sourceFilePath],\n `raw table entry missing for file: ${sourceFilePath}`,\n )[rawTable.name] = parsedExtendedTable;\n }\n for (const generatedTable of parsedGeneratedTables) {\n // Plugin-generated tables don't have a source file.\n // Generators that need to import these tables should generate their own type files.\n const sourceInfo: TypeSourceInfoEntry = {\n exportName: generatedTable.tableName,\n pluginId: generatedTable.pluginId,\n pluginImportPath: generatedTable.pluginImportPath,\n originalFilePath: sourceFilePath,\n originalExportName: typeSourceInfo[rawTable.name]?.exportName || rawTable.name,\n generatedTableKind: generatedTable.kind,\n pluginConfig: generatedTable.pluginConfig,\n namespace,\n };\n registerRawType(sourceFilePath, generatedTable.tableName, generatedTable.table, sourceInfo);\n }\n for (const ev of events) {\n if (ev.kind === \"extended\") {\n logger.log(\n ` Extended: ${styles.success(ev.tableName)} with ${styles.highlight(ev.fieldCount.toString())} fields by plugin ${styles.info(ev.pluginId)}`,\n );\n } else {\n logger.log(\n ` Generated: ${styles.success(ev.tableName)} by plugin ${styles.info(ev.pluginId)}`,\n );\n }\n }\n };\n\n const loadTypeFile = async (\n typeFile: string,\n tsconfig: string | undefined,\n ): Promise<TailorDBTypesByName> => {\n rawTypes[typeFile] = createRawTypesByName();\n const loadedTypes = createRawTypesByName();\n try {\n const module = await importUserModule(typeFile);\n\n for (const exportName of Object.keys(module)) {\n const exportedValue = module[exportName];\n\n const result = TailorDBTypeSchema.safeParse(stripTailorDBTypeBuilderHelpers(exportedValue));\n if (!result.success) {\n if (isSdkBranded(exportedValue, \"tailordb-type\")) {\n throw result.error;\n }\n continue;\n }\n\n const relativePath = path.relative(process.cwd(), typeFile);\n logger.log(\n `Type: ${styles.successBright(`\"${result.data.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n await precompileTailorDBTypeScripts(result.data, typeFile, tsconfig);\n loadedTypes[result.data.name] = result.data;\n registerRawType(typeFile, result.data.name, result.data, {\n filePath: typeFile,\n exportName,\n });\n\n // Process plugins if any\n const rawType = exportedValue as TailorDBTypeSchemaOutput & {\n plugins?: PluginAttachment[];\n };\n if (rawType.plugins && Array.isArray(rawType.plugins) && rawType.plugins.length > 0) {\n pluginAttachments.set(rawType.name, [...rawType.plugins]);\n logger.log(\n ` Plugin attachments: ${styles.info(rawType.plugins.map((p) => p.pluginId).join(\", \"))}`,\n );\n\n await processPluginsForTable(rawType, rawType.plugins, typeFile);\n }\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), typeFile);\n logger.error(`Failed to load table from ${styles.bold(relativePath)}`);\n logger.error(String(error));\n throw error;\n }\n return loadedTypes;\n };\n\n return {\n namespace,\n config,\n get types() {\n return types;\n },\n get typeSourceInfo() {\n return typeSourceInfo;\n },\n get pluginAttachments() {\n return pluginAttachments as ReadonlyMap<string, readonly PluginAttachment[]>;\n },\n loadTypes: async () => {\n if (!loadPromise) {\n loadPromise = (async () => {\n if (config.files.length === 0) {\n return undefined;\n }\n\n const typeFiles = [...new Set(loadFilesWithIgnores(config, baseDir))];\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n logger.newline();\n logger.log(\n `Found ${styles.highlight(typeFiles.length.toString())} table files for TailorDB service ${styles.highlight(`\"${namespace}\"`)}`,\n );\n\n if (pluginManager) {\n for (const typeFile of typeFiles) {\n await loadTypeFile(typeFile, tsconfig);\n }\n } else {\n await Promise.all(typeFiles.map((typeFile) => loadTypeFile(typeFile, tsconfig)));\n }\n doParseTypes();\n warnOmittedPermit();\n validateRequiredPermissions();\n return types;\n })();\n }\n return loadPromise;\n },\n processNamespacePlugins: async () => {\n if (!pluginManager) return;\n\n const results = await pluginManager.processNamespacePlugins(namespace);\n const pluginGeneratedKey = \"__plugin_generated__\";\n\n const successfulResults = results.map(({ pluginId, config, result }) => {\n if (!result.success) {\n logger.error(result.error);\n throw new Error(result.error);\n }\n return { pluginId, config, output: result.output };\n });\n\n // Validate every generated table before mutating rawTypes/typeSourceInfo,\n // so a failure does not leave partially registered state behind.\n const parsedGeneratedTables = successfulResults.flatMap(({ pluginId, config, output }) =>\n Object.entries(output.tables ?? {}).map(([kind, generatedTable]) => ({\n pluginId,\n config,\n kind,\n table: parsePluginTable(\n generatedTable,\n describeGeneratedTable(getRawPluginTableName(generatedTable), kind, pluginId),\n ),\n })),\n );\n\n const hasPreviousGeneratedTables = Object.hasOwn(rawTypes, pluginGeneratedKey);\n const previousGeneratedTables = rawTypes[pluginGeneratedKey];\n const previousGeneratedTableKeys = previousGeneratedTables\n ? Object.keys(previousGeneratedTables)\n : [];\n const hadPreviousGeneratedTables = previousGeneratedTableKeys.length > 0;\n if (hasPreviousGeneratedTables) {\n for (const tableName of previousGeneratedTableKeys) {\n delete typeSourceInfo[tableName];\n }\n }\n rawTypes[pluginGeneratedKey] = createRawTypesByName();\n\n for (const { pluginId, config, kind, table } of parsedGeneratedTables) {\n const sourceInfo: TypeSourceInfoEntry = {\n exportName: table.name,\n pluginId,\n pluginImportPath: pluginManager.getPluginImportPath(pluginId) ?? \"\",\n originalFilePath: \"\",\n originalExportName: \"\",\n generatedTableKind: kind,\n pluginConfig: config,\n namespace,\n };\n registerRawType(pluginGeneratedKey, table.name, table, sourceInfo);\n\n logger.log(\n ` Generated: ${styles.success(table.name)} by namespace plugin ${styles.info(pluginId)}`,\n );\n }\n\n // Re-parse tables to include namespace plugin tables\n if (parsedGeneratedTables.length > 0 || hadPreviousGeneratedTables) {\n doParseTypes();\n validateRequiredPermissions();\n }\n },\n };\n}\n","import { type TailorDBService } from \"#/cli/services/tailordb/service\";\nimport { type AuthConfigSchema } from \"#/parser/service/auth/index\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type { AuthConnectionConfig } from \"#/types/auth-connection.generated\";\nimport type { z } from \"zod\";\n\n/**\n * Auth config after `AuthConfigSchema.parse` (e.g. token lifetimes as Duration).\n */\ntype ParsedAuthConfig = z.output<typeof AuthConfigSchema>;\n\ntype UserProfile = NonNullable<ParsedAuthConfig[\"userProfile\"]> & {\n namespace: string;\n};\n\nexport type AuthService = {\n readonly config: ParsedAuthConfig;\n readonly tailorDBServices: ReadonlyArray<TailorDBService>;\n readonly externalTailorDBNamespaces: ReadonlyArray<string>;\n readonly connections: Readonly<Record<string, AuthConnectionConfig>>;\n readonly userProfile: UserProfile | undefined;\n resolveNamespaces: () => Promise<void>;\n};\n\n/**\n * Creates a new AuthService instance.\n * @param config - The auth configuration\n * @param tailorDBServices - The TailorDB services\n * @param externalTailorDBNamespaces - External TailorDB namespaces\n * @returns A new AuthService instance\n */\nexport function createAuthService(\n config: ParsedAuthConfig,\n tailorDBServices: ReadonlyArray<TailorDBService>,\n externalTailorDBNamespaces: ReadonlyArray<string>,\n): AuthService {\n const connections: Record<string, AuthConnectionConfig> = config.connections\n ? { ...config.connections }\n : {};\n\n let userProfile: UserProfile | undefined;\n\n return {\n config,\n tailorDBServices,\n externalTailorDBNamespaces,\n connections,\n get userProfile() {\n return userProfile;\n },\n resolveNamespaces: async () => {\n // No userProfile defined\n if (!config.userProfile) {\n return;\n }\n\n // 1. Explicit namespace\n if (config.userProfile.namespace) {\n userProfile = {\n ...config.userProfile,\n namespace: config.userProfile.namespace,\n };\n return;\n }\n\n const totalNamespaceCount = tailorDBServices.length + externalTailorDBNamespaces.length;\n let userProfileNamespace: string | undefined;\n\n // 2. Single TailorDB\n if (totalNamespaceCount === 1) {\n userProfileNamespace =\n tailorDBServices[0]?.namespace ??\n assertDefined(externalTailorDBNamespaces[0], \"external TailorDB namespace missing\");\n } else {\n // 3. Multiple TailorDBs\n await Promise.all(tailorDBServices.map((tailordb) => tailordb.loadTypes()));\n\n const userProfileTypeName =\n typeof config.userProfile.type === \"object\" && \"name\" in config.userProfile.type\n ? config.userProfile.type.name\n : undefined;\n\n if (userProfileTypeName) {\n for (const service of tailorDBServices) {\n const types = service.types;\n if (Object.prototype.hasOwnProperty.call(types, userProfileTypeName)) {\n userProfileNamespace = service.namespace;\n break;\n }\n }\n }\n\n if (!userProfileNamespace) {\n throw new Error(\n `userProfile type \"${config.userProfile.type.name}\" not found in any TailorDB namespace`,\n );\n }\n }\n\n userProfile = {\n ...config.userProfile,\n namespace: userProfileNamespace,\n };\n },\n };\n}\n","import * as os from \"node:os\";\nimport pLimit from \"p-limit\";\nimport { parsePositiveInt } from \"./parse-positive-int\";\n\n/**\n * Resolve the maximum number of bundle operations to run in parallel.\n *\n * Resolution order:\n * 1. `TAILOR_BUNDLE_CONCURRENCY` env var (positive integer)\n * 2. `os.cpus().length`, clamped to at least 1\n *\n * Each `rolldown.build` invocation drives its own module graph and Rust thread\n * pool, so unbounded parallelism can exhaust native memory on constrained\n * runners (e.g. ubuntu-latest GitHub Actions runners with hundreds of\n * resolvers). Capping at CPU count keeps the worst case predictable.\n * @returns Concurrency cap (always >= 1)\n */\nexport function resolveBundleConcurrency(): number {\n return parsePositiveInt(process.env.TAILOR_BUNDLE_CONCURRENCY) ?? Math.max(1, os.cpus().length);\n}\n\n/**\n * Run an async worker over each item with the bundle-concurrency cap applied.\n * Results are returned in the same order as the input items.\n *\n * On the first rejection no further queued work starts, but already-running\n * workers are awaited before that first rejection is rethrown, so a failing\n * bundle cannot leave sibling builds writing output after the caller\n * has moved on.\n * @param items - Items to process\n * @param worker - Async worker function\n * @returns Worker results in input order\n */\nexport async function withBundleConcurrency<T, R>(\n items: T[],\n worker: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = [];\n results.length = items.length;\n const limit = pLimit(resolveBundleConcurrency());\n let rejection: { reason: unknown } | undefined;\n\n await Promise.all(\n // flatMap skips sparse slots and, unlike map, emits no slot for them either.\n items.flatMap((item, index) => [\n limit(async () => {\n if (rejection) return;\n try {\n results[index] = await worker(item);\n } catch (reason) {\n rejection ??= { reason };\n }\n }),\n ]),\n );\n\n if (rejection) {\n throw rejection.reason;\n }\n return results;\n}\n","import { findUndefinedReferences } from \"#/cli/shared/free-variables\";\nimport { getForbiddenGlobalMessage, isForbiddenGlobal } from \"#/utils/node-builtins\";\nimport { CLIError } from \"./errors\";\n\n/**\n * Throw a CLIError when bundled code still references a Node-only global\n * (`process`, `Buffer`, etc.) that the Tailor Platform runtime never defines.\n * Run this against already-bundled output, not source text — bundling\n * resolves every reachable import first, so any free variable left over is\n * either a genuine runtime global or unreachable dead code the bundler failed\n * to resolve (which `bundleLog.assertAllResolved()` already catches).\n * @param code - Bundled JavaScript to scan.\n * @param context - Human-readable description of what produced `code`, used in the error message.\n */\nexport function assertNoForbiddenRuntimeGlobals(code: string, context: string): void {\n const freeVars = findUndefinedReferences(code);\n const forbidden = [...freeVars].filter(isForbiddenGlobal).toSorted();\n if (forbidden.length === 0) return;\n\n const noun = forbidden.length === 1 ? \"a global\" : \"globals\";\n throw CLIError({\n code: \"FORBIDDEN_RUNTIME_GLOBAL\",\n message: `${context} references ${noun} unavailable in the Tailor Platform runtime: ${forbidden.join(\", \")}.`,\n details: forbidden.map(getForbiddenGlobalMessage).join(\"\\n\"),\n });\n}\n","/**\n * JS expressions that shape the inputs passed to user-authored code.\n *\n * Two delivery paths:\n * - Apply config: shipped with apply and evaluated by the platform before\n * invoking user code.\n * - Bundle inline: interpolated into the generated entry module and\n * evaluated inside the bundled script at function entry.\n *\n * The principal field mapping (server → SDK) shared across services is built by\n * `makePrincipalExpr` from `@/parser/service/tailordb`; `tailorPrincipalMap`\n * (the `caller` mapping) is one of its outputs. `INVOKER_EXPR` and\n * `ACTOR_TRANSFORM_EXPR` below come from the same factory so the three stay in\n * sync.\n */\nimport { makePrincipalExpr, tailorPrincipalMap } from \"#/parser/service/tailordb/index\";\nimport type { Trigger } from \"#/types/executor.generated\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\n// ---------------------------------------------------------------------------\n// Bundle inline\n// ---------------------------------------------------------------------------\n\n/**\n * `invoker` value expression, inlined into bundler entry wrappers.\n *\n * Calls `tailor.context.getInvoker()` at function entry and maps the server\n * shape to `TailorPrincipal | null`. The payload is already in SDK type shape,\n * so no `USER_TYPE_*` normalization is needed; anonymous callers (`null`) pass\n * through as `null`.\n */\nexport const INVOKER_EXPR = makePrincipalExpr({\n source: \"tailor.context.getInvoker()\",\n normalize: false,\n fields: {\n type: { raw: \"$raw.type\" },\n id: \"$raw.id\",\n workspaceId: \"$raw.workspaceId\",\n attributes: \"$raw.attributeMap\",\n attributeList: \"$raw.attributes\",\n },\n});\n\n// ---------------------------------------------------------------------------\n// Executor\n// ---------------------------------------------------------------------------\n\n/**\n * Actor field transformation expression.\n *\n * Transforms the server's actor object to match `TailorPrincipal | null`.\n */\nconst ACTOR_TRANSFORM_EXPR = `actor: ${makePrincipalExpr({\n source: \"args.actor\",\n normalize: true,\n requireId: true,\n fields: {\n type: { raw: \"$raw?.userType\", fallback: \"$raw?.type\" },\n id: \"$raw?.userId ?? $raw?.id\",\n workspaceId: \"$raw.workspaceId\",\n attributes: \"$raw.attributeMap ?? {}\",\n attributeList: \"$raw.attributes ?? []\",\n },\n})}`;\n\n/**\n * Build the JavaScript expression that transforms server-format executor event\n * args into SDK-format args at runtime.\n *\n * The Tailor Platform server delivers event args with server-side field names.\n * The SDK exposes different field names to user code. This function produces a\n * JavaScript expression string that performs the mapping when evaluated\n * server-side.\n * @param triggerKind - The trigger kind discriminant from the parsed executor\n * @param env - Application env record to embed in the expression\n * @returns A JavaScript expression string, e.g. `({ ...args, ... })`\n */\nexport function buildExecutorArgsExpr(\n triggerKind: Trigger[\"kind\"],\n env: Record<string, string | number | boolean>,\n): string {\n const envExpr = `env: ${JSON.stringify(env)}`;\n\n switch (triggerKind) {\n case \"schedule\":\n return `({ ...args, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, ${envExpr} })`;\n\n case \"resolverExecuted\":\n return `({ ...args, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, success: !!args.succeeded, result: args.succeeded?.result.resolver, error: args.failed?.error, ${envExpr} })`;\n\n case \"incomingWebhook\":\n return `({ ...args, appNamespace: args.namespaceName, rawBody: args.raw_body, ${envExpr} })`;\n\n // Workflow events carry no namespace, and a single trigger can mix events\n // that report an outcome with events that do not, so `success` is derived\n // only when the delivered event actually has a result.\n case \"workflowExecution\":\n case \"workflowJobExecution\":\n return `({ ...args, event: args.eventType?.split(\".\").pop(), rawEvent: args.eventType, ${ACTOR_TRANSFORM_EXPR}, ...(args.succeeded ? { success: true } : args.failed ? { success: false, error: args.failed.error ?? \"\" } : {}), ${envExpr} })`;\n\n default:\n // All event triggers: inject event (short name) and rawEvent (full event type) from server-side eventType\n return `({ ...args, event: args.eventType?.split(\".\").pop(), rawEvent: args.eventType, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, ${envExpr} })`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Resolver\n// ---------------------------------------------------------------------------\n\n/**\n * Build the operationHook expression for resolver pipelines.\n *\n * Transforms server context to SDK resolver context:\n * context.args → input\n * context.pipeline → spread into result\n * user (global var) → caller (`TailorPrincipal | null`)\n * env → injected as JSON\n * @param env - Application env record to embed in the expression\n * @returns A JavaScript expression string for the operationHook\n */\nexport function buildResolverOperationHookExpr(\n env: Record<string, string | number | boolean>,\n): string {\n return `({ ...context.pipeline, input: context.args, caller: ${tailorPrincipalMap}, env: ${JSON.stringify(env)} });`;\n}\n\ntype ResolverPermissionPolicies = Extract<NonNullable<Resolver[\"permission\"]>, readonly unknown[]>;\ntype ResolverPermissionPolicy = ResolverPermissionPolicies[number];\ntype ResolverPermissionOperand = string | boolean | { user: string };\ntype ResolverPermissionCondition = readonly [\n ResolverPermissionOperand,\n \"=\" | \"!=\",\n ResolverPermissionOperand,\n];\n\nfunction isSingleResolverCondition(\n conditions: ResolverPermissionPolicy[\"conditions\"],\n): conditions is ResolverPermissionCondition {\n return conditions.length === 3 && typeof conditions[1] === \"string\";\n}\n\nfunction resolverPermissionOperandExpr(operand: ResolverPermissionOperand): string {\n if (typeof operand === \"object\") {\n if (operand.user === \"_loggedIn\") {\n return `(context.caller !== null)`;\n }\n if (operand.user === \"id\") {\n return `context.caller?.id`;\n }\n return `context.caller?.attributes?.[${JSON.stringify(operand.user)}]`;\n }\n return JSON.stringify(operand);\n}\n\n// `_loggedIn` always evaluates to a defined boolean, but `id` and arbitrary\n// attribute lookups go through `context.caller?.` and can be `undefined` --\n// the caller is `null` for anonymous requests, and an attribute key may not\n// be set.\nfunction isArbitraryAttributeOperand(operand: ResolverPermissionOperand): boolean {\n return typeof operand === \"object\" && operand.user !== \"_loggedIn\";\n}\n\nfunction resolverPermissionConditionExpr(condition: ResolverPermissionCondition): string {\n const [left, operator, right] = condition;\n const leftExpr = resolverPermissionOperandExpr(left);\n const rightExpr = resolverPermissionOperandExpr(right);\n\n if (operator === \"!=\") {\n // A missing attribute must not satisfy `!=` -- otherwise an\n // attribute-less caller would unintentionally match a policy meant to\n // exclude only a specific value (`{ user: \"role\" } != \"BANNED\"` should\n // not let a caller with no `role` attribute at all through).\n const userOperandExpr = isArbitraryAttributeOperand(left)\n ? leftExpr\n : isArbitraryAttributeOperand(right)\n ? rightExpr\n : undefined;\n if (userOperandExpr) {\n return `(${userOperandExpr} !== undefined && ${leftExpr} !== ${rightExpr})`;\n }\n }\n\n const jsOperator = operator === \"=\" ? \"===\" : \"!==\";\n return `(${leftExpr} ${jsOperator} ${rightExpr})`;\n}\n\nfunction resolverPermissionPolicyExpr(policy: ResolverPermissionPolicy): string {\n const conditions = isSingleResolverCondition(policy.conditions)\n ? [policy.conditions]\n : policy.conditions;\n if (conditions.length === 0) {\n throw new Error(\n \"Resolver permission policy must have at least one condition, got an empty array.\",\n );\n }\n return conditions.map(resolverPermissionConditionExpr).join(\" && \");\n}\n\n/**\n * Build a JS object literal capturing whether `policy` matched and its\n * (possibly empty) description, for runtime denial-reason attribution.\n * @param policy - The policy to compile\n * @returns A JS object literal expression: `{ matched, description }`\n */\nfunction policyEntryExpr(policy: ResolverPermissionPolicy): string {\n return `{ matched: ${resolverPermissionPolicyExpr(policy)}, description: ${JSON.stringify(policy.description ?? \"\")} }`;\n}\n\n/**\n * Build the permission guard statement injected at resolver entry.\n *\n * Rejects the call with `TailorErrors` — the only error class the platform\n * turns back into a message the caller can read — when the caller doesn't match\n * `permission`, evaluated against `context.caller` — the original caller,\n * unaffected by `authInvoker`. `permission` is deny-by-default: a caller is\n * granted only by a matching `permit: true` policy, and a matching\n * `permit: false` policy always overrides that grant. The thrown message only\n * includes the description(s) of the policy/policies that actually caused the\n * denial.\n *\n * The schema requires at least one `permit: true` policy (an array of only\n * `permit: false` policies is rejected at build time), so `allowPolicies` is\n * never empty here for schema-valid input; this function still handles that\n * case defensively since it also runs against test-authored raw shapes.\n * @param permission - The resolver's `permission` config\n * @returns A JS statement, or `undefined` when `permission` is omitted or `\"allowAnonymous\"`\n */\nexport function buildResolverPermissionGuardExpr(\n permission: Resolver[\"permission\"],\n): string | undefined {\n if (!permission || permission === \"allowAnonymous\") {\n return undefined;\n }\n if (permission.length === 0) {\n throw new Error(\"Resolver permission must have at least one policy, got an empty array.\");\n }\n const denyPolicies = permission.filter((policy) => policy.permit === false);\n const allowPolicies = permission.filter((policy) => policy.permit !== false);\n\n const denyEntriesExpr = `[${denyPolicies.map(policyEntryExpr).join(\", \")}]`;\n const allowEntriesExpr = `[${allowPolicies.map(policyEntryExpr).join(\", \")}]`;\n\n return `{\n const $denyPolicies = ${denyEntriesExpr};\n const $allowPolicies = ${allowEntriesExpr};\n const $matchedDeny = $denyPolicies.filter((p) => p.matched);\n const $anyAllowMatched = $allowPolicies.some((p) => p.matched);\n if ($matchedDeny.length > 0 || ($allowPolicies.length > 0 && !$anyAllowMatched)) {\n const $reasons = ($matchedDeny.length > 0 ? $matchedDeny : $allowPolicies)\n .map((p) => p.description)\n .filter(Boolean);\n const $message = $reasons.length > 0 ? \"access denied: \" + $reasons.join(\"; \") : \"access denied\";\n throw new TailorErrors([{ message: $message, path: [] }]);\n }\n }`;\n}\n\n/**\n * A resolver's permission config together with the default declared by its\n * namespace. The resolver's own `permission` replaces the namespace default\n * instead of merging with it, so a resolver opts out of a namespace-wide\n * requirement with `permission: \"allowAnonymous\"`.\n */\nexport type ResolverPermissionResolution = {\n permission: Resolver[\"permission\"];\n defaultPermission?: Resolver[\"permission\"];\n};\n\n/**\n * Build the permission guard and input-validation statements shared by every\n * resolver entry wrapper (production bundling and `function run`).\n *\n * Kept as a single generator so a resolver-wrapping behavior (like the\n * permission guard) can't be added to one entry-point template and forgotten\n * in the other — the namespace-default precedence below is resolved here for\n * the same reason. References `context.caller`, `context.input`, `invoker`,\n * and `_internalResolver` — the caller's wrapper must bind a `context` object\n * with `user`/`input` properties and an `invoker` binding (from\n * `INVOKER_EXPR`) before inlining this expression.\n * @param params - The resolver's and its namespace's permission config\n * @returns A JS statement block to inline before calling `_internalResolver.body(...)`\n */\nexport function buildResolverPermissionAndInputCheckExpr(\n params: ResolverPermissionResolution,\n): string {\n const { permission, defaultPermission } = params;\n const permissionGuardExpr = buildResolverPermissionGuardExpr(permission ?? defaultPermission);\n return `\n ${permissionGuardExpr ?? \"\"}\n if (_internalResolver.input) {\n const result = t.object(_internalResolver.input).parse({\n value: context.input,\n data: context.input,\n invoker,\n });\n\n if (result.issues) {\n throw new TailorErrors(result.issues.map(issue => ({\n message: issue.message,\n path: issue.path ?? [],\n })));\n }\n }\n `;\n}\n","import * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { loadFilesWithIgnores, type FileLoadConfig } from \"#/cli/services/file-loader\";\nimport { createStartTransformPlugin } from \"#/cli/services/workflow/start-transformer\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { assertNoForbiddenRuntimeGlobals } from \"#/cli/shared/forbidden-runtime-globals\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { INVOKER_EXPR } from \"#/cli/shared/runtime-exprs\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport { loadExecutor } from \"./loader\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\ninterface ExecutorInfo {\n name: string;\n sourceFile: string;\n}\n\n/**\n * Options for bundling executors\n */\nexport interface BundleExecutorsOptions {\n /** Executor file loading configuration */\n config: FileLoadConfig;\n /** Start context for workflow/job transformations */\n startContext?: StartContext;\n /** Additional files to bundle (e.g., plugin-generated executors) */\n additionalFiles?: string[];\n /** Optional bundle cache for skipping unchanged builds */\n cache?: BundleCache;\n /** Whether to enable inline sourcemaps */\n inlineSourcemap?: boolean;\n /** Controls which console calls are kept in bundled code */\n bundleLogLevel?: LogLevel;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n /** Optional tsconfig lookup cache shared across bundles in this CLI run */\n tsconfigCache?: TsconfigLookupCache;\n}\n\n/**\n * Bundle executors from the specified configuration\n *\n * This function:\n * 1. Creates an in-memory entry module that extracts operation.body\n * 2. Bundles in a single step with tree-shaking\n * @param options - Bundle executor options\n * @returns Map of executor name to bundled code\n */\nexport async function bundleExecutors(\n options: BundleExecutorsOptions,\n): Promise<Map<string, string>> {\n const bundledCode = new Map<string, string>();\n const {\n config,\n startContext,\n additionalFiles = [],\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n baseDir,\n tsconfigCache,\n } = options;\n const configFiles = loadFilesWithIgnores(config, baseDir);\n const files = [...configFiles, ...additionalFiles];\n if (files.length === 0) {\n logger.warn(`No executor files found for patterns: ${config.files.join(\", \")}`);\n return bundledCode;\n }\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(files.length.toString())} files for ${styles.info('\"executor\"')}`,\n );\n\n // Load all executors and filter to function/jobFunction only\n const executors: ExecutorInfo[] = [];\n for (const file of files) {\n const executor = await loadExecutor(file);\n if (!executor) {\n logger.debug(` Skipping: ${file} (could not be loaded)`);\n continue;\n }\n\n // Only bundle function and jobFunction executors\n if (![\"function\", \"jobFunction\"].includes(executor.operation.kind)) {\n logger.debug(` Skipping: ${executor.name} (not a function executor)`);\n continue;\n }\n\n executors.push({\n name: executor.name,\n sourceFile: file,\n });\n }\n\n if (executors.length === 0) {\n logger.debug(\" No function executors to bundle\");\n return bundledCode;\n }\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // Process each executor, capped by TAILOR_BUNDLE_CONCURRENCY to bound native\n // memory use (each rolldown.build allocates its own module graph).\n const results = await withBundleConcurrency(executors, (executor) =>\n bundleSingleExecutor(\n executor,\n tsconfig,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n ),\n );\n\n for (const [name, code] of results) {\n bundledCode.set(name, code);\n }\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info('\"executor\"')}`);\n\n return bundledCode;\n}\n\nasync function bundleSingleExecutor(\n executor: ExecutorInfo,\n tsconfig: string | undefined,\n startContext?: StartContext,\n cache?: BundleCache,\n inlineSourcemap?: boolean,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<[string, string]> {\n const serializedStartContext = serializeStartContext(startContext);\n\n const contextHash = computeBundlerContextHash({\n sourceFile: executor.sourceFile,\n extraContext: serializedStartContext,\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n });\n\n const code = await withCache({\n cache,\n kind: \"executor\",\n name: executor.name,\n sourceFile: executor.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(executor.sourceFile);\n\n const entryContent = ml /* js */ `\n import _internalExecutor from \"${absoluteSourcePath}\";\n\n const __executor_function = async (args) => {\n const invoker = ${INVOKER_EXPR};\n return _internalExecutor.operation.body({ ...args, invoker });\n };\n\n export { __executor_function as main };\n `;\n const entry = createVirtualEntry(\n `executor:${executor.name}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n const startPlugin = createStartTransformPlugin(startContext);\n const plugins: rolldown.Plugin[] = [entry.plugin];\n if (startPlugin) {\n plugins.push(startPlugin);\n }\n plugins.push(\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n assertNoForbiddenRuntimeGlobals(bundledCode, `Executor \"${executor.name}\"`);\n return bundledCode;\n },\n });\n\n return [executor.name, code];\n}\n","import type { HttpAdapterConfigInput } from \"#/types/http-adapter.generated\";\n\n/**\n * Maps the lowercase `input` handler keys to the HTTP methods they serve.\n * The key set is tied to `inputHandlersSchema` in `./schema` via the\n * zinfer-generated config type, so the two cannot drift apart.\n */\nexport const HTTP_METHODS = {\n get: \"GET\",\n post: \"POST\",\n put: \"PUT\",\n patch: \"PATCH\",\n delete: \"DELETE\",\n} as const satisfies Record<keyof Required<HttpAdapterConfigInput[\"input\"]>, string>;\n\nexport type HttpMethodKey = keyof typeof HTTP_METHODS;\n\nexport const HTTP_METHOD_KEYS = Object.keys(HTTP_METHODS) as readonly HttpMethodKey[];\n","import { z } from \"zod\";\nimport { functionSchema } from \"../common\";\n\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;\n\nconst inputHandlersSchema = z\n .strictObject({\n get: functionSchema.optional().describe(\"Handler for GET requests\"),\n post: functionSchema.optional().describe(\"Handler for POST requests\"),\n put: functionSchema.optional().describe(\"Handler for PUT requests\"),\n patch: functionSchema.optional().describe(\"Handler for PATCH requests\"),\n delete: functionSchema.optional().describe(\"Handler for DELETE requests\"),\n })\n\n .refine(\n // optional fields become undefined after zod parses them\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n (val) => Object.values(val).some((v) => v !== undefined),\n \"input must declare at least one HTTP method handler\",\n )\n .describe(\"Per-method functions that transform HTTP requests to GraphQL requests\");\n\nexport const HttpAdapterConfigSchema = z.strictObject({\n name: z\n .string()\n .regex(\n NAME_PATTERN,\n \"name must be 3-63 chars, lowercase alphanumeric with hyphens, not starting or ending with a hyphen\",\n )\n .describe(\"Unique adapter name within the domain\"),\n pathPattern: z\n .string()\n .min(1)\n .describe(\"Path pattern with segment wildcards (trailing or single-segment)\"),\n enabled: z.boolean().default(true).describe(\"Whether the adapter is active\"),\n priority: z\n .number()\n .int()\n .min(0)\n .default(0)\n .describe(\"Matching priority; the lowest value wins when multiple adapters match\"),\n input: inputHandlersSchema,\n output: functionSchema\n .optional()\n .describe(\"Function that transforms GraphQL response to HTTP response\"),\n});\n","import { createRequire } from \"node:module\";\nimport { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport { HTTP_METHODS, type HttpMethodKey } from \"#/parser/service/http-adapter/index\";\nimport { getNodeBuiltinMessage, isNodeBuiltinImport } from \"#/utils/node-builtins\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\nconst ADAPTER_BUNDLE_WARN_BYTES = 64 * 1024;\nconst ADAPTER_BUNDLE_ERROR_BYTES = 256 * 1024;\nconst nodeRequire = createRequire(import.meta.url);\nconst GRAPHQL_WEB_MODULE = nodeRequire.resolve(\"@0no-co/graphql.web\");\n\nexport interface HttpAdapterBundleInput {\n name: string;\n sourceFile: string;\n methods: HttpMethodKey[];\n hasOutput: boolean;\n}\n\nexport interface HttpAdapterBundleResult {\n /** Adapter name → bundled input JS string. */\n bundledInputs: Map<string, string>;\n /** Adapter name → bundled output JS string. Only populated when the adapter has an output. */\n bundledOutputs: Map<string, string>;\n}\n\n/**\n * Bundle each adapter's `input` (and `output`, if present) into a standalone\n * IIFE defining a global `transform(input)` entry point. `input` gets a\n * generated dispatcher that routes by `req.method`; `output` is used as is.\n * @param adapters - Detected adapters to bundle\n * @param baseDir - Directory the owning config's tsconfig is resolved against\n * @param cache - Optional bundle cache for skipping unchanged builds\n * @param bundleLogLevel - Controls which console calls are kept in bundled code\n * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run\n * @returns Bundled scripts keyed by adapter name\n */\nexport async function bundleHttpAdapters(\n adapters: HttpAdapterBundleInput[],\n baseDir: string,\n cache?: BundleCache,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<HttpAdapterBundleResult> {\n if (adapters.length === 0) {\n return { bundledInputs: new Map(), bundledOutputs: new Map() };\n }\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(adapters.length.toString())} files for ${styles.info('\"http-adapter\"')}`,\n );\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // rolldown.build() is memory-intensive; cap parallelism like the other SDK bundlers.\n const tasks = adapters.flatMap((adapter) => {\n const kinds: Array<\"input\" | \"output\"> = adapter.hasOutput ? [\"input\", \"output\"] : [\"input\"];\n return kinds.map((kind) => ({ adapter, kind }));\n });\n const results = await withBundleConcurrency(tasks, ({ adapter, kind }) =>\n bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLevel, tsconfigCache),\n );\n\n const bundledInputs = new Map<string, string>();\n const bundledOutputs = new Map<string, string>();\n for (const [name, kind, code] of results) {\n if (kind === \"input\") {\n bundledInputs.set(name, code);\n } else {\n bundledOutputs.set(name, code);\n }\n }\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info('\"http-adapter\"')}`);\n\n return { bundledInputs, bundledOutputs };\n}\n\nasync function bundleAdapterScript(\n adapter: HttpAdapterBundleInput,\n kind: \"input\" | \"output\",\n tsconfig: string | undefined,\n cache: BundleCache | undefined,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<[string, \"input\" | \"output\", string]> {\n const contextHash = computeBundlerContextHash({\n sourceFile: adapter.sourceFile,\n extraContext: kind === \"input\" ? adapter.methods.join(\",\") : \"\",\n tsconfig,\n inlineSourcemap: false,\n bundleLogLevel,\n prefix: `${kind}:document-query-normalize-v1`,\n });\n\n const code = await withCache({\n cache,\n kind: kind === \"input\" ? \"http-adapter-input\" : \"http-adapter-output\",\n name: adapter.name,\n sourceFile: adapter.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(adapter.sourceFile);\n const entryContent =\n kind === \"input\"\n ? buildInputEntry(absoluteSourcePath, adapter.methods, GRAPHQL_WEB_MODULE)\n : buildOutputEntry(absoluteSourcePath);\n const entry = createVirtualEntry(\n `http-adapter:${adapter.name}:${kind}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n const rejectNodeImports: rolldown.Plugin = {\n name: \"http-adapter-reject-node-imports\",\n resolveId(source) {\n if (isNodeBuiltinImport(source)) {\n throw new Error(`HTTP adapter \"${adapter.name}\": ${getNodeBuiltinMessage(source)}`);\n }\n return null;\n },\n };\n\n // Stub out `@tailor-platform/sdk` imports: only the brand matters at\n // build time, and the IIFE must not depend on external globals.\n const stubSdkImports: rolldown.Plugin = {\n name: \"http-adapter-stub-sdk\",\n resolveId(source) {\n if (source === \"@tailor-platform/sdk\" || source.startsWith(\"@tailor-platform/sdk/\")) {\n return { id: \"\\0http-adapter-sdk-stub\", moduleSideEffects: false };\n }\n return null;\n },\n load(id) {\n if (id === \"\\0http-adapter-sdk-stub\") {\n return \"export const createHttpAdapter = (cfg) => cfg;\\nexport default { createHttpAdapter };\\n\";\n }\n return null;\n },\n };\n\n const plugins: rolldown.Plugin[] = [\n entry.plugin,\n rejectNodeImports,\n stubSdkImports,\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n ...cachePlugins,\n ];\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"iife\",\n sourcemap: false,\n minify: true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n // es2017 on purpose: async/await must survive downleveling so\n // rejectAsyncInBundle can reject it (lower targets rewrite it into\n // generator+Promise code that evades the check and breaks on Sobek).\n transform: { target: \"es2017\" },\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n const bundled = result.output[0].code;\n\n const byteLength = Buffer.byteLength(bundled, \"utf8\");\n if (byteLength > ADAPTER_BUNDLE_ERROR_BYTES) {\n throw new Error(\n `HTTP adapter \"${adapter.name}\" ${kind} script is ${byteLength} bytes, exceeding the ${ADAPTER_BUNDLE_ERROR_BYTES} byte limit`,\n );\n }\n if (byteLength > ADAPTER_BUNDLE_WARN_BYTES) {\n logger.warn(\n `HTTP adapter \"${adapter.name}\" ${kind} script is ${byteLength} bytes, larger than the recommended ${ADAPTER_BUNDLE_WARN_BYTES} byte limit`,\n );\n }\n\n // Load-time checks only see the handler functions; imported helpers can\n // still introduce async/await, so verify the whole bundle is synchronous.\n rejectAsyncInBundle(bundled, adapter.name, kind);\n\n return bundled;\n },\n });\n\n return [adapter.name, kind, code];\n}\n\nfunction buildInputEntry(\n absoluteSourcePath: string,\n methods: HttpMethodKey[],\n graphqlPrinterModule: string,\n): string {\n const cases = methods\n .map((method) => {\n const result = `__adapter.input.${method}(req)`;\n const expression = `__normalizeHttpAdapterGraphQLRequest(${result})`;\n return ` case \"${HTTP_METHODS[method]}\": return ${expression};`;\n })\n .join(\"\\n\");\n const supported = methods.map((m) => HTTP_METHODS[m]).join(\", \");\n const documentNormalizer = `import { print as __printHttpAdapterDocument } from ${JSON.stringify(graphqlPrinterModule)};\nfunction __normalizeHttpAdapterGraphQLRequest(result) {\n if (!result || typeof result.query === \"string\") {\n return result;\n }\n return { ...result, query: __printHttpAdapterDocument(result.query) };\n}\n`;\n return `${documentNormalizer}import __adapter from ${JSON.stringify(absoluteSourcePath)};\nglobalThis.transform = function(req) {\n switch (req.method) {\n${cases}\n default: throw new Error(\"HTTP adapter received unsupported method: \" + req.method + \" (supported: ${supported})\");\n }\n};\n`;\n}\n\nfunction buildOutputEntry(absoluteSourcePath: string): string {\n return `import __adapter from ${JSON.stringify(absoluteSourcePath)};\nglobalThis.transform = __adapter.output;\n`;\n}\n\nfunction rejectAsyncInBundle(code: string, adapterName: string, kind: \"input\" | \"output\"): void {\n // Use a fake filename so oxc treats this as a module. The bundle is already\n // minified IIFE; oxc parses it without complaint.\n const { program } = parseSync(`${adapterName}.${kind}.bundle.js`, code);\n\n let asyncFound = false;\n const stack: unknown[] = [program];\n while (stack.length > 0) {\n const node = stack.pop();\n if (!node || typeof node !== \"object\") continue;\n const n = node as Record<string, unknown>;\n const type = typeof n.type === \"string\" ? n.type : \"\";\n if (type === \"AwaitExpression\") {\n asyncFound = true;\n break;\n }\n if (\n (type === \"FunctionDeclaration\" ||\n type === \"FunctionExpression\" ||\n type === \"ArrowFunctionExpression\") &&\n n.async === true\n ) {\n asyncFound = true;\n break;\n }\n if ((type === \"ForOfStatement\" || type === \"ForStatement\") && n.await === true) {\n asyncFound = true;\n break;\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) stack.push(c);\n } else if (child && typeof child === \"object\") {\n stack.push(child);\n }\n }\n }\n\n if (asyncFound) {\n throw new Error(\n `HTTP adapter \"${adapterName}\" ${kind} bundle contains async/await, which is unavailable in the gateway runtime. ` +\n `Check imported helper modules — even if your handler is synchronous, an async helper will fail at runtime.`,\n );\n }\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { type HttpAdapterServiceInput } from \"#/configure/config/types\";\nimport {\n HTTP_METHOD_KEYS,\n HttpAdapterConfigSchema,\n type HttpMethodKey,\n} from \"#/parser/service/http-adapter/index\";\nimport { type HttpAdapterConfig } from \"#/types/http-adapter.generated\";\nimport { isSdkBranded } from \"#/utils/brand\";\n\ntype HttpAdapterServiceConfig = HttpAdapterServiceInput;\n\ntype LoadedHttpAdapter = {\n adapter: HttpAdapterConfig;\n sourceFile: string;\n methods: HttpMethodKey[];\n hasOutput: boolean;\n};\n\nexport type HttpAdapterService = {\n readonly config: HttpAdapterServiceConfig;\n readonly adapters: ReadonlyArray<LoadedHttpAdapter>;\n readonly fileCount: number;\n loadAdapters: () => Promise<void>;\n printLoadedAdapters: () => void;\n};\n\nexport interface CreateHttpAdapterServiceParams {\n config: HttpAdapterServiceConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\nexport function createHttpAdapterService(\n params: CreateHttpAdapterServiceParams,\n): HttpAdapterService {\n const { config, baseDir } = params;\n let adapters: LoadedHttpAdapter[] = [];\n let fileCount = 0;\n let loaded = false;\n\n return {\n config,\n get adapters() {\n return adapters;\n },\n get fileCount() {\n return fileCount;\n },\n loadAdapters: async () => {\n if (loaded) return;\n const result = await loadAdapterFiles(config, baseDir);\n adapters = result.adapters;\n fileCount = result.fileCount;\n loaded = true;\n },\n printLoadedAdapters: () => {\n if (adapters.length === 0) return;\n logger.newline();\n logger.log(`Found ${styles.highlight(adapters.length.toString())} HTTP adapters`);\n for (const { adapter, sourceFile } of adapters) {\n const relativePath = path.relative(process.cwd(), sourceFile);\n logger.log(\n `HTTP adapter: ${styles.successBright(\n `\"${adapter.name}\"`,\n )} loaded from ${styles.path(relativePath)}`,\n );\n }\n },\n };\n}\n\nasync function loadAdapterFiles(\n config: HttpAdapterServiceConfig,\n baseDir: string,\n): Promise<{ adapters: LoadedHttpAdapter[]; fileCount: number }> {\n if (config.files.length === 0) {\n return { adapters: [], fileCount: 0 };\n }\n\n const files = loadFilesWithIgnores(config, baseDir);\n\n // Import every matched file and keep the ones whose default export is a\n // createHttpAdapter() result, mirroring the resolver/executor loaders.\n // Matched files without one (e.g. shared helpers) are skipped.\n const loadResults = await Promise.all(files.map(loadAdapterFromFile));\n\n const adapters: LoadedHttpAdapter[] = [];\n const seenNames = new Map<string, string>();\n for (const result of loadResults) {\n if (!result) continue;\n const existing = seenNames.get(result.adapter.name);\n if (existing) {\n throw new Error(\n `Duplicate HTTP adapter name \"${result.adapter.name}\" found:\\n` +\n ` - ${existing}\\n` +\n ` - ${result.sourceFile}\\n` +\n `Each HTTP adapter must have a unique name.`,\n );\n }\n seenNames.set(result.adapter.name, result.sourceFile);\n adapters.push(result);\n }\n\n return { adapters, fileCount: files.length };\n}\n\nasync function loadAdapterFromFile(filePath: string): Promise<LoadedHttpAdapter | null> {\n try {\n const module = await importUserModule(filePath);\n // Only a createHttpAdapter() result is a valid default export; a plain\n // object that happens to match the schema is rejected by the brand check.\n if (!isSdkBranded(module.default, \"http-adapter\")) {\n // Not an adapter file (e.g. a shared helper matched by the glob). Guard\n // against an adapter that is only exported under a named export, which\n // would otherwise silently disappear from the deployment.\n const named = Object.entries(module).find(\n ([exportName, value]) => exportName !== \"default\" && isSdkBranded(value, \"http-adapter\"),\n );\n if (named) {\n throw new Error(\n `HTTP adapter must be the default export, but it is exported as \\`${named[0]}\\`. ` +\n \"Re-export it: `export default createHttpAdapter({...})`.\",\n );\n }\n return null;\n }\n\n const parsed = HttpAdapterConfigSchema.safeParse(module.default);\n if (!parsed.success) {\n throw parsed.error;\n }\n\n const adapter = parsed.data;\n const methods = collectMethodKeys(adapter);\n rejectAsyncHandlers(adapter, methods, filePath);\n\n return {\n adapter,\n sourceFile: filePath,\n methods,\n hasOutput: adapter.output !== undefined,\n };\n } catch (error) {\n const relativePath = path.relative(process.cwd(), filePath);\n logger.error(\n `${styles.error(\"Failed to load HTTP adapter from\")} ${styles.errorBright(relativePath)}`,\n );\n logger.error(String(error));\n throw error;\n }\n}\n\nfunction collectMethodKeys(adapter: HttpAdapterConfig): HttpMethodKey[] {\n const input = adapter.input as Partial<Record<HttpMethodKey, unknown>>;\n return HTTP_METHOD_KEYS.filter((key) => typeof input[key] === \"function\");\n}\n\nfunction rejectAsyncHandlers(\n adapter: HttpAdapterConfig,\n methods: HttpMethodKey[],\n sourceFile: string,\n): void {\n const input = adapter.input as Partial<Record<HttpMethodKey, unknown>>;\n for (const method of methods) {\n if (isAsyncFunction(input[method])) {\n throw new Error(\n `HTTP adapter \"${adapter.name}\" in ${sourceFile} has an async \\`input.${method}\\` function. ` +\n `Handlers must be synchronous; async/await is not supported.`,\n );\n }\n }\n if (adapter.output !== undefined && isAsyncFunction(adapter.output)) {\n throw new Error(\n `HTTP adapter \"${adapter.name}\" in ${sourceFile} has an async \\`output\\` function. ` +\n `Handlers must be synchronous; async/await is not supported.`,\n );\n }\n}\n\nfunction isAsyncFunction(fn: unknown): boolean {\n return typeof fn === \"function\" && fn.constructor.name === \"AsyncFunction\";\n}\n","import { z } from \"zod\";\nimport { AuthInvokerSchema } from \"#/parser/service/auth/schema\";\nimport { TailorFieldSchema } from \"#/parser/service/field/schema\";\nimport { functionSchema } from \"../common\";\n\nexport const QueryTypeSchema = z\n .union([z.literal(\"query\"), z.literal(\"mutation\")])\n .describe(\"GraphQL operation type\");\n\nconst ResolverPermissionOperandSchema = z.union([\n z.strictObject({ user: z.string() }),\n z.string(),\n z.boolean(),\n]);\n\nconst ResolverPermissionOperatorSchema = z.union([z.literal(\"=\"), z.literal(\"!=\")]);\n\nconst isUserOperand = (operand: z.infer<typeof ResolverPermissionOperandSchema>) =>\n typeof operand === \"object\";\n\n// Fixed `user` keys have a known value type; arbitrary user attributes don't\n// (their declared type lives in the configure-layer generic, not here), so\n// only these two are checked against the operand they're compared to.\nconst KNOWN_USER_OPERAND_TYPES: Record<string, \"string\" | \"boolean\"> = {\n _loggedIn: \"boolean\",\n id: \"string\",\n};\n\nconst operandTypeMismatch = (\n userOperand: z.infer<typeof ResolverPermissionOperandSchema>,\n otherOperand: z.infer<typeof ResolverPermissionOperandSchema>,\n) => {\n if (typeof userOperand !== \"object\") {\n return undefined;\n }\n const expected = KNOWN_USER_OPERAND_TYPES[userOperand.user];\n if (\n expected === undefined ||\n typeof otherOperand === \"object\" ||\n typeof otherOperand === expected\n ) {\n return undefined;\n }\n return { key: userOperand.user, expected };\n};\n\nconst ResolverPermissionConditionSchema = z\n .tuple([\n ResolverPermissionOperandSchema,\n ResolverPermissionOperatorSchema,\n ResolverPermissionOperandSchema,\n ])\n .refine(\n ([left, , right]) => isUserOperand(left) !== isUserOperand(right),\n \"Resolver permission condition must reference a `user` operand on exactly one side \" +\n \"(comparing two `user` operands to each other can match on `undefined === undefined`)\",\n )\n .superRefine(([left, , right], ctx) => {\n for (const mismatch of [operandTypeMismatch(left, right), operandTypeMismatch(right, left)]) {\n if (mismatch) {\n ctx.addIssue({\n code: \"custom\",\n message: `\\`${mismatch.key}\\` must compare to a ${mismatch.expected}`,\n });\n }\n }\n })\n .readonly();\n\nconst ResolverPermissionPolicySchema = z.strictObject({\n conditions: z.union([\n ResolverPermissionConditionSchema,\n z\n .array(ResolverPermissionConditionSchema)\n .min(1, \"Resolver permission policy must have at least one condition\")\n .readonly(),\n ]),\n permit: z.boolean(),\n description: z\n .string()\n .optional()\n .describe(\"Reason recorded for this policy, used in the access-denied error message\"),\n});\n\nexport const ResolverPermissionSchema = z\n .union([\n z\n .array(ResolverPermissionPolicySchema)\n .min(1, \"Resolver permission must have at least one policy\")\n .refine(\n (policies) => policies.some((policy) => policy.permit === true),\n \"Resolver permission must include at least one `permit: true` policy — a policy array \" +\n \"with only `permit: false` policies still lets any caller through by simply not \" +\n \"authenticating, since none of the deny conditions apply to a caller with no user \" +\n \"attributes at all\",\n )\n .readonly(),\n z.literal(\"allowAnonymous\"),\n ])\n .describe(\n \"Access requirement for this resolver, evaluated against the original caller \" +\n '(unaffected by `invoker`) before `body` runs. \"allowAnonymous\" documents that ' +\n \"anonymous callers are allowed. Omitted (default): unchanged, anonymous callers can \" +\n \"reach the resolver\",\n );\n\nexport const ResolverSchema = z.strictObject({\n operation: QueryTypeSchema.describe(\"GraphQL operation type (query or mutation)\"),\n name: z.string().describe(\"Resolver name\"),\n description: z.string().optional().describe(\"Resolver description\"),\n input: z.record(z.string(), TailorFieldSchema).optional().describe(\"Input field definitions\"),\n body: functionSchema.describe(\"Resolver implementation function\"),\n output: TailorFieldSchema.describe(\"Output field definition\"),\n publishEvents: z.boolean().optional().describe(\"Enable publishing events from this resolver\"),\n invoker: AuthInvokerSchema.optional().describe(\"Machine user to execute this resolver as\"),\n permission: ResolverPermissionSchema.optional(),\n});\n","import { importUserModule } from \"#/cli/shared/user-modules\";\nimport { ResolverSchema } from \"#/parser/service/resolver/index\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\n/**\n * Load and validate a resolver definition from a file.\n * @param resolverFilePath - Path to the resolver file\n * @returns Parsed resolver or null if invalid\n */\nexport async function loadResolver(resolverFilePath: string): Promise<Resolver | null> {\n const resolverModule = await importUserModule(resolverFilePath);\n const resolver = resolverModule.default;\n\n const parseResult = ResolverSchema.safeParse(resolver);\n if (!parseResult.success) {\n return null;\n }\n\n return parseResult.data;\n}\n","import * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { type BundleCache, computeBundlerContextHash, withCache } from \"#/cli/cache/bundle-cache\";\nimport { type FileLoadConfig, loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { createStartTransformPlugin } from \"#/cli/services/workflow/start-transformer\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { assertNoForbiddenRuntimeGlobals } from \"#/cli/shared/forbidden-runtime-globals\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { buildResolverPermissionAndInputCheckExpr, INVOKER_EXPR } from \"#/cli/shared/runtime-exprs\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport { loadResolver } from \"./loader\";\nimport type { LogLevel } from \"#/configure/config/types\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\ninterface ResolverInfo {\n name: string;\n sourceFile: string;\n permission: Resolver[\"permission\"];\n}\n\nexport interface BundleResolversOptions {\n /** Resolver namespace name */\n namespace: string;\n /** Resolver file loading configuration */\n config: FileLoadConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n /** The namespace's `defaultPermission`, applied to resolvers declaring none */\n defaultPermission?: Resolver[\"permission\"];\n /** Start context for workflow/job transformations */\n startContext?: StartContext;\n /** Optional bundle cache for skipping unchanged builds */\n cache?: BundleCache;\n /** Whether to enable inline sourcemaps */\n inlineSourcemap?: boolean;\n /** Controls which console calls are kept in bundled code */\n bundleLogLevel?: LogLevel;\n /** Optional tsconfig lookup cache shared across bundles in this CLI run */\n tsconfigCache?: TsconfigLookupCache;\n}\n\n/**\n * Bundle resolvers for the specified namespace\n *\n * This function:\n * 1. Uses a transform plugin to add validation wrapper during bundling\n * 2. Creates an in-memory entry module\n * 3. Bundles in a single step with tree-shaking\n * @param options - Bundle options\n * @returns Map of resolver name to bundled code\n */\nexport async function bundleResolvers(\n options: BundleResolversOptions,\n): Promise<Map<string, string>> {\n const {\n namespace,\n config,\n baseDir,\n defaultPermission,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n tsconfigCache,\n } = options;\n const bundledCode = new Map<string, string>();\n const files = loadFilesWithIgnores(config, baseDir);\n if (files.length === 0) {\n logger.warn(`No resolver files found for patterns: ${config.files.join(\", \")}`);\n return bundledCode;\n }\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(files.length.toString())} files for ${styles.info(\n `\"${namespace}\"`,\n )}`,\n );\n\n // Load all resolvers to get their names\n const resolvers: ResolverInfo[] = [];\n for (const file of files) {\n const resolver = await loadResolver(file);\n if (!resolver) {\n logger.debug(` Skipping: ${file} (could not be loaded)`);\n continue;\n }\n resolvers.push({\n name: resolver.name,\n sourceFile: file,\n permission: resolver.permission,\n });\n }\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // Process each resolver, capped by TAILOR_BUNDLE_CONCURRENCY to bound native\n // memory use (each rolldown.build allocates its own module graph).\n const results = await withBundleConcurrency(resolvers, (resolver) =>\n bundleSingleResolver({\n namespace,\n resolver,\n tsconfig,\n defaultPermission,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n }),\n );\n\n for (const [name, code] of results) {\n bundledCode.set(name, code);\n }\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info(`\"${namespace}\"`)}`);\n\n return bundledCode;\n}\n\ntype BundleSingleResolverOptions = Omit<BundleResolversOptions, \"config\" | \"baseDir\"> & {\n resolver: ResolverInfo;\n tsconfig: string | undefined;\n};\n\nasync function bundleSingleResolver(\n options: BundleSingleResolverOptions,\n): Promise<[string, string]> {\n const {\n namespace,\n resolver,\n tsconfig,\n defaultPermission,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n tsconfigCache,\n } = options;\n const serializedStartContext = serializeStartContext(startContext);\n\n const contextHash = computeBundlerContextHash({\n sourceFile: resolver.sourceFile,\n // The namespace default is part of the generated guard but lives in the\n // config file, not in any resolver source, so a cached bundle would\n // otherwise survive a change to it. Encoded as a pair rather than joined,\n // so no separator has to be a character neither value can contain.\n extraContext: JSON.stringify([serializedStartContext, defaultPermission ?? null]),\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n });\n\n const code = await withCache({\n cache,\n kind: \"resolver\",\n namespace,\n name: resolver.name,\n sourceFile: resolver.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(resolver.sourceFile);\n const guardAndInputCheckExpr = buildResolverPermissionAndInputCheckExpr({\n permission: resolver.permission,\n defaultPermission,\n });\n\n const entryContent = ml /* js */ `\n import _internalResolver from \"${absoluteSourcePath}\";\n import { t } from \"@tailor-platform/sdk\";\n\n const $tailor_resolver_body = async (context) => {\n const invoker = ${INVOKER_EXPR};\n ${guardAndInputCheckExpr}\n return _internalResolver.body({ ...context, invoker });\n };\n\n export { $tailor_resolver_body as main };\n `;\n const entry = createVirtualEntry(\n `resolver:${resolver.name}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n const startPlugin = createStartTransformPlugin(startContext);\n const plugins: rolldown.Plugin[] = [entry.plugin];\n if (startPlugin) {\n plugins.push(startPlugin);\n }\n plugins.push(\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n assertNoForbiddenRuntimeGlobals(bundledCode, `Resolver \"${resolver.name}\"`);\n return bundledCode;\n },\n });\n\n return [resolver.name, code];\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { ResolverPermissionSchema } from \"#/parser/service/resolver/index\";\nimport type { ResolverServiceConfig, ResolverServiceInput } from \"#/configure/config/types\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\ntype ParseParams = {\n namespace: string;\n config: ResolverServiceConfig;\n};\n\n/**\n * Validate a resolver namespace's `defaultPermission` with the same schema as\n * a resolver's own `permission`, so an invalid policy fails the build instead\n * of compiling into a guard that lets everyone through.\n * @param params - The namespace name and its resolver service config\n * @returns The validated default, or `undefined` when the namespace declares none\n */\nexport function parseResolverDefaultPermission(\n params: ParseParams,\n): Resolver[\"permission\"] | undefined {\n const { namespace, config } = params;\n if (config.defaultPermission === undefined) {\n return undefined;\n }\n const result = ResolverPermissionSchema.safeParse(config.defaultPermission);\n if (!result.success) {\n throw new Error(\n `Invalid \\`defaultPermission\\` for resolver namespace \"${namespace}\": ` +\n result.error.issues.map((issue) => issue.message).join(\"; \"),\n );\n }\n return result.data;\n}\n\ntype ResolveForFileParams = {\n config: ResolverServiceInput | undefined;\n filePath: string;\n baseDir: string;\n};\n\n/**\n * Find the `defaultPermission` of the resolver namespace a file belongs to.\n *\n * `function run` receives a single file rather than a namespace, so the\n * namespace is recovered by matching the file against each namespace's own\n * patterns — otherwise a test run would skip a guard the deployed resolver has.\n *\n * Nothing stops two namespaces' patterns from claiming the same file, and\n * `deploy` then bundles that resolver once per namespace, each with its own\n * default. Picking one here would make the test run agree with only one of\n * the deployed copies, so an ambiguous file is rejected instead.\n * @param params - The config's resolver section, the resolver file, and the config's own directory\n * @returns The owning namespace's validated default, or `undefined` when no namespace claims the file\n */\nexport function resolveResolverDefaultPermissionForFile(\n params: ResolveForFileParams,\n): Resolver[\"permission\"] | undefined {\n const { config, filePath, baseDir } = params;\n if (!config) {\n return undefined;\n }\n\n // Globbed paths keep the platform's own separators; `path.resolve` here is\n // pathe's, which normalizes both sides to the same form before comparing.\n const targetFile = path.resolve(filePath);\n const owners: Array<{ namespace: string; config: ResolverServiceConfig }> = [];\n for (const [namespace, serviceConfig] of Object.entries(config)) {\n if (\"external\" in serviceConfig) {\n continue;\n }\n const files = loadFilesWithIgnores(serviceConfig, baseDir);\n if (files.some((file) => path.resolve(file) === targetFile)) {\n owners.push({ namespace, config: serviceConfig });\n }\n }\n\n if (owners.length > 1) {\n throw new Error(\n `Resolver ${path.relative(process.cwd(), targetFile)} matches more than one resolver ` +\n `namespace: ${owners.map((owner) => `\"${owner.namespace}\"`).join(\", \")}. ` +\n `Each namespace applies its own \\`defaultPermission\\`, so narrow the \\`files\\`/` +\n `\\`ignores\\` patterns until exactly one namespace claims this file.`,\n );\n }\n\n const [owner] = owners;\n return owner ? parseResolverDefaultPermission(owner) : undefined;\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { ResolverSchema } from \"#/parser/service/resolver/index\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport { parseResolverDefaultPermission } from \"./default-permission\";\nimport type { ResolverServiceConfig } from \"#/configure/config/types\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\nexport type ResolverService = {\n readonly namespace: string;\n readonly config: ResolverServiceConfig;\n /** The namespace's validated `defaultPermission`, applied to resolvers declaring none. */\n readonly defaultPermission: Resolver[\"permission\"] | undefined;\n readonly resolvers: Record<string, Resolver>;\n loadResolvers: () => Promise<void>;\n};\n\n/**\n * Creates a new ResolverService instance.\n * @param namespace - The namespace for this resolver service\n * @param config - The resolver service configuration\n * @param baseDir - Directory the config's file patterns are resolved against\n * @returns A new ResolverService instance\n */\nexport function createResolverService(\n namespace: string,\n config: ResolverServiceConfig,\n baseDir: string,\n): ResolverService {\n const resolvers: Record<string, Resolver> = {};\n const defaultPermission = parseResolverDefaultPermission({ namespace, config });\n let loaded = false;\n\n const loadResolverForFile = async (resolverFile: string): Promise<Resolver | undefined> => {\n try {\n const resolverModule = await importUserModule(resolverFile);\n const result = ResolverSchema.safeParse(resolverModule.default);\n if (result.success) {\n const relativePath = path.relative(process.cwd(), resolverFile);\n logger.log(\n `Resolver: ${styles.successBright(`\"${result.data.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n resolvers[resolverFile] = result.data;\n return result.data;\n }\n if (isSdkBranded(resolverModule.default, \"resolver\")) {\n throw result.error;\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), resolverFile);\n logger.error(`Failed to load resolver from ${styles.bold(relativePath)}`);\n logger.error(String(error));\n throw error;\n }\n return undefined;\n };\n\n return {\n namespace,\n config,\n defaultPermission,\n get resolvers() {\n return resolvers;\n },\n loadResolvers: async () => {\n if (loaded) {\n return;\n }\n if (config.files.length === 0) {\n return;\n }\n\n const resolverFiles = loadFilesWithIgnores(config, baseDir);\n\n logger.log(\n `Found ${styles.highlight(resolverFiles.length.toString())} resolver files for service ${styles.highlight(`\"${namespace}\"`)}`,\n );\n\n await Promise.all(resolverFiles.map((resolverFile) => loadResolverForFile(resolverFile)));\n assertUniqueResolverNames(resolvers, namespace);\n warnUndeclaredPermissions({ namespace, defaultPermission, resolvers });\n loaded = true;\n },\n };\n}\n\ntype WarnUndeclaredPermissionsParams = {\n namespace: string;\n defaultPermission: Resolver[\"permission\"] | undefined;\n resolvers: Record<string, Resolver>;\n};\n\n/**\n * Warn about resolvers that declare no access requirement at all.\n *\n * A namespace-level `defaultPermission` covers every resolver in the\n * namespace, so the warning only fires when the namespace declares none and\n * at least one of its resolvers declares none either — those resolvers are\n * reachable by anonymous callers.\n * @param params - The namespace, its default permission, and its loaded resolvers\n */\nfunction warnUndeclaredPermissions(params: WarnUndeclaredPermissionsParams): void {\n const { namespace, defaultPermission, resolvers } = params;\n if (defaultPermission !== undefined) {\n return;\n }\n\n const loaded = Object.values(resolvers);\n const undeclared = loaded.filter((resolver) => resolver.permission === undefined);\n if (undeclared.length === 0) {\n return;\n }\n\n logger.warn(\n `Resolver namespace ${styles.highlight(`\"${namespace}\"`)}: ${undeclared.length} of ` +\n `${loaded.length} resolvers declare no \\`permission\\`, so anonymous callers can reach ` +\n `them. Set \\`defaultPermission\\` on the namespace, or declare \\`permission\\` on each ` +\n `resolver (\"allowAnonymous\" if public access is intended).`,\n );\n // Sorted because resolvers load concurrently, so their record order varies per run.\n const names = undeclared.map((resolver) => resolver.name).toSorted();\n logger.debug(` Resolvers without \\`permission\\`: ${names.join(\", \")}`);\n}\n\n/**\n * Assert that every loaded resolver in a namespace has a unique name.\n * Resolvers are stored by source file, so two files declaring the same\n * `name` would otherwise silently share a single bundle cache entry.\n * @param resolvers - Loaded resolvers keyed by source file\n * @param namespace - The namespace the resolvers belong to\n */\nfunction assertUniqueResolverNames(resolvers: Record<string, Resolver>, namespace: string): void {\n const seenNames = new Map<string, string>();\n for (const [file, resolver] of Object.entries(resolvers)) {\n const relativePath = path.relative(process.cwd(), file);\n const existing = seenNames.get(resolver.name);\n if (existing) {\n throw new Error(\n `Duplicate resolver name \"${resolver.name}\" found in namespace \"${namespace}\":\\n` +\n ` - ${existing}\\n` +\n ` - ${relativePath}\\n` +\n `Each resolver must have a unique name within a namespace.`,\n );\n }\n seenNames.set(resolver.name, relativePath);\n }\n}\n","import { parseSync } from \"oxc-parser\";\nimport { type ASTNode, type Replacement, applyReplacements, findStatementEnd } from \"./ast-utils\";\nimport { findAllJobs } from \"./job-detector\";\nimport { collectSdkBindings, isSdkFunctionCall } from \"./sdk-binding-collector\";\nimport type { Program } from \"@oxc-project/types\";\n\n/**\n * Find variable declarations by export names\n * Returns a map of export name to statement range\n * @param program - Parsed TypeScript program\n * @returns Map of export name to statement range\n */\nfunction findVariableDeclarationsByName(\n program: Program,\n): Map<string, { start: number; end: number }> {\n const declarations = new Map<string, { start: number; end: number }>();\n\n for (const statement of program.body) {\n const declaration =\n statement.type === \"ExportNamedDeclaration\" ? statement.declaration : statement;\n if (declaration?.type !== \"VariableDeclaration\") continue;\n\n const variableDeclaration = declaration;\n for (const declarator of variableDeclaration.declarations) {\n if (declarator.id.type === \"Identifier\") {\n declarations.set(declarator.id.name, {\n start: statement.start,\n end: statement.end,\n });\n }\n }\n }\n\n return declarations;\n}\n\n/**\n * Find createWorkflow default export declarations\n * Returns the range of the export statement to remove\n * @param program - Parsed TypeScript program\n * @returns Range of the default export statement or null\n */\nfunction findWorkflowDefaultExport(program: Program): { start: number; end: number } | null {\n const bindings = collectSdkBindings(program, \"createWorkflow\");\n\n for (const statement of program.body) {\n if (statement.type === \"ExportDefaultDeclaration\") {\n const exportDecl = statement;\n const declaration = exportDecl.declaration;\n\n // Check for direct createWorkflow call: export default createWorkflow({...})\n if (isSdkFunctionCall(declaration as unknown as ASTNode, bindings, \"createWorkflow\")) {\n return { start: exportDecl.start, end: exportDecl.end };\n }\n\n // Check for variable reference that was assigned from createWorkflow\n // This handles: const wf = createWorkflow({...}); export default wf;\n if (declaration.type === \"Identifier\") {\n return { start: exportDecl.start, end: exportDecl.end };\n }\n }\n }\n\n return null;\n}\n\n/**\n * Transform workflow source code\n * - Other jobs: remove entire variable declaration\n * @param source - The source code to transform\n * @param targetJobName - The name of the target job (from job config)\n * @param targetJobExportName - The export name of the target job (optional, for enhanced detection)\n * @param otherJobExportNames - Export names of other jobs to remove (optional, for enhanced detection)\n * @returns Transformed workflow source code\n */\nexport function transformWorkflowSource(\n source: string,\n targetJobName: string,\n targetJobExportName?: string,\n otherJobExportNames?: string[],\n): string {\n // Use .ts extension to properly parse TypeScript code\n const { program } = parseSync(\"input.ts\", source);\n\n // Find all jobs using AST detection\n const detectedJobs = findAllJobs(program, source);\n\n // Defense-in-depth: the bundler already gates this function behind an\n // isJobSourceFile check, so dependency files should not reach here.\n // Guard anyway so that external callers don't accidentally strip exports\n // from files that don't contain the target job.\n const targetJobExistsInFile = detectedJobs.some((j) => j.name === targetJobName);\n if (!targetJobExistsInFile) {\n return source;\n }\n\n // Find all variable declarations for export name-based removal\n const allDeclarations = findVariableDeclarationsByName(program);\n\n const replacements: Replacement[] = [];\n const removedStarts = new Set<number>();\n\n // Step 1: First, collect all ranges that will be removed (other job declarations)\n // This runs before the trigger pass so calls inside sibling jobs are removed first.\n for (const job of detectedJobs) {\n if (job.name === targetJobName) {\n continue;\n }\n\n if (job.statementRange && !removedStarts.has(job.statementRange.start)) {\n const endPos = findStatementEnd(source, job.statementRange.end);\n removedStarts.add(job.statementRange.start);\n replacements.push({\n start: job.statementRange.start,\n end: endPos,\n text: \"\",\n });\n } else if (!job.statementRange) {\n // Fallback: replace body with empty function if we can't find the statement\n removedStarts.add(job.bodyValueRange.start);\n replacements.push({\n start: job.bodyValueRange.start,\n end: job.bodyValueRange.end,\n text: \"() => {}\",\n });\n }\n }\n\n // Step 2: Remove other jobs by export name (catches jobs missed by AST detection)\n if (otherJobExportNames) {\n for (const exportName of otherJobExportNames) {\n if (exportName === targetJobExportName) continue;\n\n const declRange = allDeclarations.get(exportName);\n if (declRange && !removedStarts.has(declRange.start)) {\n const endPos = findStatementEnd(source, declRange.end);\n removedStarts.add(declRange.start);\n replacements.push({\n start: declRange.start,\n end: endPos,\n text: \"\",\n });\n }\n }\n }\n\n // Step 3: Remove createWorkflow default export (not needed in job bundles)\n const workflowExport = findWorkflowDefaultExport(program);\n if (workflowExport && !removedStarts.has(workflowExport.start)) {\n const endPos = findStatementEnd(source, workflowExport.end);\n removedStarts.add(workflowExport.start);\n replacements.push({\n start: workflowExport.start,\n end: endPos,\n text: \"\",\n });\n }\n\n return applyReplacements(source, replacements);\n}\n","import * as fs from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { assertNoForbiddenRuntimeGlobals } from \"#/cli/shared/forbidden-runtime-globals\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { INVOKER_EXPR } from \"#/cli/shared/runtime-exprs\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport { getModuleExportName, type ASTNode } from \"./ast-utils\";\nimport { findAllJobs } from \"./job-detector\";\nimport { transformWorkflowSource } from \"./source-transformer\";\nimport { detectResolvedStartCalls, hasStartCall, transformStartCalls } from \"./start-transformer\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\nfunction safeRealpath(p: string): string {\n const resolved = path.resolve(p);\n try {\n return fs.realpathSync(resolved);\n } catch (e) {\n logger.debug(`realpathSync failed for ${resolved}: ${e instanceof Error ? e.message : e}`);\n return resolved;\n }\n}\n\ninterface JobInfo {\n name: string;\n exportName: string;\n sourceFile: string;\n}\n\n/**\n * Thrown when a job's dependency graph cannot be statically determined, so the\n * job or a call to it would otherwise be silently dropped from the bundle.\n */\nclass WorkflowJobDetectionError extends Error {}\n\nfunction isExecJobFunctionCallee(node: unknown): boolean {\n if (!node || typeof node !== \"object\") return false;\n const callee = node as ASTNode;\n if (callee.type !== \"MemberExpression\") return false;\n const property = callee.property as ASTNode | undefined;\n if (property?.type !== \"Identifier\" || property.name !== \"execJobFunction\") return false;\n const object = callee.object as ASTNode | undefined;\n if (object?.type !== \"MemberExpression\") return false;\n const workflowProperty = object.property as ASTNode | undefined;\n if (workflowProperty?.type !== \"Identifier\" || workflowProperty.name !== \"workflow\") {\n return false;\n }\n const root = object.object as ASTNode | undefined;\n return root?.type === \"Identifier\" && root.name === \"tailor\";\n}\n\nfunction extractStaticStringValue(node: unknown): string | undefined {\n if (!node || typeof node !== \"object\") return undefined;\n const value = node as ASTNode;\n if (value.type === \"Literal\" && typeof value.value === \"string\") {\n return value.value;\n }\n if (value.type === \"TemplateLiteral\") {\n const quasis = value.quasis as Array<{ value?: { cooked?: string } }> | undefined;\n const expressions = value.expressions as unknown[] | undefined;\n if (quasis?.length === 1 && (expressions?.length ?? 0) === 0) {\n return quasis[0]?.value?.cooked;\n }\n }\n return undefined;\n}\n\nconst RUNTIME_WORKFLOW_MODULE_SPECIFIERS = new Set([\n \"@tailor-platform/sdk/runtime\",\n \"@tailor-platform/sdk/runtime/workflow\",\n]);\n\nfunction collectRuntimeWorkflowImportBindings(program: ASTNode): Set<string> {\n const bindings = new Set<string>();\n for (const statement of (program.body as ASTNode[] | undefined) ?? []) {\n if (statement.type !== \"ImportDeclaration\" || statement.importKind === \"type\") continue;\n const source = statement.source as ASTNode | undefined;\n if (\n typeof source?.value !== \"string\" ||\n !RUNTIME_WORKFLOW_MODULE_SPECIFIERS.has(source.value)\n ) {\n continue;\n }\n for (const specifier of (statement.specifiers as ASTNode[] | undefined) ?? []) {\n if (specifier.type !== \"ImportSpecifier\" || specifier.importKind === \"type\") continue;\n const imported = getModuleExportName(specifier.imported);\n const local = getModuleExportName(specifier.local);\n if (imported === \"workflow\" && local) bindings.add(local);\n }\n }\n return bindings;\n}\n\nfunction isDirectExecJobFunctionCallee(\n node: unknown,\n runtimeWorkflowBindings: ReadonlySet<string>,\n): boolean {\n if (isExecJobFunctionCallee(node)) return true;\n if (!node || typeof node !== \"object\") return false;\n const callee = node as ASTNode;\n if (callee.type !== \"MemberExpression\") return false;\n const property = callee.property as ASTNode | undefined;\n if (property?.type !== \"Identifier\" || property.name !== \"execJobFunction\") return false;\n const object = callee.object as ASTNode | undefined;\n return object?.type === \"Identifier\" && runtimeWorkflowBindings.has(object.name as string);\n}\n\ninterface DirectExecJobFunctionCall {\n targetName: string | undefined;\n}\n\n/**\n * Find calls to `execJobFunction` written directly in workflow source, on\n * either the ambient `tailor.workflow` global or a `workflow` value imported\n * from `@tailor-platform/sdk/runtime`(`/workflow`) (aliases included). Such a\n * call is never recognized as a dependency, so its target would silently be\n * dropped from the bundle unless something else happens to reference it.\n * @param program - Parsed workflow file AST\n * @returns Every direct execJobFunction call found, with its static target\n * name when the first argument is a string literal\n */\nfunction findDirectExecJobFunctionCalls(program: ASTNode): DirectExecJobFunctionCall[] {\n const runtimeWorkflowBindings = collectRuntimeWorkflowImportBindings(program);\n const calls: DirectExecJobFunctionCall[] = [];\n\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n if (\n node.type === \"CallExpression\" &&\n isDirectExecJobFunctionCallee(node.callee, runtimeWorkflowBindings)\n ) {\n const args = node.arguments as unknown[] | undefined;\n calls.push({ targetName: extractStaticStringValue(args?.[0]) });\n }\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(program);\n return calls;\n}\n\nfunction buildDirectExecJobFunctionErrorMessage(\n sourceFile: string,\n call: DirectExecJobFunctionCall,\n): string {\n if (call.targetName !== undefined) {\n return (\n `Workflow file ${sourceFile} calls execJobFunction(\"${call.targetName}\", ...) directly. A ` +\n `direct call is never recognized as a dependency, so \"${call.targetName}\" would silently be ` +\n `dropped from the bundle unless something else happens to reference it. Call the ` +\n `\"${call.targetName}\" job's .start(...) method from inside a job body instead.`\n );\n }\n return (\n `Workflow file ${sourceFile} calls execJobFunction(...) directly with a job name that isn't a ` +\n `string literal, so the target can't be resolved at build time. Call the target job's own ` +\n `.start(...) method from inside a job body instead of calling execJobFunction directly.`\n );\n}\n\n/**\n * Find the job names a bundled job's code calls `execJobFunction` on, by\n * looking for `tailor.workflow.execJobFunction(<name>, ...)` calls with a\n * static string name.\n * @param code - Bundled job code\n * @returns Target job names referenced with a statically known name\n */\nexport function collectExecJobFunctionTargets(code: string): string[] {\n const { program, errors } = parseSync(\"input.js\", code);\n if (errors.length > 0) {\n throw new WorkflowJobDetectionError(\n `Failed to parse bundled job code while checking for missed dependencies: ` +\n `${errors.map((e) => e.message).join(\"; \")}`,\n );\n }\n const targets: string[] = [];\n\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n if (node.type === \"CallExpression\" && isExecJobFunctionCallee(node.callee)) {\n const args = node.arguments as unknown[] | undefined;\n const target = extractStaticStringValue(args?.[0]);\n if (target !== undefined) targets.push(target);\n }\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return targets;\n}\n\n/**\n * Check every bundled job's code for execJobFunction targets that were not\n * bundled, throwing a WorkflowJobDetectionError naming the caller job when\n * one is found (or when the caller's own bundled code fails to parse).\n * @param bundledCode - Bundled job code by job name\n * @param usedJobNames - Job names that were actually bundled\n */\nexport function validateBundledDependencies(\n bundledCode: Map<string, string>,\n usedJobNames: readonly string[],\n): void {\n const usedJobNameSet = new Set(usedJobNames);\n for (const [callerJobName, code] of bundledCode) {\n let targets: string[];\n try {\n targets = collectExecJobFunctionTargets(code);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new WorkflowJobDetectionError(\n `Failed to check the bundled output of workflow job \"${callerJobName}\" for missed ` +\n `dependencies: ${message}`,\n );\n }\n\n for (const targetJobName of targets) {\n if (!usedJobNameSet.has(targetJobName)) {\n throw new WorkflowJobDetectionError(\n `Workflow job \"${callerJobName}\" calls execJobFunction(\"${targetJobName}\", ...) — usually the ` +\n `result of a rewritten \"${targetJobName}\" job .start() call — but \"${targetJobName}\" was not ` +\n `detected as a dependency and is not included in the bundle. Call the \"${targetJobName}\" job's ` +\n `.start() method from inside the body of workflow job \"${callerJobName}\" (a nested function ` +\n `inside body works too), or make sure the file containing the call is covered by the workflow ` +\n `service's \"files\" pattern.`,\n );\n }\n }\n }\n}\n\nexport interface BundleWorkflowJobsResult {\n /** Maps mainJobName -> list of all job names it depends on (including itself) */\n mainJobDeps: Record<string, string[]>;\n /** Job names that were actually bundled */\n usedJobNames: string[];\n /** Maps job name to bundled code string */\n bundledCode: Map<string, string>;\n}\n\n/**\n * Bundle workflow jobs\n *\n * This function:\n * 1. Detects which jobs are actually used (mainJobs + their dependencies)\n * 2. Uses a transform plugin to transform start calls during bundling\n * 3. Creates an in-memory entry module and bundles with tree-shaking\n *\n * Returns metadata about which jobs each workflow uses.\n * @param allJobs - All available job infos\n * @param mainJobNames - Names of main jobs\n * @param env - Environment variables to inject\n * @param startContext - Start context for transformations\n * @param baseDir - Directory the owning config's tsconfig is resolved against\n * @param cache - Optional bundle cache for skipping unchanged builds\n * @param inlineSourcemap - Whether to enable inline sourcemaps\n * @param bundleLogLevel - Controls which console calls are kept in bundled code\n * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run\n * @returns Workflow job bundling result\n */\nexport async function bundleWorkflowJobs(\n allJobs: JobInfo[],\n mainJobNames: string[],\n env: Record<string, string | number | boolean> = {},\n startContext: StartContext,\n baseDir: string,\n cache?: BundleCache,\n inlineSourcemap?: boolean,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<BundleWorkflowJobsResult> {\n if (allJobs.length === 0) {\n logger.warn(\"No workflow jobs to bundle\");\n return { mainJobDeps: {}, usedJobNames: [], bundledCode: new Map() };\n }\n\n // Filter to only used jobs and get per-mainJob dependencies\n const { usedJobs, mainJobDeps } = await filterUsedJobs(allJobs, mainJobNames, startContext);\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(usedJobs.length.toString())} files for ${styles.info('\"workflow-job\"')}`,\n );\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // Process each job, capped by TAILOR_BUNDLE_CONCURRENCY to bound native\n // memory use (each rolldown.build allocates its own module graph).\n const results = await withBundleConcurrency(usedJobs, (job) =>\n bundleSingleJob(\n job,\n usedJobs,\n tsconfig,\n env,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n ),\n );\n\n const bundledCode = new Map<string, string>();\n for (const [name, code] of results) {\n bundledCode.set(name, code);\n }\n\n // Backstop for dependency-graph gaps the source-level checks in\n // filterUsedJobs cannot see (e.g. a factored-out .start() call inside a\n // helper file outside `workflow.files`): the rewrite still resolves and\n // produces a valid execJobFunction call, but the target was never bundled.\n // Runs before the success log below so a failure here doesn't print a\n // misleading \"Bundled\" message right before throwing.\n validateBundledDependencies(\n bundledCode,\n usedJobs.map((job) => job.name),\n );\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info('\"workflow-job\"')}`);\n\n return {\n mainJobDeps,\n usedJobNames: usedJobs.map((job) => job.name),\n bundledCode,\n };\n}\n\ninterface FilterUsedJobsResult {\n usedJobs: JobInfo[];\n mainJobDeps: Record<string, string[]>;\n}\n\n/**\n * Filter jobs to only include those that are actually used.\n * A job is \"used\" if:\n * - It's a mainJob of a workflow\n * - It's called via .start() from another used job (transitively)\n *\n * Also returns a map of mainJob -> all jobs it depends on (for metadata).\n * @param allJobs - All available job infos\n * @param mainJobNames - Names of main jobs\n * @param startContext - Module binding metadata for resolving start targets\n * @returns Used jobs and main job dependency map\n */\nasync function filterUsedJobs(\n allJobs: JobInfo[],\n mainJobNames: string[],\n startContext: StartContext,\n): Promise<FilterUsedJobsResult> {\n if (allJobs.length === 0 || mainJobNames.length === 0) {\n return { usedJobs: [], mainJobDeps: {} };\n }\n\n // Build maps for lookups\n const jobsBySourceFile = new Map<string, JobInfo[]>();\n for (const job of allJobs) {\n const existing = jobsBySourceFile.get(job.sourceFile) || [];\n existing.push(job);\n jobsBySourceFile.set(job.sourceFile, existing);\n }\n\n // Files with no job of their own (e.g. a shared helper module factoring out\n // .start() calls) still need scanning for stray start calls below; otherwise\n // a call factored into such a file is never checked at all.\n const filesToScan = new Map(jobsBySourceFile);\n const knownRealpaths = new Set([...jobsBySourceFile.keys()].map(safeRealpath));\n for (const binding of startContext.modules.values()) {\n if (!knownRealpaths.has(safeRealpath(binding.sourceFile))) {\n filesToScan.set(binding.sourceFile, []);\n }\n }\n\n // Detect start calls and build dependency graph\n // Maps job name -> set of job names it starts\n const dependencies = new Map<string, Set<string>>();\n\n // Process all source files in parallel\n const fileResults = await Promise.all(\n Array.from(filesToScan.entries()).map(async ([sourceFile, jobs]) => {\n try {\n const source = await fs.promises.readFile(sourceFile, \"utf-8\");\n const { program, errors } = parseSync(sourceFile, source);\n if (errors.length > 0) {\n throw new WorkflowJobDetectionError(\n `Failed to parse ${sourceFile}: ${errors.map((e) => e.message).join(\"; \")}`,\n );\n }\n\n const [firstDirectExecCall] = findDirectExecJobFunctionCalls(program as unknown as ASTNode);\n if (firstDirectExecCall) {\n throw new WorkflowJobDetectionError(\n buildDirectExecJobFunctionErrorMessage(sourceFile, firstDirectExecCall),\n );\n }\n\n // Find all jobs in this file to get body ranges\n const detectedJobs = findAllJobs(program, source);\n const startCalls = detectResolvedStartCalls(program, source, startContext, sourceFile);\n\n // For each job in this file, find which start calls are inside its body\n const jobDependencies: Array<{ jobName: string; deps: Set<string> }> = [];\n\n for (const job of jobs) {\n const detectedJob = detectedJobs.find((d) => d.name === job.name);\n if (!detectedJob) {\n throw new WorkflowJobDetectionError(\n `Workflow job \"${job.name}\" (export \"${job.exportName}\" in ${sourceFile}) could not be ` +\n `statically detected: createWorkflowJob's \"name\" must be a string literal and \"body\" ` +\n `must be a function expression. Dynamic or computed values (e.g. body: someWrapper(fn)) ` +\n `cannot be bundled and would be silently dropped.`,\n );\n }\n\n const jobDeps = new Set<string>();\n\n for (const call of startCalls) {\n // Check if this start call is inside the job's body\n if (\n call.kind === \"job\" &&\n call.callRange.start >= detectedJob.bodyValueRange.start &&\n call.callRange.end <= detectedJob.bodyValueRange.end\n ) {\n jobDeps.add(call.targetName);\n }\n }\n\n if (jobDeps.size > 0) {\n jobDependencies.push({ jobName: job.name, deps: jobDeps });\n }\n }\n\n for (const call of startCalls) {\n if (call.kind !== \"job\") continue;\n const isInsideAJobBody = detectedJobs.some(\n (detectedJob) =>\n call.callRange.start >= detectedJob.bodyValueRange.start &&\n call.callRange.end <= detectedJob.bodyValueRange.end,\n );\n if (!isInsideAJobBody) {\n throw new WorkflowJobDetectionError(\n `Call to job \"${call.targetName}\".start() in ${sourceFile} is not inside any workflow ` +\n `job's body: it was factored into a function defined outside the calling job's body. ` +\n `Dependency detection only sees .start() calls lexically inside a job body, so this call ` +\n `would silently drop \"${call.targetName}\" from the bundle. Move the call to a function ` +\n `defined inside the calling job's body.`,\n );\n }\n }\n\n return jobDependencies;\n } catch (error) {\n if (error instanceof WorkflowJobDetectionError) throw error;\n // Some other unexpected error (e.g. a file read failure): treat the\n // file as having no dependencies rather than failing the whole build.\n return [];\n }\n }),\n );\n\n // Merge results into dependencies map\n for (const jobDependencies of fileResults) {\n for (const { jobName, deps } of jobDependencies) {\n dependencies.set(jobName, deps);\n }\n }\n\n // Collect all used jobs and per-mainJob dependencies\n const usedJobNames = new Set<string>();\n const mainJobDeps: Record<string, string[]> = {};\n\n function collectDeps(jobName: string, collected: Set<string>) {\n if (collected.has(jobName)) return;\n collected.add(jobName);\n\n // Recursively collect dependencies\n const deps = dependencies.get(jobName);\n if (deps) {\n for (const dep of deps) {\n collectDeps(dep, collected);\n }\n }\n }\n\n // For each mainJob, collect all its dependencies\n for (const mainJobName of mainJobNames) {\n const depsForMainJob = new Set<string>();\n collectDeps(mainJobName, depsForMainJob);\n mainJobDeps[mainJobName] = Array.from(depsForMainJob);\n\n // Add to global used jobs\n for (const dep of depsForMainJob) {\n usedJobNames.add(dep);\n }\n }\n\n // Filter to only used jobs\n const usedJobs = allJobs.filter((job) => usedJobNames.has(job.name));\n return { usedJobs, mainJobDeps };\n}\n\nasync function bundleSingleJob(\n job: JobInfo,\n allJobs: JobInfo[],\n tsconfig: string | undefined,\n env: Record<string, string | number | boolean>,\n startContext: StartContext,\n cache?: BundleCache,\n inlineSourcemap?: boolean,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<[string, string]> {\n const serializedStartContext = serializeStartContext(startContext);\n\n // Include sorted env variables as a prefix so that env changes invalidate the cache\n const sortedEnvPrefix = JSON.stringify(\n Object.fromEntries(Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))),\n );\n const contextHash = computeBundlerContextHash({\n sourceFile: job.sourceFile,\n extraContext: serializedStartContext,\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n prefix: sortedEnvPrefix,\n });\n\n const code = await withCache({\n cache,\n kind: \"workflow-job\",\n name: job.name,\n sourceFile: job.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(job.sourceFile);\n\n const entryContent = ml /* js */ `\n import { ${job.exportName} } from \"${absoluteSourcePath}\";\n\n export async function main(input) {\n const env = ${JSON.stringify(env)};\n const invoker = ${INVOKER_EXPR};\n return await ${job.exportName}.body(input, { env, invoker });\n }\n `;\n const entry = createVirtualEntry(\n `workflow-job:${job.name}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n // Pre-compute once to avoid redundant realpathSync calls per module\n const resolvedSourceFile = safeRealpath(job.sourceFile);\n\n // Step 2: Bundle with a transform plugin that transforms start calls\n // Collect export names for enhanced AST removal (catches jobs missed by AST detection)\n const otherJobExportNames = allJobs\n .filter(\n (candidate) =>\n candidate.name !== job.name &&\n safeRealpath(candidate.sourceFile) === resolvedSourceFile,\n )\n .map((j) => j.exportName);\n\n // Create transform plugin to transform start calls and remove other job declarations\n const transformPlugin: rolldown.Plugin = {\n name: \"workflow-transform\",\n transform: {\n filter: {\n id: {\n include: [/\\.(ts|mts|cts|js|mjs|cjs)$/],\n },\n },\n handler(code, id) {\n // Only transform source files that contain workflow jobs or start calls\n if (\n !code.includes(\"createWorkflowJob\") &&\n !code.includes(\"createWorkflow\") &&\n !hasStartCall(code)\n ) {\n return null;\n }\n\n // Only remove other jobs and the default workflow export from the job's\n // own source file. Dependency files imported by the source file must keep\n // their exports intact for rolldown to resolve cross-file\n // imports (e.g. `import workflow from \"./other-workflow\"`).\n let transformed = code;\n const isJobSourceFile = safeRealpath(id) === resolvedSourceFile;\n if (isJobSourceFile) {\n transformed = transformWorkflowSource(\n code,\n job.name,\n job.exportName,\n otherJobExportNames,\n );\n }\n\n // Apply workflow.start / job.start transformation.\n if (hasStartCall(transformed)) {\n transformed = transformStartCalls(transformed, startContext, id);\n }\n\n if (transformed === code) return null;\n return { code: transformed };\n },\n },\n };\n\n const plugins: rolldown.Plugin[] = [\n entry.plugin,\n transformPlugin,\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n ];\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n assertNoForbiddenRuntimeGlobals(bundledCode, `Workflow job \"${job.name}\"`);\n return bundledCode;\n },\n });\n\n return [job.name, code];\n}\n","import { z } from \"zod\";\nimport { functionSchema } from \"../common\";\n\nexport const WorkflowJobSchema = z.strictObject({\n name: z.string().describe(\"Job name (must be unique across the project)\"),\n start: functionSchema.describe(\"Start function that initiates the job\"),\n body: functionSchema.describe(\"Job implementation function\"),\n publishEvents: z\n .boolean()\n .optional()\n .describe(\"Enable publishing job execution events for this job\"),\n});\n\nconst durationUnits = [\"ms\", \"s\", \"m\"] as const;\n\nconst unitToSeconds: Record<(typeof durationUnits)[number], number> = {\n ms: 1 / 1000,\n s: 1,\n m: 60,\n};\n\nfunction durationToSeconds(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m)$/);\n if (!match) return 0;\n const value = match[1];\n const unit = match[2];\n if (value === undefined || unit === undefined) return 0;\n return parseInt(value, 10) * unitToSeconds[unit as (typeof durationUnits)[number]];\n}\n\nconst baseDurationSchema = z.templateLiteral([z.number().int().positive(), z.enum(durationUnits)]);\n\nconst durationSchema = (maxSeconds: number) =>\n baseDurationSchema.refine((val) => durationToSeconds(val) <= maxSeconds, {\n message: `Duration must be at most ${maxSeconds} seconds`,\n });\n\nexport const RetryPolicySchema = z\n .strictObject({\n maxRetries: z.number().int().min(1).max(10).describe(\"Maximum number of retries (1-10)\"),\n initialBackoff: durationSchema(3600).describe(\n \"Initial backoff duration (e.g., '1s', '500ms', '1m', max 1h)\",\n ),\n maxBackoff: durationSchema(86400).describe(\n \"Maximum backoff duration (e.g., '30s', '5m', max 24h)\",\n ),\n backoffMultiplier: z.number().min(1).describe(\"Backoff multiplier (>= 1)\"),\n })\n\n .refine((data) => durationToSeconds(data.initialBackoff) <= durationToSeconds(data.maxBackoff), {\n message: \"initialBackoff must be less than or equal to maxBackoff\",\n path: [\"initialBackoff\"],\n })\n .refine((data) => durationToSeconds(data.initialBackoff) > 0, {\n message: \"initialBackoff must be greater than 0\",\n path: [\"initialBackoff\"],\n });\n\nexport const ConcurrencyPolicySchema = z.strictObject({\n maxConcurrentExecutions: z\n .number()\n .int()\n .min(1)\n .max(1000)\n .describe(\"Maximum number of concurrent executions (1-1000)\"),\n});\n\nexport const ExecutionPolicyNameSchema = z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/,\n \"Invalid execution policy name: must match [a-z0-9-] (3-63 chars; must start and end with [a-z0-9])\",\n )\n .describe(\"Workspace-unique execution policy name embedded in the resource TRN\");\n\nexport const ExecutionPolicyKeySchema = z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9_:.-]{0,62}[a-z0-9*]$/,\n \"Invalid execution policy key: must match [a-z0-9_:.-] (2-64 chars; must start with [a-z0-9] and end with [a-z0-9] or a trailing '*')\",\n )\n .describe(\"Execution policy key passed to execJobFunction's executionPolicyKey option\");\n\nexport const WorkflowJobFunctionExecutionPolicySchema = z.strictObject({\n name: ExecutionPolicyNameSchema,\n key: ExecutionPolicyKeySchema,\n concurrencyPolicy: ConcurrencyPolicySchema.optional().describe(\n \"Optional per-key concurrency cap for job function dispatches matching this policy\",\n ),\n});\n\nexport const WorkflowSchema = z.strictObject({\n name: z.string().describe(\"Workflow name\"),\n mainJob: WorkflowJobSchema.describe(\"Main job that starts the workflow\"),\n retryPolicy: RetryPolicySchema.optional().describe(\"Retry policy for the workflow\"),\n concurrencyPolicy: ConcurrencyPolicySchema.optional().describe(\n \"Concurrency policy for the workflow\",\n ),\n publishEvents: z\n .boolean()\n .optional()\n .describe(\"Enable publishing workflow execution events for this workflow\"),\n});\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { WorkflowJobSchema, WorkflowSchema } from \"#/parser/service/workflow/index\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport type { WorkflowServiceConfig } from \"#/configure/config/types\";\nimport type { Workflow } from \"#/types/workflow.generated\";\n\nexport interface CollectedJob {\n name: string;\n exportName: string;\n sourceFile: string;\n /** Explicit `publishEvents` from `createWorkflowJob`, when the job set one. */\n publishEvents?: boolean;\n}\n\nfunction stripRuntimeStart(workflow: unknown): unknown {\n if (\n !isSdkBranded(workflow, \"workflow\") ||\n workflow === null ||\n typeof workflow !== \"object\" ||\n !(\"start\" in workflow)\n ) {\n return workflow;\n }\n const { start: _start, ...rest } = workflow as Record<string, unknown>;\n return rest;\n}\n\ninterface WorkflowLoadResult {\n workflows: Record<string, Workflow>;\n workflowSources: Array<{ workflow: Workflow; sourceFile: string }>;\n jobs: CollectedJob[];\n fileCount: number;\n}\n\nexport type WorkflowService = {\n readonly config: WorkflowServiceConfig;\n readonly workflows: Record<string, Workflow>;\n readonly workflowSources: ReadonlyArray<{ workflow: Workflow; sourceFile: string }>;\n readonly jobs: CollectedJob[];\n readonly fileCount: number;\n loadWorkflows: () => Promise<void>;\n printLoadedWorkflows: () => void;\n};\n\n/**\n * Parameters for creating a WorkflowService\n */\nexport interface CreateWorkflowServiceParams {\n /** The workflow service configuration */\n config: WorkflowServiceConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\n/**\n * Creates a new WorkflowService instance.\n * @param params - Parameters for creating the service\n * @returns A new WorkflowService instance\n */\nexport function createWorkflowService(params: CreateWorkflowServiceParams): WorkflowService {\n const { config, baseDir } = params;\n let workflows: Record<string, Workflow> = {};\n let workflowSources: Array<{ workflow: Workflow; sourceFile: string }> = [];\n let jobs: CollectedJob[] = [];\n let fileCount = 0;\n let loaded = false;\n\n return {\n config,\n get workflows() {\n return workflows;\n },\n get workflowSources() {\n return workflowSources;\n },\n get jobs() {\n return jobs;\n },\n get fileCount() {\n return fileCount;\n },\n loadWorkflows: async () => {\n if (loaded) {\n return;\n }\n const result = await loadAndCollectJobs(config, baseDir);\n workflows = result.workflows;\n workflowSources = result.workflowSources;\n jobs = result.jobs;\n fileCount = result.fileCount;\n loaded = true;\n },\n printLoadedWorkflows: () => {\n if (fileCount === 0) {\n return;\n }\n logger.newline();\n logger.log(`Found ${styles.highlight(fileCount.toString())} workflow files`);\n for (const { workflow, sourceFile } of workflowSources) {\n const relativePath = path.relative(process.cwd(), sourceFile);\n logger.log(\n `Workflow: ${styles.successBright(`\"${workflow.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n }\n },\n };\n}\n\n/**\n * Load workflow files and collect all jobs in a single pass.\n * Dependencies are detected at bundle time via AST analysis.\n * @param config - Workflow service configuration\n * @param baseDir - Directory the config's file patterns are resolved against\n * @returns Loaded workflows and collected jobs\n */\nasync function loadAndCollectJobs(\n config: WorkflowServiceConfig,\n baseDir: string,\n): Promise<WorkflowLoadResult> {\n const workflows: Record<string, Workflow> = {};\n const workflowSources: Array<{ workflow: Workflow; sourceFile: string }> = [];\n const collectedJobs: CollectedJob[] = [];\n\n if (config.files.length === 0) {\n return {\n workflows,\n workflowSources,\n jobs: collectedJobs,\n fileCount: 0,\n };\n }\n\n const workflowFiles = loadFilesWithIgnores(config, baseDir);\n const fileCount = workflowFiles.length;\n\n // Maps for collecting data\n const allJobsMap = new Map<string, CollectedJob>();\n\n // Load all files in parallel and collect jobs and workflows\n const loadResults = await Promise.all(\n workflowFiles.map(async (workflowFile) => {\n const { jobs, workflow } = await loadFileContent(workflowFile);\n return { workflowFile, jobs, workflow };\n }),\n );\n\n for (const { workflowFile, jobs, workflow } of loadResults) {\n if (workflow) {\n workflowSources.push({ workflow, sourceFile: workflowFile });\n workflows[workflowFile] = workflow;\n }\n\n for (const job of jobs) {\n const existing = allJobsMap.get(job.name);\n if (existing) {\n throw new Error(\n `Duplicate job name \"${job.name}\" found:\\n` +\n ` - ${existing.sourceFile} (export: ${existing.exportName})\\n` +\n ` - ${job.sourceFile} (export: ${job.exportName})\\n` +\n `Each job must have a unique name.`,\n );\n }\n allJobsMap.set(job.name, job);\n collectedJobs.push(job);\n }\n }\n\n return {\n workflows,\n workflowSources,\n jobs: collectedJobs,\n fileCount,\n };\n}\n\n/**\n * Load a single file and extract jobs and workflow\n * @param filePath - Path to the workflow file\n * @returns Extracted jobs and workflow\n */\nasync function loadFileContent(filePath: string): Promise<{\n jobs: CollectedJob[];\n workflow: Workflow | null;\n}> {\n const jobs: CollectedJob[] = [];\n let workflow: Workflow | null = null;\n\n try {\n const module = await importUserModule(filePath);\n\n for (const [exportName, exportValue] of Object.entries(module)) {\n // Check if it's a workflow (default export)\n if (exportName === \"default\") {\n const workflowResult = WorkflowSchema.safeParse(stripRuntimeStart(exportValue));\n if (workflowResult.success) {\n workflow = workflowResult.data;\n } else if (isSdkBranded(exportValue, [\"workflow\", \"workflow-job\"])) {\n throw workflowResult.error;\n }\n continue;\n }\n\n const jobResult = WorkflowJobSchema.safeParse(exportValue);\n if (jobResult.success) {\n jobs.push({\n name: jobResult.data.name,\n exportName,\n sourceFile: filePath,\n ...(jobResult.data.publishEvents !== undefined\n ? { publishEvents: jobResult.data.publishEvents }\n : {}),\n });\n } else if (isSdkBranded(exportValue, [\"workflow\", \"workflow-job\"])) {\n throw jobResult.error;\n }\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), filePath);\n logger.error(\n `${styles.error(\"Failed to load workflow from\")} ${styles.errorBright(relativePath)}`,\n );\n logger.error(String(error));\n throw error;\n }\n\n return { jobs, workflow };\n}\n","import type { AppConfig } from \"#/configure/config/types\";\n\ntype AuthNamespaceApplication = {\n authService?: { config: { name: string } };\n config?: Pick<AppConfig, \"auth\">;\n};\n\n/**\n * Resolve the auth namespace configured for an application.\n * @param application - Loaded application with local or external Auth config\n * @returns Auth namespace, or undefined when no Auth config is present\n */\nexport function getApplicationAuthNamespace(\n application: AuthNamespaceApplication,\n): string | undefined {\n return application.authService?.config.name ?? application.config?.auth?.name;\n}\n\n/**\n * Resolve the auth namespace configured for an application, throwing when none is configured.\n * @param application - Loaded application with local or external Auth config\n * @returns Auth namespace\n */\nexport function requireApplicationAuthNamespace(application: AuthNamespaceApplication): string {\n const authNamespace = getApplicationAuthNamespace(application);\n if (!authNamespace) {\n throw new Error(\"No Auth service configured\");\n }\n return authNamespace;\n}\n","let distPath: string | null = null;\n\nexport const getDistDir = (): string => {\n const configured = process.env.TAILOR_BUILD_OUTPUT_DIR;\n if (configured && configured !== distPath) {\n distPath = configured;\n } else if (distPath === null) {\n distPath = configured || \".tailor\";\n }\n return distPath;\n};\n","import { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Resolve whether inline sourcemaps should be enabled.\n *\n * Resolution order:\n * 1. Config value (`inlineSourcemap` in defineConfig) — if explicitly set\n * 2. Environment variable `TAILOR_INLINE_SOURCEMAP` — if explicitly set\n * 3. Default: `true`\n * @param configValue - The `inlineSourcemap` value from AppConfig\n * @returns Whether inline sourcemaps should be enabled\n */\nexport function resolveInlineSourcemap(configValue?: boolean): boolean {\n if (configValue !== undefined) return configValue;\n const envValue = parseBoolean(process.env.TAILOR_INLINE_SOURCEMAP);\n if (envValue !== undefined) return envValue;\n return true;\n}\n","export function resolverBundleKey(namespace: string, resolverName: string): string {\n return `${namespace}:${resolverName}`;\n}\n","import { z } from \"zod\";\n\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,28}[a-z0-9]$/;\nconst AUTH_NAMESPACE_PATTERN = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;\n\n// strip unknown keys\nexport const AIGatewaySchema = z.strictObject({\n name: z\n .string()\n .regex(NAME_PATTERN, \"Must be 3-30 lowercase alphanumeric characters or hyphens\")\n .describe(\"AI Gateway name\"),\n authNamespace: z\n .string()\n .regex(AUTH_NAMESPACE_PATTERN, \"Must be 3-63 lowercase alphanumeric characters or hyphens\")\n .optional()\n .describe(\n \"Auth namespace used to resolve request tokens against the workspace's auth. Defaults to the application's own auth service when omitted; omitting it without an Auth service configured is rejected.\",\n ),\n cors: z\n .array(z.string())\n .optional()\n .describe(\n \"Allowed CORS origins for browser-based clients. Each entry is `*`, `http(s)://*`, `http(s)://*.example.com`, or `http(s)://app.example.com`, optionally with `:port`. Empty list disables cross-origin access.\",\n ),\n});\n","import { z } from \"zod\";\n\n/**\n * Normalize IdPGqlOperationsConfig (alias or object) to IdPGqlOperations object.\n * \"query\" alias expands to read-only mode: every mutation is disabled while\n * queries (`read`, `requestMfaSettingsUrl`) stay enabled.\n * @param config - The config to normalize\n * @returns The normalized IdPGqlOperations object\n */\nfunction normalizeIdPGqlOperations(\n config:\n | \"query\"\n | {\n create?: boolean;\n update?: boolean;\n delete?: boolean;\n read?: boolean;\n sendPasswordResetEmail?: boolean;\n requestMfaSettingsUrl?: boolean;\n unenrollMfa?: boolean;\n },\n) {\n if (config === \"query\") {\n return {\n create: false,\n update: false,\n delete: false,\n read: true,\n sendPasswordResetEmail: false,\n requestMfaSettingsUrl: true,\n unenrollMfa: false,\n };\n }\n return config;\n}\n\n/**\n * Zod schema for IdPGqlOperations configuration with normalization transform.\n * Accepts \"query\" alias or detailed object, normalizes to IdPGqlOperations object.\n */\nexport const IdPGqlOperationsSchema = z\n .union([\n z.literal(\"query\"),\n z.strictObject({\n create: z.boolean().optional().describe(\"Enable _createUser mutation (default: true)\"),\n update: z.boolean().optional().describe(\"Enable _updateUser mutation (default: true)\"),\n delete: z.boolean().optional().describe(\"Enable _deleteUser mutation (default: true)\"),\n read: z.boolean().optional().describe(\"Enable _users and _user queries (default: true)\"),\n sendPasswordResetEmail: z\n .boolean()\n .optional()\n .describe(\"Enable _sendPasswordResetEmail mutation (default: true)\"),\n requestMfaSettingsUrl: z\n .boolean()\n .optional()\n .describe(\"Enable _requestMfaSettingsUrl query (default: true)\"),\n unenrollMfa: z.boolean().optional().describe(\"Enable _unenrollMfa mutation (default: true)\"),\n }),\n ])\n .describe(\n \"Configuration for GraphQL operations on IdP users.\\nAll operations are enabled by default (undefined or true = enabled, false = disabled).\",\n )\n .transform((val) => normalizeIdPGqlOperations(val));\n\nexport const IdPLangSchema = z.enum([\"en\", \"ja\"]).describe(\"IdP UI language\");\n\n// Origins are either a literal http(s) origin (scheme + host + optional port,\n// no path/query/fragment) or a static-website `<name>:url` placeholder that\n// the CLI resolves to a real origin at apply time. The placeholder branch\n// uses the same slug rule as the platform's static-website name validator so\n// typos like `https://app.example.com:url` are rejected instead of being\n// silently interpreted as a website name at apply time.\nconst allowedReturnOriginPattern =\n /^(https?:\\/\\/[a-zA-Z0-9.-]+(:[0-9]+)?|[a-z0-9][a-z0-9-]{1,61}[a-z0-9]:url)$/;\n\nexport const IdPUserAuthPolicySchema = z\n .strictObject({\n useNonEmailIdentifier: z\n .boolean()\n .optional()\n .describe(\"Use non-email identifier for usernames\"),\n allowSelfPasswordReset: z\n .boolean()\n .optional()\n .describe(\"Allow users to reset their own passwords\"),\n passwordRequireUppercase: z\n .boolean()\n .optional()\n .describe(\"Require uppercase letters in passwords\"),\n passwordRequireLowercase: z\n .boolean()\n .optional()\n .describe(\"Require lowercase letters in passwords\"),\n passwordRequireNonAlphanumeric: z\n .boolean()\n .optional()\n .describe(\"Require non-alphanumeric characters in passwords\"),\n passwordRequireNumeric: z\n .boolean()\n .optional()\n .describe(\"Require numeric characters in passwords\"),\n passwordMinLength: z\n .number()\n .int()\n .refine((val) => val >= 6 && val <= 30, {\n message: \"passwordMinLength must be between 6 and 30\",\n })\n .optional()\n .describe(\"Minimum password length (6-30)\"),\n passwordMaxLength: z\n .number()\n .int()\n .refine((val) => val >= 6 && val <= 4096, {\n message: \"passwordMaxLength must be between 6 and 4096\",\n })\n .optional()\n .describe(\"Maximum password length (6-4096)\"),\n allowedEmailDomains: z\n .array(z.string())\n .optional()\n .describe(\"Restrict registration to these email domains\"),\n allowGoogleOauth: z.boolean().optional().describe(\"Enable Google OAuth login\"),\n allowMicrosoftOauth: z.boolean().optional().describe(\"Enable Microsoft OAuth login\"),\n disablePasswordAuth: z.boolean().optional().describe(\"Disable password-based authentication\"),\n enableMfa: z\n .boolean()\n .optional()\n .describe(\"Make TOTP MFA available for users in this namespace\"),\n requireMfa: z\n .boolean()\n .optional()\n .describe(\n \"Require TOTP MFA enrollment and challenge for password-authenticated users (requires enableMfa)\",\n ),\n allowedReturnOrigins: z\n .array(\n z\n .string()\n .regex(\n allowedReturnOriginPattern,\n 'must be an http(s) origin like \"https://app.example.com\" (scheme + host + optional port, no path/query/fragment) or a static-website placeholder like \"<name>:url\"',\n ),\n )\n .optional()\n .describe(\n \"Application origins (scheme + host + optional port) allowed as MFA self-service return targets\",\n ),\n mfaIssuer: z\n .string()\n .max(64, \"mfaIssuer must be 64 characters or less\")\n .optional()\n .describe(\"Label shown next to the user account in authenticator apps\"),\n })\n\n .refine(\n (data) =>\n data.passwordMinLength === undefined ||\n data.passwordMaxLength === undefined ||\n data.passwordMinLength <= data.passwordMaxLength,\n {\n message: \"passwordMinLength must be less than or equal to passwordMaxLength\",\n path: [\"passwordMinLength\"],\n },\n )\n .refine(\n (data) =>\n !data.allowedEmailDomains ||\n data.allowedEmailDomains.length === 0 ||\n !data.useNonEmailIdentifier,\n {\n message: \"allowedEmailDomains cannot be set when useNonEmailIdentifier is true\",\n path: [\"allowedEmailDomains\"],\n },\n )\n .refine(\n (data) =>\n data.allowGoogleOauth === undefined ||\n data.allowGoogleOauth === false ||\n !data.useNonEmailIdentifier,\n {\n message: \"allowGoogleOauth cannot be set when useNonEmailIdentifier is true\",\n path: [\"allowGoogleOauth\"],\n },\n )\n .refine(\n (data) =>\n !data.allowGoogleOauth || (data.allowedEmailDomains && data.allowedEmailDomains.length > 0),\n {\n message: \"allowGoogleOauth requires allowedEmailDomains to be set\",\n path: [\"allowGoogleOauth\"],\n },\n )\n .refine((data) => !data.allowMicrosoftOauth || !data.useNonEmailIdentifier, {\n message: \"allowMicrosoftOauth cannot be set when useNonEmailIdentifier is true\",\n path: [\"allowMicrosoftOauth\"],\n })\n .refine(\n (data) =>\n !data.allowMicrosoftOauth ||\n (data.allowedEmailDomains && data.allowedEmailDomains.length > 0),\n {\n message: \"allowMicrosoftOauth requires allowedEmailDomains to be set\",\n path: [\"allowMicrosoftOauth\"],\n },\n )\n .refine((data) => !data.allowMicrosoftOauth || data.disablePasswordAuth === true, {\n message: \"allowMicrosoftOauth requires disablePasswordAuth to be enabled\",\n path: [\"allowMicrosoftOauth\"],\n })\n .refine(\n (data) =>\n !data.disablePasswordAuth ||\n data.allowGoogleOauth === true ||\n data.allowMicrosoftOauth === true,\n {\n message: \"disablePasswordAuth requires allowGoogleOauth or allowMicrosoftOauth to be enabled\",\n path: [\"disablePasswordAuth\"],\n },\n )\n .refine((data) => !data.disablePasswordAuth || !data.allowSelfPasswordReset, {\n message: \"disablePasswordAuth cannot be used with allowSelfPasswordReset\",\n path: [\"disablePasswordAuth\"],\n })\n .refine((data) => !data.requireMfa || data.enableMfa === true, {\n message: \"requireMfa requires enableMfa to be enabled\",\n path: [\"requireMfa\"],\n })\n .refine(\n (data) =>\n !data.enableMfa || (data.allowedReturnOrigins && data.allowedReturnOrigins.length > 0),\n {\n message:\n \"enableMfa requires allowedReturnOrigins to list at least one origin so MFA self-service has a valid return target\",\n path: [\"enableMfa\"],\n },\n );\n\nconst emailFieldSchema = z\n .string()\n .max(200, \"must be 200 characters or less\")\n .regex(/^[^\\r\\n]*$/, \"must not contain newline characters\");\n\nexport const IdPEmailConfigSchema = z\n .strictObject({\n fromName: emailFieldSchema.optional().describe(\"Default sender display name for emails\"),\n passwordResetSubject: emailFieldSchema\n .optional()\n .describe(\"Default subject for password reset emails\"),\n })\n\n .describe(\"Namespace-level email configuration defaults\");\n\nconst IdPPermissionOperandSchema = z.union([\n z.string(),\n z.boolean(),\n z.array(z.string()).readonly(),\n z.array(z.boolean()).readonly(),\n z.strictObject({ user: z.string() }),\n z.strictObject({ idpUser: z.enum([\"id\", \"name\", \"disabled\"]) }),\n z.strictObject({ oldIdpUser: z.enum([\"id\", \"name\", \"disabled\"]) }),\n z.strictObject({ newIdpUser: z.enum([\"id\", \"name\", \"disabled\"]) }),\n]);\n\nconst IdPPermissionOperatorSchema = z.enum([\"=\", \"!=\", \"in\", \"not in\"]);\n\nconst IdPPermissionConditionSchema = z\n .tuple([IdPPermissionOperandSchema, IdPPermissionOperatorSchema, IdPPermissionOperandSchema])\n .readonly();\n\nconst IdPActionPermissionSchema = z.union([\n // Object format: { conditions, description?, permit? }\n z.strictObject({\n conditions: z.union([\n IdPPermissionConditionSchema,\n z.array(IdPPermissionConditionSchema).readonly(),\n ]),\n description: z.string().optional(),\n permit: z.boolean().optional(),\n }),\n // Single condition tuple: [operand, operator, operand]\n z\n .tuple([IdPPermissionOperandSchema, IdPPermissionOperatorSchema, IdPPermissionOperandSchema])\n .readonly(),\n // Single condition tuple with permit: [operand, operator, operand, permit]\n z\n .tuple([\n IdPPermissionOperandSchema,\n IdPPermissionOperatorSchema,\n IdPPermissionOperandSchema,\n z.boolean(),\n ])\n .readonly(),\n // Multiple conditions with optional trailing permit\n z\n .array(z.union([IdPPermissionConditionSchema, z.boolean()]))\n .refine(\n (arr) => {\n const boolIndex = arr.findIndex((item) => typeof item === \"boolean\");\n return boolIndex === -1 || boolIndex === arr.length - 1;\n },\n { message: \"Boolean permit flag must only appear at the end\" },\n )\n .readonly(),\n]);\n\nexport const IdPPermissionSchema = z\n .strictObject({\n create: z.array(IdPActionPermissionSchema).readonly(),\n read: z.array(IdPActionPermissionSchema).readonly(),\n update: z.array(IdPActionPermissionSchema).readonly(),\n delete: z.array(IdPActionPermissionSchema).readonly(),\n sendPasswordResetEmail: z.array(IdPActionPermissionSchema).readonly().optional(),\n unenrollMfa: z.array(IdPActionPermissionSchema).readonly().optional(),\n })\n\n .describe(\"Per-operation permission policies for IdP users\");\n\nexport const IdPSchema = z\n .strictObject({\n name: z.string().describe(\"IdP service name\"),\n authorization: z\n .union([z.literal(\"insecure\"), z.literal(\"loggedIn\"), z.strictObject({ cel: z.string() })])\n .optional()\n .describe(\"Authorization mode for IdP API access\"),\n clients: z.array(z.string()).describe(\"OAuth2 client names that can use this IdP\"),\n lang: IdPLangSchema.optional().describe(\"UI language for IdP pages\"),\n userAuthPolicy: IdPUserAuthPolicySchema.transform((input) =>\n // transform input may be undefined before schema parse\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n IdPUserAuthPolicySchema.parse(input ?? {}),\n )\n .optional()\n .describe(\"User authentication policy configuration\"),\n publishEvents: z.boolean().optional().describe(\"Enable publishing user lifecycle events\"),\n gqlOperations: IdPGqlOperationsSchema.optional().describe(\n \"Configure which GraphQL operations are enabled\",\n ),\n emailConfig: IdPEmailConfigSchema.optional().describe(\n \"Namespace-level email configuration defaults\",\n ),\n permission: IdPPermissionSchema.optional().describe(\n \"Per-operation permission policies for IdP users\",\n ),\n })\n\n .refine(\n (data) =>\n !data.userAuthPolicy?.enableMfa ||\n data.gqlOperations?.unenrollMfa === false ||\n (data.permission !== undefined && data.permission.unenrollMfa !== undefined),\n {\n message:\n \"permission.unenrollMfa must be set explicitly when userAuthPolicy.enableMfa is true (set [{ conditions: [...], permit: true }] to allow, or [] to deny all). permission itself must also be defined. The requirement is only relaxed when gqlOperations.unenrollMfa is false.\",\n path: [\"permission\", \"unenrollMfa\"],\n },\n )\n .refine(\n (data) =>\n !data.permission ||\n data.userAuthPolicy?.disablePasswordAuth === true ||\n data.gqlOperations?.sendPasswordResetEmail === false ||\n data.permission.sendPasswordResetEmail !== undefined,\n {\n message:\n \"permission.sendPasswordResetEmail must be set explicitly when password authentication is enabled (set [{ conditions: [...], permit: true }] to allow, or [] to deny; only optional when userAuthPolicy.disablePasswordAuth is true or gqlOperations.sendPasswordResetEmail is false)\",\n path: [\"permission\", \"sendPasswordResetEmail\"],\n },\n );\n","import { z } from \"zod\";\n\nconst namePattern = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;\nconst nameSchema = z.string().regex(namePattern);\n\nconst secretsVaultSchema = z.record(nameSchema, z.string().nullish());\nexport const SecretsSchema = z.strictObject({\n vaults: z.record(nameSchema, secretsVaultSchema),\n options: z.strictObject({\n ignoreNullishValues: z.boolean(),\n }),\n});\n","import { z } from \"zod\";\n\n// strip unknown keys\nexport const StaticWebsiteSchema = z.strictObject({\n name: z.string().describe(\"Static website name\"),\n description: z.string().optional().describe(\"Static website description\"),\n allowedIpAddresses: z\n .array(z.string())\n .optional()\n .describe(\"IP addresses allowed to access the website\"),\n customDomains: z.array(z.string()).optional().describe(\"Custom domains for the static website\"),\n});\n","import {\n WAIT_POINT_KEY_GRAMMAR as KEY_GRAMMAR,\n WAIT_POINT_KEY_MAX_LENGTH as MAX_KEY_LENGTH,\n WAIT_POINT_KEY_REGEX as KEY_REGEX,\n isWaitPointParamSegment,\n} from \"#/utils/wait-point-key-grammar\";\nimport type { RegisteredWaitPoint } from \"#/utils/wait-point-registry\";\n\nconst LITERAL_SEGMENT_REGEX = /^[a-z0-9]+$/;\nconst PARAM_NAME_REGEX = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Check one declared wait point key against the key rules.\n *\n * The declaration matters: only `createWaitPoints`' `define` receives the key\n * before the type arguments, so only there can TypeScript read the `$params`\n * off the key literal.\n * @param waitPoint - A key as declared, with the declaration it came from\n * @returns The rule the key breaks, or undefined when the key is usable\n */\nexport function checkWaitPointKey(waitPoint: RegisteredWaitPoint): string | undefined {\n const { key, declaredBy } = waitPoint;\n const segments = key.split(\"-\");\n // Excluding bare \"$\" matters here: otherwise a key carrying one would be\n // answered with advice about typing its $params.\n const paramSegments = segments.filter(isWaitPointParamSegment);\n\n if (paramSegments.length > 0 && declaredBy !== \"define\") {\n return declaredBy === \"property\"\n ? `Invalid wait point key \"${key}\": $params cannot come from a property name. Pass the key to define instead, e.g. define.for(\"${key}\")<Payload, Result>().`\n : `Invalid wait point key \"${key}\": createWaitPoint takes its type arguments first, which stops TypeScript inferring the key as a literal, so it cannot type the $params. Declare it through createWaitPoints instead: createWaitPoints((define) => ({ myWaitPoint: define.for(\"${key}\")<Payload, Result>() })).`;\n }\n\n const seen = new Set<string>();\n let literals = 0;\n\n for (const segment of segments) {\n if (segment.startsWith(\"$\")) {\n const name = segment.slice(1);\n if (!PARAM_NAME_REGEX.test(name)) {\n return `Invalid wait point key \"${key}\": \"${segment}\" is not a usable parameter name. Use letters, digits and underscores, starting with a letter or underscore.`;\n }\n if (seen.has(name)) {\n return `Invalid wait point key \"${key}\": parameter \"$${name}\" appears more than once.`;\n }\n seen.add(name);\n continue;\n }\n // An empty segment comes from a run of hyphens, which the key grammar allows\n // inside a key. Leave the placement rules to the whole-key checks below.\n if (segment === \"\") continue;\n if (!LITERAL_SEGMENT_REGEX.test(segment)) {\n return `Invalid wait point key \"${key}\": segment \"${segment}\" may only contain [a-z0-9]. Wait point keys accept ${KEY_GRAMMAR}, with $params standing in for runtime values.`;\n }\n literals += 1;\n }\n\n // Only a key that actually carries $params can be identity-less in this\n // sense; without them, an empty run of segments is a plain grammar failure.\n if (literals === 0 && paramSegments.length > 0) {\n // A key that also sits outside the grammar needs to hear that first:\n // adding the literal this message asks for would leave \"-$id\" broken.\n return key.startsWith(\"-\") || key.endsWith(\"-\")\n ? `Invalid wait point key \"${key}\": must match ${KEY_GRAMMAR}.`\n : `Invalid wait point key \"${key}\": it needs at least one literal segment alongside its $params, otherwise the key carries no identity of its own and can collide with an unrelated wait point.`;\n }\n\n if (paramSegments.length === 0) {\n return KEY_REGEX.test(key)\n ? undefined\n : `Invalid wait point key \"${key}\": must match ${KEY_GRAMMAR}.`;\n }\n\n // Every param value is itself `[a-z0-9]`-bounded, so the shortest instance of\n // the pattern is valid exactly when every instance is.\n const shortest = segments.map((segment) => (segment.startsWith(\"$\") ? \"0\" : segment)).join(\"-\");\n if (shortest.length > MAX_KEY_LENGTH) {\n return `Wait point key \"${key}\" cannot fit in ${MAX_KEY_LENGTH} characters: even single-character parameter values produce ${shortest.length}.`;\n }\n return KEY_REGEX.test(shortest)\n ? undefined\n : `Invalid wait point key \"${key}\": must match ${KEY_GRAMMAR}.`;\n}\n\n/**\n * Check every declared wait point key, reporting each broken rule once.\n * @param waitPoints - The keys declared across the project, as registered\n * @returns One message per distinct declaration that breaks a rule\n */\nexport function collectWaitPointKeyFailures(waitPoints: readonly RegisteredWaitPoint[]): string[] {\n const failures: string[] = [];\n // The declaration is half of what makes a key valid, so the same key\n // declared two ways is two things to check, not one.\n const seen = new Set<string>();\n for (const waitPoint of waitPoints) {\n const identity = `${waitPoint.declaredBy} ${waitPoint.key}`;\n if (seen.has(identity)) continue;\n seen.add(identity);\n const failure = checkWaitPointKey(waitPoint);\n if (failure) failures.push(failure);\n }\n return failures;\n}\n","import * as path from \"pathe\";\nimport { generatePluginExecutorFiles } from \"#/cli/commands/generate/plugin-executor-generator\";\nimport { generatePluginTableFiles } from \"#/cli/commands/generate/plugin-table-generator\";\nimport { bundleAuthHooks } from \"#/cli/services/auth/bundler\";\nimport { createAuthService, type AuthService } from \"#/cli/services/auth/service\";\nimport { bundleExecutors } from \"#/cli/services/executor/bundler\";\nimport { createExecutorService, type ExecutorService } from \"#/cli/services/executor/service\";\nimport {\n bundleHttpAdapters,\n type HttpAdapterBundleResult,\n} from \"#/cli/services/http-adapter/bundler\";\nimport {\n createHttpAdapterService,\n type HttpAdapterService,\n} from \"#/cli/services/http-adapter/service\";\nimport { bundleResolvers } from \"#/cli/services/resolver/bundler\";\nimport { createResolverService, type ResolverService } from \"#/cli/services/resolver/service\";\nimport { createTailorDBService, type TailorDBService } from \"#/cli/services/tailordb/service\";\nimport { assertUniqueLocalTailorDBTypeNames } from \"#/cli/services/tailordb/type-name-validation\";\nimport { bundleWorkflowJobs, type BundleWorkflowJobsResult } from \"#/cli/services/workflow/bundler\";\nimport { createWorkflowService, type WorkflowService } from \"#/cli/services/workflow/service\";\nimport { getApplicationAuthNamespace } from \"#/cli/shared/auth-namespace\";\nimport { resolveBundleLogLevel } from \"#/cli/shared/bundle-log-level\";\nimport { type LoadedConfig } from \"#/cli/shared/config-loader\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { resolveInlineSourcemap } from \"#/cli/shared/inline-sourcemap\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { resolverBundleKey } from \"#/cli/shared/resolver-bundle-key\";\nimport { buildStartContext } from \"#/cli/shared/start-context\";\nimport { createTsconfigLookupCache } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport {\n type AppConfig,\n type ExecutorServiceInput,\n type HttpAdapterServiceInput,\n type ResolverServiceInput,\n type WorkflowServiceConfig,\n} from \"#/configure/config/types\";\nimport { type AuthConfig } from \"#/configure/services/auth/types\";\nimport { type IdPConfig, type IdPOwnConfig } from \"#/configure/services/idp/types\";\nimport { AIGatewaySchema } from \"#/parser/service/aigateway/index\";\nimport { AuthConfigSchema } from \"#/parser/service/auth/index\";\nimport { IdPSchema } from \"#/parser/service/idp/index\";\nimport { SecretsSchema } from \"#/parser/service/secrets/index\";\nimport { StaticWebsiteSchema } from \"#/parser/service/staticwebsite/index\";\nimport { TailorDBServiceConfigSchema } from \"#/parser/service/tailordb/index\";\nimport { collectWaitPointKeyFailures } from \"#/parser/service/workflow/wait-point-key\";\nimport { getScopedWaitPoints } from \"#/utils/wait-point-registry\";\nimport type { BundleCache } from \"#/cli/cache/bundle-cache\";\nimport type { BundledScripts } from \"#/cli/commands/deploy/function-registry-types\";\nimport type { TailorDBServiceInput } from \"#/configure/services/tailordb/types\";\nimport type { PluginManager } from \"#/plugin/manager\";\nimport type { AIGateway, AIGatewayInput } from \"#/types/aigateway.generated\";\nimport type { IdP } from \"#/types/idp.generated\";\nimport type { StaticWebsite, StaticWebsiteInput } from \"#/types/staticwebsite.generated\";\n\ntype SecretVault = {\n readonly vaultName: string;\n readonly secrets: ReadonlyArray<{ name: string; value: string | null | undefined }>;\n};\n\nexport type Application = {\n readonly name: string;\n readonly id: string | undefined;\n readonly config: AppConfig;\n readonly subgraphs: ReadonlyArray<{ Type: string; Name: string }>;\n readonly tailorDBServices: ReadonlyArray<TailorDBService>;\n readonly externalTailorDBNamespaces: ReadonlyArray<string>;\n readonly resolverServices: ReadonlyArray<ResolverService>;\n readonly idpServices: ReadonlyArray<IdP>;\n readonly authService: Readonly<AuthService> | undefined;\n readonly executorService: Readonly<ExecutorService> | undefined;\n readonly workflowService: Readonly<WorkflowService> | undefined;\n readonly httpAdapterService: Readonly<HttpAdapterService> | undefined;\n readonly staticWebsiteServices: ReadonlyArray<StaticWebsite>;\n readonly aiGatewayServices: ReadonlyArray<AIGateway>;\n readonly secrets: ReadonlyArray<SecretVault>;\n readonly ignoreNullishValues: boolean;\n readonly env: Readonly<Record<string, string | number | boolean>>;\n readonly applications: ReadonlyArray<Application>;\n};\n\n/**\n * Result of loading the application\n */\nexport interface LoadApplicationResult {\n /** Fully initialized application */\n application: Application;\n /** Workflow bundling result (if workflows were bundled) */\n workflowBuildResult?: BundleWorkflowJobsResult;\n /** HTTP adapter bundling result (if adapters were bundled) */\n httpAdapterBuildResult?: HttpAdapterBundleResult;\n /** In-memory bundled scripts organized by kind */\n bundledScripts: BundledScripts;\n}\n\ntype DefineTailorDBResult = {\n tailorDBServices: TailorDBService[];\n externalTailorDBNamespaces: string[];\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction defineTailorDB(\n config: TailorDBServiceInput | undefined,\n baseDir: string,\n pluginManager?: PluginManager,\n): DefineTailorDBResult {\n const tailorDBServices: TailorDBService[] = [];\n const externalTailorDBNamespaces: string[] = [];\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { tailorDBServices, externalTailorDBNamespaces, subgraphs };\n }\n\n for (const [namespace, serviceConfig] of Object.entries(config)) {\n if (\"external\" in serviceConfig) {\n externalTailorDBNamespaces.push(namespace);\n } else {\n // Parse config through schema to normalize gqlOperations\n const parsedConfig = TailorDBServiceConfigSchema.parse(serviceConfig);\n const tailorDB = createTailorDBService({\n namespace,\n config: parsedConfig,\n pluginManager,\n baseDir,\n });\n tailorDBServices.push(tailorDB);\n }\n subgraphs.push({ Type: \"tailordb\", Name: namespace });\n }\n\n return { tailorDBServices, externalTailorDBNamespaces, subgraphs };\n}\n\ntype DefineResolverResult = {\n resolverServices: ResolverService[];\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction defineResolver(\n config: ResolverServiceInput | undefined,\n baseDir: string,\n): DefineResolverResult {\n const resolverServices: ResolverService[] = [];\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { resolverServices, subgraphs };\n }\n\n for (const [namespace, serviceConfig] of Object.entries(config)) {\n if (!(\"external\" in serviceConfig)) {\n const resolverService = createResolverService(namespace, serviceConfig, baseDir);\n resolverServices.push(resolverService);\n }\n subgraphs.push({ Type: \"pipeline\", Name: namespace });\n }\n\n return { resolverServices, subgraphs };\n}\n\ntype DefineIdpResult = {\n idpServices: IdP[];\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction stripIdpProviderHelper(idpConfig: IdPOwnConfig): IdPOwnConfig {\n const configWithProvider = idpConfig as IdPOwnConfig & { provider?: unknown };\n if (typeof configWithProvider.provider !== \"function\") return idpConfig;\n const { provider: _provider, ...config } = configWithProvider;\n return config;\n}\n\nfunction defineIdp(config: readonly IdPConfig[] | undefined): DefineIdpResult {\n const idpServices: IdP[] = [];\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { idpServices, subgraphs };\n }\n\n const idpNames = new Set<string>();\n config.forEach((idpConfig) => {\n const name = idpConfig.name;\n if (idpNames.has(name)) {\n throw new Error(`IdP with name \"${name}\" already defined.`);\n }\n idpNames.add(name);\n if (!(\"external\" in idpConfig)) {\n const idp = IdPSchema.parse(stripIdpProviderHelper(idpConfig));\n idpServices.push(idp);\n }\n subgraphs.push({ Type: \"idp\", Name: name });\n });\n\n return { idpServices, subgraphs };\n}\n\ntype DefineAuthResult = {\n authService: AuthService | undefined;\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction defineAuth(\n config: AuthConfig | undefined,\n tailorDBServices: ReadonlyArray<TailorDBService>,\n externalTailorDBNamespaces: ReadonlyArray<string>,\n): DefineAuthResult {\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { authService: undefined, subgraphs };\n }\n\n let authService: AuthService | undefined;\n if (!(\"external\" in config)) {\n authService = createAuthService(\n AuthConfigSchema.parse(config),\n tailorDBServices,\n externalTailorDBNamespaces,\n );\n }\n subgraphs.push({ Type: \"auth\", Name: config.name });\n\n return { authService, subgraphs };\n}\n\nfunction defineExecutor(\n config: ExecutorServiceInput | undefined,\n baseDir: string,\n hasPluginExecutors: boolean,\n): ExecutorService | undefined {\n if (!config && !hasPluginExecutors) {\n return undefined;\n }\n return createExecutorService({ config: config ?? { files: [] }, baseDir });\n}\n\nfunction defineWorkflow(\n config: WorkflowServiceConfig | undefined,\n baseDir: string,\n): WorkflowService | undefined {\n if (!config) {\n return undefined;\n }\n return createWorkflowService({ config, baseDir });\n}\n\nfunction defineHttpAdapterService(\n config: HttpAdapterServiceInput | undefined,\n baseDir: string,\n): HttpAdapterService | undefined {\n if (!config) {\n return undefined;\n }\n return createHttpAdapterService({ config, baseDir });\n}\n\nfunction stripStaticWebsiteUrlHelper(config: StaticWebsiteInput): StaticWebsiteInput {\n const configWithUrl = config as StaticWebsiteInput & { url?: unknown };\n if (configWithUrl.url !== `${config.name}:url`) return config;\n const { url: _url, ...websiteConfig } = configWithUrl;\n return websiteConfig;\n}\n\nfunction defineStaticWebsites(\n websites: readonly StaticWebsiteInput[] | undefined,\n): StaticWebsite[] {\n const staticWebsiteServices: StaticWebsite[] = [];\n const websiteNames = new Set<string>();\n\n (websites ?? []).forEach((config) => {\n const website = StaticWebsiteSchema.parse(stripStaticWebsiteUrlHelper(config));\n if (websiteNames.has(website.name)) {\n throw new Error(`Static website with name \"${website.name}\" already defined.`);\n }\n websiteNames.add(website.name);\n staticWebsiteServices.push(website);\n });\n\n return staticWebsiteServices;\n}\n\nfunction defineAIGateways(\n gateways: readonly AIGatewayInput[] | undefined,\n applicationAuthNamespace: string | undefined,\n): AIGateway[] {\n const aiGatewayServices: AIGateway[] = [];\n const gatewayNames = new Set<string>();\n\n (gateways ?? []).forEach((config) => {\n const gateway = AIGatewaySchema.parse(config);\n if (gatewayNames.has(gateway.name)) {\n throw new Error(`AI Gateway with name \"${gateway.name}\" already defined.`);\n }\n gatewayNames.add(gateway.name);\n if (gateway.authNamespace === undefined) {\n if (!applicationAuthNamespace) {\n throw new Error(\n `AI Gateway \"${gateway.name}\" has no \"authNamespace\" and no Auth service is configured ` +\n `to default to. Define an Auth service, or set \"authNamespace\" explicitly.`,\n );\n }\n gateway.authNamespace = applicationAuthNamespace;\n }\n aiGatewayServices.push(gateway);\n });\n\n return aiGatewayServices;\n}\n\nfunction parseSecretManager(config: AppConfig[\"secrets\"]): {\n secrets: SecretVault[];\n ignoreNullishValues: boolean;\n} {\n if (!config) {\n return { secrets: [], ignoreNullishValues: false };\n }\n\n const parsed = SecretsSchema.parse(config);\n const { ignoreNullishValues } = parsed.options;\n\n const secrets = Object.entries(parsed.vaults).map(([vaultName, vaultSecrets]) => ({\n vaultName,\n secrets: Object.entries(vaultSecrets).map(([name, value]) => ({ name, value })),\n }));\n\n // Defensive check: error if nullish values exist without ignoreNullishValues\n if (!ignoreNullishValues) {\n for (const vault of secrets) {\n for (const secret of vault.secrets) {\n if (secret.value == null) {\n throw new Error(\n `Secret \"${vault.vaultName}/${secret.name}\" has no value. ` +\n `Use { ignoreNullishValues: true } option in defineSecretManager() to skip secrets without values.`,\n );\n }\n }\n }\n }\n\n return { secrets, ignoreNullishValues };\n}\n\ntype DefineServicesResult = {\n tailordbResult: DefineTailorDBResult;\n resolverResult: DefineResolverResult;\n idpResult: DefineIdpResult;\n authResult: DefineAuthResult;\n staticWebsiteServices: StaticWebsite[];\n aiGatewayServices: AIGateway[];\n secrets: SecretVault[];\n ignoreNullishValues: boolean;\n};\n\nfunction defineServices(\n config: AppConfig,\n baseDir: string,\n pluginManager?: PluginManager,\n): DefineServicesResult {\n const tailordbResult = defineTailorDB(config.db, baseDir, pluginManager);\n const resolverResult = defineResolver(config.resolver, baseDir);\n const idpResult = defineIdp(config.idp);\n const authResult = defineAuth(\n config.auth,\n tailordbResult.tailorDBServices,\n tailordbResult.externalTailorDBNamespaces,\n );\n const staticWebsiteServices = defineStaticWebsites(config.staticWebsites);\n const aiGatewayServices = defineAIGateways(\n config.aiGateways,\n getApplicationAuthNamespace({ authService: authResult.authService, config }),\n );\n const { secrets, ignoreNullishValues } = parseSecretManager(config.secrets);\n return {\n tailordbResult,\n resolverResult,\n idpResult,\n authResult,\n staticWebsiteServices,\n aiGatewayServices,\n secrets,\n ignoreNullishValues: ignoreNullishValues,\n };\n}\n\nfunction buildApplication(params: {\n config: AppConfig;\n tailordbResult: DefineTailorDBResult;\n resolverResult: DefineResolverResult;\n idpResult: DefineIdpResult;\n authResult: DefineAuthResult;\n executorService: ExecutorService | undefined;\n workflowService: WorkflowService | undefined;\n httpAdapterService: HttpAdapterService | undefined;\n staticWebsiteServices: StaticWebsite[];\n aiGatewayServices: AIGateway[];\n secrets: SecretVault[];\n ignoreNullishValues: boolean;\n env: Record<string, string | number | boolean>;\n}): Application {\n const application: Application = {\n name: params.config.name,\n id: params.config.id,\n config: params.config,\n subgraphs: [\n ...params.tailordbResult.subgraphs,\n ...params.resolverResult.subgraphs,\n ...params.idpResult.subgraphs,\n ...params.authResult.subgraphs,\n ],\n tailorDBServices: params.tailordbResult.tailorDBServices,\n externalTailorDBNamespaces: params.tailordbResult.externalTailorDBNamespaces,\n resolverServices: params.resolverResult.resolverServices,\n idpServices: params.idpResult.idpServices,\n authService: params.authResult.authService,\n executorService: params.executorService,\n workflowService: params.workflowService,\n httpAdapterService: params.httpAdapterService,\n staticWebsiteServices: params.staticWebsiteServices,\n aiGatewayServices: params.aiGatewayServices,\n secrets: params.secrets,\n ignoreNullishValues: params.ignoreNullishValues,\n env: params.env,\n get applications() {\n return [application];\n },\n };\n return application;\n}\n\n/**\n * Parameters for defining an application\n */\nexport interface DefineApplicationParams {\n /** Application configuration object (must be loaded via loadConfig) */\n config: LoadedConfig;\n /** Plugin manager for processing plugins */\n pluginManager?: PluginManager;\n /** Optional bundle cache for skipping unchanged builds */\n bundleCache?: BundleCache;\n}\n\n/**\n * Define a Tailor application from the given configuration.\n * This is a lightweight, synchronous function that creates the application\n * structure without loading tables or bundling files.\n * @param params - Parameters for defining the application\n * @returns Configured application instance\n */\nexport function defineApplication(params: DefineApplicationParams): Application {\n const { config, pluginManager } = params;\n const baseDir = path.dirname(config.path);\n const services = defineServices(config, baseDir, pluginManager);\n // Plugin executors are not known at define-time; generate/apply flows handle them after table loading.\n const executorService = defineExecutor(config.executor, baseDir, false);\n const workflowService = defineWorkflow(config.workflow, baseDir);\n const httpAdapterService = defineHttpAdapterService(config.httpAdapter, baseDir);\n\n return buildApplication({\n config,\n ...services,\n executorService,\n workflowService,\n httpAdapterService,\n env: config.env ?? {},\n });\n}\n\n/**\n * Generate plugin table and executor files if a plugin manager is provided.\n * Collects source table info from TailorDB services and delegates to PluginManager.\n * @param pluginManager - Plugin manager instance (skips if undefined)\n * @param tailorDBServices - TailorDB services to collect table source info from\n * @param configPath - Path to tailor.config.ts for resolving plugin imports\n * @returns Generated executor file paths\n */\nexport function generatePluginFilesIfNeeded(\n pluginManager: PluginManager | undefined,\n tailorDBServices: ReadonlyArray<TailorDBService>,\n configPath: string,\n): string[] {\n if (!pluginManager) return [];\n\n const sourceTableInfoMap = new Map<string, { filePath: string; exportName: string }>();\n for (const db of tailorDBServices) {\n const tableSourceInfo = db.typeSourceInfo;\n for (const [tableName, sourceInfo] of Object.entries(tableSourceInfo)) {\n if (sourceInfo.filePath) {\n sourceTableInfoMap.set(tableName, {\n filePath: sourceInfo.filePath,\n exportName: sourceInfo.exportName,\n });\n }\n }\n }\n\n return pluginManager.generatePluginFiles({\n outputDir: path.join(getDistDir(), \"plugin\"),\n sourceTableInfoMap,\n configPath,\n tableGenerator: generatePluginTableFiles,\n executorGenerator: generatePluginExecutorFiles,\n });\n}\n\nfunction assertWaitPointKeys(): void {\n const failures = collectWaitPointKeyFailures(getScopedWaitPoints());\n if (failures.length === 0) return;\n throw new Error(failures.join(\"\\n\"));\n}\n\n/**\n * Load and fully initialize a Tailor application.\n * This performs all I/O-heavy operations: loading tables, processing plugins,\n * generating plugin files, bundling, and loading definitions for validation.\n * @param params - Parameters for defining and loading the application\n * @returns Fully initialized application with workflow results\n */\nexport async function loadApplication(\n params: DefineApplicationParams,\n): Promise<LoadApplicationResult> {\n const { config, pluginManager, bundleCache } = params;\n const baseDir = path.dirname(config.path);\n\n // 1. Define services (synchronous)\n const {\n tailordbResult,\n resolverResult,\n idpResult,\n authResult,\n staticWebsiteServices,\n aiGatewayServices,\n secrets,\n ignoreNullishValues,\n } = defineServices(config, baseDir, pluginManager);\n\n // 2. Load TailorDB tables and process namespace plugins\n for (const tailordb of tailordbResult.tailorDBServices) {\n await tailordb.loadTypes();\n await tailordb.processNamespacePlugins();\n }\n assertUniqueLocalTailorDBTypeNames({\n tailorDBServices: tailordbResult.tailorDBServices,\n });\n\n // 3. Generate plugin files and determine executor file paths\n const pluginExecutorFiles = generatePluginFilesIfNeeded(\n pluginManager,\n tailordbResult.tailorDBServices,\n config.path,\n );\n\n // 4. Determine final executorService (const, no reassignment)\n const executorService = defineExecutor(config.executor, baseDir, pluginExecutorFiles.length > 0);\n\n // 5. Load and collect workflows\n const workflowService = defineWorkflow(config.workflow, baseDir);\n if (workflowService) {\n await workflowService.loadWorkflows();\n }\n\n // 6. Load and collect HTTP adapters\n const httpAdapterService = defineHttpAdapterService(config.httpAdapter, baseDir);\n if (httpAdapterService) {\n await httpAdapterService.loadAdapters();\n }\n\n // 7. Build start context for workflow/job start transformation\n const startContext = await buildStartContext(\n config.workflow,\n getApplicationAuthNamespace({ authService: authResult.authService, config }),\n baseDir,\n );\n\n // 8. Resolve bundle settings\n const inlineSourcemap = resolveInlineSourcemap(config.inlineSourcemap);\n const bundleLogLevel = resolveBundleLogLevel(config.logLevel);\n // Shared across every bundle below so a project with many resolvers/executors/etc.\n // reads and parses each ancestor tsconfig once instead of once per item.\n const tsconfigCache = createTsconfigLookupCache();\n\n // Collect in-memory bundled scripts\n const bundledScripts: BundledScripts = {\n resolvers: new Map(),\n executors: new Map(),\n workflowJobs: new Map(),\n authHooks: new Map(),\n };\n\n // 9. Bundle resolvers\n for (const pipeline of resolverResult.resolverServices) {\n const resolverBundles = await bundleResolvers({\n namespace: pipeline.namespace,\n config: pipeline.config,\n baseDir,\n defaultPermission: pipeline.defaultPermission,\n startContext,\n cache: bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n });\n for (const [name, code] of resolverBundles) {\n bundledScripts.resolvers.set(resolverBundleKey(pipeline.namespace, name), code);\n }\n }\n\n // 10. Bundle executors\n if (executorService) {\n bundledScripts.executors = await bundleExecutors({\n config: executorService.config,\n startContext,\n additionalFiles: [...pluginExecutorFiles],\n cache: bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n baseDir,\n tsconfigCache,\n });\n }\n\n // 11. Bundle workflows\n let workflowBuildResult: BundleWorkflowJobsResult | undefined;\n if (workflowService && workflowService.jobs.length > 0) {\n const mainJobNames = workflowService.workflowSources.map((ws) => ws.workflow.mainJob.name);\n workflowBuildResult = await bundleWorkflowJobs(\n workflowService.jobs,\n mainJobNames,\n config.env ?? {},\n startContext,\n baseDir,\n bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n );\n bundledScripts.workflowJobs = workflowBuildResult.bundledCode;\n }\n\n // 12. Bundle HTTP adapters\n let httpAdapterBuildResult: HttpAdapterBundleResult | undefined;\n if (httpAdapterService && httpAdapterService.adapters.length > 0) {\n httpAdapterBuildResult = await bundleHttpAdapters(\n httpAdapterService.adapters.map((a) => ({\n name: a.adapter.name,\n sourceFile: a.sourceFile,\n methods: a.methods,\n hasOutput: a.hasOutput,\n })),\n baseDir,\n bundleCache,\n bundleLogLevel,\n tsconfigCache,\n );\n }\n\n // 13. Bundle auth hooks\n if (authResult.authService?.config.hooks?.beforeLogin) {\n const authName = authResult.authService.config.name;\n bundledScripts.authHooks = await bundleAuthHooks({\n configPath: config.path,\n authName,\n handlerAccessPath: `auth.hooks.beforeLogin.handler`,\n env: config.env ?? {},\n startContext,\n cache: bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n baseDir,\n tsconfigCache,\n });\n }\n\n // 14. Load resolver and executor definitions (for validation/logging)\n for (const pipeline of resolverResult.resolverServices) {\n await pipeline.loadResolvers();\n }\n if (executorService) {\n await executorService.loadExecutors();\n if (pluginExecutorFiles.length > 0) {\n await executorService.loadPluginExecutorFiles([...pluginExecutorFiles]);\n }\n }\n // 15. Check the wait point keys every loaded module declared\n assertWaitPointKeys();\n\n if (workflowService) {\n workflowService.printLoadedWorkflows();\n }\n if (httpAdapterService) {\n httpAdapterService.printLoadedAdapters();\n }\n logger.newline();\n\n // 16. Build immutable Application\n const application = buildApplication({\n config,\n tailordbResult,\n resolverResult,\n idpResult,\n authResult,\n executorService,\n workflowService,\n httpAdapterService,\n staticWebsiteServices,\n aiGatewayServices,\n secrets,\n ignoreNullishValues,\n env: config.env ?? {},\n });\n\n return { application, workflowBuildResult, httpAdapterBuildResult, bundledScripts };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"application-D3HlhR3i.mjs","names":["sanitizePluginId","toCamelCase","toKebabCase","importExpr","callExpr","callExpr","callExpr","CLIError","exportDecl","CLIError","NAME_PATTERN","KEY_GRAMMAR","KEY_REGEX"],"sources":["../src/parser/app-config/log-level.ts","../src/cli/shared/parse-positive-int.ts","../src/cli/shared/apply-concurrency.ts","../src/cli/shared/client.ts","../src/cli/shared/plugin-import.ts","../src/plugin/guards.ts","../src/cli/commands/generate/plugin-executor-generator.ts","../src/cli/commands/generate/plugin-table-generator.ts","../src/cli/cache/dep-collector-plugin.ts","../src/cli/cache/hasher.ts","../src/cli/cache/bundle-cache.ts","../src/cli/services/workflow/ast-utils.ts","../src/cli/services/workflow/sdk-binding-collector.ts","../src/cli/services/workflow/job-detector.ts","../src/cli/services/workflow/workflow-detector.ts","../src/cli/shared/start-context.ts","../src/cli/services/workflow/start-transformer.ts","../src/cli/shared/bundle-log.ts","../src/cli/shared/bundle-log-level.ts","../src/cli/shared/function-treeshake.ts","../src/cli/shared/platform-bundle-plugin.ts","../src/cli/shared/resolve-tsconfig.ts","../src/cli/shared/tsconfig-paths-plugin.ts","../src/cli/shared/virtual-entry.ts","../src/cli/services/auth/bundler.ts","../src/utils/script-expr.ts","../src/parser/service/tailordb/hook-args-object.ts","../src/parser/service/tailordb/hooks-validate-precompiled-expr.ts","../src/parser/service/tailordb/field.ts","../src/parser/service/permission.ts","../src/parser/service/tailordb/permission.ts","../src/parser/service/tailordb/type-parser.ts","../src/cli/shared/free-variables.ts","../src/cli/services/tailordb/hooks-validate-bundler.ts","../src/cli/services/tailordb/type-name-validation.ts","../src/cli/services/tailordb/service.ts","../src/cli/services/auth/service.ts","../src/cli/shared/bundle-concurrency.ts","../src/cli/shared/forbidden-runtime-globals.ts","../src/cli/shared/runtime-exprs.ts","../src/cli/services/executor/bundler.ts","../src/parser/service/http-adapter/methods.ts","../src/parser/service/http-adapter/schema.ts","../src/cli/services/http-adapter/bundler.ts","../src/cli/services/http-adapter/service.ts","../src/parser/service/resolver/schema.ts","../src/cli/services/resolver/loader.ts","../src/cli/services/resolver/bundler.ts","../src/cli/services/resolver/default-permission.ts","../src/cli/services/resolver/service.ts","../src/cli/services/workflow/source-transformer.ts","../src/cli/services/workflow/bundler.ts","../src/parser/service/workflow/schema.ts","../src/cli/services/workflow/service.ts","../src/cli/shared/auth-namespace.ts","../src/cli/shared/dist-dir.ts","../src/cli/shared/inline-sourcemap.ts","../src/cli/shared/resolver-bundle-key.ts","../src/parser/service/aigateway/schema.ts","../src/parser/service/idp/schema.ts","../src/parser/service/secrets/schema.ts","../src/parser/service/staticwebsite/schema.ts","../src/parser/service/workflow/wait-point-key.ts","../src/cli/services/application.ts"],"sourcesContent":["export const LOG_LEVELS = [\"DEBUG\", \"INFO\", \"WARN\", \"ERROR\", \"SILENT\"] as const;\n\nexport function isLogLevel(value: string): value is (typeof LOG_LEVELS)[number] {\n return (LOG_LEVELS as readonly string[]).includes(value);\n}\n","const POSITIVE_INT_PATTERN = /^\\d*[1-9]\\d*$/;\n\n/**\n * Parse a string value as a positive integer.\n *\n * Only decimal digits are accepted (leading zeros allowed), so `0`, negative\n * numbers, decimals, exponent notation, and signed values are all rejected.\n * Values above `Number.MAX_SAFE_INTEGER` are rejected too: past that point the\n * parsed number no longer represents the digits it came from, so it cannot\n * describe a meaningful limit.\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns The parsed integer, or `undefined` when the value is unset or unrecognized\n */\nexport function parsePositiveInt(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim();\n if (!POSITIVE_INT_PATTERN.test(normalized)) return undefined;\n const parsed = Number.parseInt(normalized, 10);\n return Number.isSafeInteger(parsed) ? parsed : undefined;\n}\n","import pLimit from \"p-limit\";\nimport { parsePositiveInt } from \"./parse-positive-int\";\n\n/**\n * Default cap on concurrent operator RPCs when `TAILOR_APPLY_CONCURRENCY` is\n * unset. Chosen to tame the create burst (a fresh workspace fires one\n * `create*` per resource at once) that triggers the platform-side\n * `already_exists` race on compound creates, while still deploying quickly.\n */\nconst DEFAULT_APPLY_CONCURRENCY = 16;\n\n/**\n * Resolve the maximum number of operator RPCs to run in parallel.\n *\n * Resolution order:\n * 1. `TAILOR_APPLY_CONCURRENCY` env var (positive integer)\n * 2. `DEFAULT_APPLY_CONCURRENCY`\n *\n * A fresh-workspace apply creates every resource at once; firing all of them\n * concurrently overloads the platform, whose responses then come back as\n * `Unavailable`/`ResourceExhausted` and drive retries into the non-idempotent\n * compound-create `already_exists` race. Capping bounds the worst case.\n * @returns Concurrency cap (always >= 1)\n */\nexport function resolveApplyConcurrency(): number {\n return parsePositiveInt(process.env.TAILOR_APPLY_CONCURRENCY) ?? DEFAULT_APPLY_CONCURRENCY;\n}\n\n/**\n * Create a limiter capped at the resolved apply concurrency. The returned\n * function defers a task until a slot is free, then resolves with its result.\n *\n * Share a single instance across all RPCs that should contend for the same\n * budget (e.g. one per operator client) so the cap bounds total in-flight\n * calls, not per-call-site bursts.\n * @returns A limiter that defers tasks beyond the concurrency cap\n */\nexport function createApplyLimiter(): <R>(task: () => Promise<R>) => Promise<R> {\n return pLimit(resolveApplyConcurrency());\n}\n\n/**\n * Comparator that orders `name`-bearing items by `name`, for a stable,\n * reproducible apply order within the concurrency cap.\n *\n * Uses a code-point comparison rather than `localeCompare` so the order does\n * not depend on the runtime's default locale/collation.\n * @param a - Left item\n * @param b - Right item\n * @returns Negative, zero, or positive per code-point ordering of the names\n */\nexport function byName(a: { name: string }, b: { name: string }): number {\n if (a.name < b.name) return -1;\n if (a.name > b.name) return 1;\n return 0;\n}\n","import { OAuth2Client } from \"@badgateway/oauth2-client\";\nimport { create } from \"@bufbuild/protobuf\";\nimport { MethodOptions_IdempotencyLevel } from \"@bufbuild/protobuf/wkt\";\nimport {\n type Client,\n Code,\n ConnectError,\n createClient,\n type Interceptor,\n type Transport,\n type UnaryResponse,\n} from \"@connectrpc/connect\";\nimport { z } from \"zod\";\nimport { createApplyLimiter } from \"./apply-concurrency\";\nimport { logger } from \"./logger\";\nimport { parseBoolean } from \"./parse-boolean\";\nimport { userAgent } from \"./user-agent\";\nimport type { OperatorService } from \"@tailor-platform/tailor-proto/service_pb\";\n\nexport const defaultPlatformBaseUrl = \"https://api.tailor.tech\";\nexport const defaultConsoleBaseUrl = \"https://console.tailor.tech\";\n\nconst defaultOAuth2ClientId = \"cpoc_0Iudir72fqSpqC6GQ58ri1cLAqcq5vJl\";\nconst oauth2DiscoveryEndpoint = \"/.well-known/oauth-authorization-server/oauth2/platform\";\n\nexport type PlatformClientConfig = {\n platformUrl?: string;\n oauth2ClientId?: string;\n consoleUrl?: string;\n};\n\nconst tokenPlatformConfigs = new Map<string, PlatformClientConfig>();\n\nfunction getEnvPlatformUrl(): string | undefined {\n return process.env.TAILOR_PLATFORM_URL ?? process.env.PLATFORM_URL;\n}\n\nfunction getEnvOAuth2ClientId(): string | undefined {\n return process.env.TAILOR_PLATFORM_OAUTH2_CLIENT_ID ?? process.env.PLATFORM_OAUTH2_CLIENT_ID;\n}\n\nexport function normalizeBaseUrl(value: string): string {\n const url = new URL(value);\n url.hash = \"\";\n url.search = \"\";\n return url.toString().replace(/\\/$/, \"\");\n}\n\nexport function getEffectivePlatformConfig(config: PlatformClientConfig = {}) {\n const platformUrl = config.platformUrl ?? getEnvPlatformUrl();\n const oauth2ClientId = config.oauth2ClientId ?? getEnvOAuth2ClientId();\n const consoleUrl = config.consoleUrl ?? process.env.TAILOR_PLATFORM_CONSOLE_URL;\n const effective = {\n ...(platformUrl ? { platformUrl } : {}),\n ...(oauth2ClientId ? { oauth2ClientId } : {}),\n ...(consoleUrl ? { consoleUrl } : {}),\n };\n return Object.keys(effective).length > 0 ? effective : undefined;\n}\n\nexport function rememberPlatformConfigForToken(accessToken: string, config?: PlatformClientConfig) {\n const effectiveConfig = getEffectivePlatformConfig(config);\n if (effectiveConfig) {\n tokenPlatformConfigs.set(accessToken, effectiveConfig);\n } else {\n tokenPlatformConfigs.delete(accessToken);\n }\n}\n\nfunction getPlatformConfigForToken(accessToken: string): PlatformClientConfig | undefined {\n return tokenPlatformConfigs.get(accessToken);\n}\n\nexport function getPlatformBaseUrl(config: PlatformClientConfig = {}) {\n return normalizeBaseUrl(config.platformUrl ?? getEnvPlatformUrl() ?? defaultPlatformBaseUrl);\n}\n\nexport function isDefaultPlatform(config?: PlatformClientConfig): boolean {\n return getPlatformBaseUrl(config) === normalizeBaseUrl(defaultPlatformBaseUrl);\n}\n\nexport function getOAuth2ClientId(config: PlatformClientConfig = {}) {\n return config.oauth2ClientId ?? getEnvOAuth2ClientId() ?? defaultOAuth2ClientId;\n}\n\nfunction inferConsoleBaseUrl(platformBaseUrl: string) {\n const platformUrl = new URL(platformBaseUrl);\n if (platformUrl.hostname.startsWith(\"api.\")) {\n platformUrl.hostname = platformUrl.hostname.replace(/^api\\./, \"console.\");\n return normalizeBaseUrl(platformUrl.toString());\n }\n return defaultConsoleBaseUrl;\n}\n\n/**\n * Redirect an inferred console URL to the console-next host when\n * `TAILOR_CONSOLE_NEXT` is enabled. An explicitly configured console URL\n * (`consoleUrl` / `TAILOR_PLATFORM_CONSOLE_URL`) is never rewritten.\n * @param consoleBaseUrl - Inferred console base URL\n * @returns The console-next base URL, or the input unchanged\n */\nfunction applyConsoleNext(consoleBaseUrl: string): string {\n if (parseBoolean(process.env.TAILOR_CONSOLE_NEXT) !== true) return consoleBaseUrl;\n const url = new URL(consoleBaseUrl);\n url.hostname = url.hostname.replace(/^console\\./, \"console-next.\");\n return normalizeBaseUrl(url.toString());\n}\n\nexport function getConsoleBaseUrl(config: PlatformClientConfig = {}) {\n if (config.consoleUrl) return normalizeBaseUrl(config.consoleUrl);\n if (config.platformUrl) {\n const inferredUrl = inferConsoleBaseUrl(config.platformUrl);\n if (inferredUrl !== defaultConsoleBaseUrl) return applyConsoleNext(inferredUrl);\n }\n if (process.env.TAILOR_PLATFORM_CONSOLE_URL)\n return normalizeBaseUrl(process.env.TAILOR_PLATFORM_CONSOLE_URL);\n return applyConsoleNext(inferConsoleBaseUrl(getPlatformBaseUrl(config)));\n}\n\n/**\n * Initialize an OAuth2 client for Tailor Platform.\n * @param config - Optional platform connection settings\n * @returns Configured OAuth2 client\n */\nexport function initOAuth2Client(config?: PlatformClientConfig) {\n return new OAuth2Client({\n clientId: getOAuth2ClientId(config),\n server: getPlatformBaseUrl(config),\n discoveryEndpoint: oauth2DiscoveryEndpoint,\n });\n}\n\nexport type OperatorClient = Client<typeof OperatorService>;\n\n/**\n * Initialize an Operator client with the given access token.\n * @param accessToken - Access token for authentication\n * @param config - Optional platform connection settings\n * @returns Configured Operator client\n */\nexport async function initOperatorClient(accessToken: string, config?: PlatformClientConfig) {\n const platformConfig = config ?? getPlatformConfigForToken(accessToken);\n const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([\n import(\"#/cli/telemetry/interceptor\"),\n import(\"@tailor-platform/tailor-proto/service_pb\"),\n ]);\n\n const interceptors: Interceptor[] = [\n await userAgentInterceptor(),\n await bearerTokenInterceptor(accessToken),\n retryInterceptor(),\n errorHandlingInterceptor(),\n createTracingInterceptor(),\n // Innermost: gates the actual network attempt so each retry re-acquires a\n // slot and backoff waits happen outside the cap.\n concurrencyLimitInterceptor(),\n ];\n\n const transport = await createTransport(getPlatformBaseUrl(platformConfig), interceptors);\n return createClient(OperatorService, transport);\n}\n\n/**\n * Create a Connect transport using connect-node (HTTP/2).\n *\n * connect-node works on both Node.js and Bun. connect-web is not used because\n * it does not support client_streaming, which is required for function uploads.\n * @param baseUrl - Base URL for the transport\n * @param interceptors - Request interceptors\n * @returns Configured transport\n */\nexport async function createTransport(\n baseUrl: string,\n interceptors: Interceptor[],\n): Promise<Transport> {\n const { createConnectTransport } = await import(\"@connectrpc/connect-node\");\n return createConnectTransport({ httpVersion: \"2\", baseUrl, interceptors });\n}\n\n/**\n * Create an interceptor that sets a User-Agent header.\n * @returns User-Agent interceptor\n */\nasync function userAgentInterceptor(): Promise<Interceptor> {\n const ua = await userAgent();\n return (next) => async (req) => {\n req.header.set(\"User-Agent\", ua);\n return await next(req);\n };\n}\n\nexport { userAgent };\n\n/**\n * Create an interceptor that sets the Authorization bearer token.\n * @param accessToken - Access token to use\n * @returns Bearer token interceptor\n */\nasync function bearerTokenInterceptor(accessToken: string): Promise<Interceptor> {\n return (next) => async (req) => {\n req.header.set(\"Authorization\", `Bearer ${accessToken}`);\n return await next(req);\n };\n}\n\n/**\n * Create an interceptor that retries failed unary requests with backoff.\n *\n * Retries unary methods on `Unavailable`/`ResourceExhausted`, and\n * `Aborted`/`Internal` only for methods declared side-effect-free or idempotent,\n * up to 3 attempts. Workspace creation is excluded because it has no idempotency\n * key and a lost response is ambiguous.\n * As a targeted exception for the deploy/apply flow, a post-retry `AlreadyExists`\n * from an allowlisted Create (see `RETRY_SAFE_CREATE_METHODS`) is treated as\n * success, since it means a prior attempt already committed the resource\n * server-side. A first-attempt `AlreadyExists` from such a Create still\n * surfaces, but is routed to crash/error reporting first (the top-level handler\n * skips `ConnectError`), so the otherwise-silent compound-create race is\n * trackable.\n * @internal\n * @returns Retry interceptor\n */\nexport function retryInterceptor(): Interceptor {\n return (next) => async (req) => {\n if (req.stream) {\n return await next(req);\n }\n\n let lastError: unknown;\n for (let i = 0; i < MAX_RETRY_ATTEMPTS; i++) {\n if (i > 0) {\n await waitRetryBackoff(i);\n }\n\n try {\n return await next(req);\n } catch (error) {\n // A retry that comes back AlreadyExists is treated as success: a prior\n // attempt (the one whose retriable error sent us here) already created\n // the resource server-side, but its response was lost as\n // Unavailable/ResourceExhausted under load. The identical retry then\n // races against that committed write and fails with `already_exists`.\n // Restricted to RETRY_SAFE_CREATE_METHODS (deploy creates whose response\n // body is unused) and to actual retries (i > 0).\n if (isRetrySafeCreateAlreadyExists(error, req.method.name)) {\n if (i > 0) {\n logger.debug(\n `retry: ${req.method.name} returned AlreadyExists on attempt ${i + 1}; ` +\n `treating as success (prior attempt likely committed)`,\n );\n return synthesizeEmptyUnaryResponse(req);\n }\n // First-attempt AlreadyExists on a retry-safe create: no retry of ours\n // preceded it, so the resource was committed out-of-band (a concurrent\n // or non-idempotent compound create under load — #1350). The top-level\n // handler skips ConnectError, so route it to error tracking here before\n // letting it surface as the deploy error.\n const { reportCrash } = await import(\"#/cli/crashreport/index\");\n await reportCrash(error, \"handledError\");\n }\n if (req.method.name !== \"CreateWorkspace\" && isRetirable(error, req.method.idempotency)) {\n lastError = error;\n logger.debug(\n `retry: ${req.method.name} attempt ${i + 1} failed with ` +\n `${connectCodeName(error)}; retrying`,\n );\n continue;\n }\n throw error;\n }\n }\n throw lastError;\n };\n}\n\n/**\n * Create an interceptor that caps the number of concurrent unary RPCs.\n *\n * A fresh-workspace apply fires one `create*` per resource at once; left\n * unbounded, the platform sheds load as `Unavailable`/`ResourceExhausted`,\n * which drives retries into the non-idempotent compound-create `already_exists`\n * race (#1350). One shared limiter per client bounds total in-flight calls\n * across every deploy resource, not just a single call site. Streaming RPCs\n * (e.g. function uploads) are not gated.\n * @internal\n * @returns Concurrency-limiting interceptor\n */\nexport function concurrencyLimitInterceptor(): Interceptor {\n const limit = createApplyLimiter();\n return (next) => async (req) => {\n if (req.stream) {\n return await next(req);\n }\n return await limit(() => next(req));\n };\n}\n\n/**\n * Human-readable name for the Connect status code of an error, for diagnostics.\n * @param error - Error thrown by a request (expected to be a ConnectError)\n * @returns The Code name (e.g., \"Unavailable\"), or \"unknown\" for non-ConnectError\n */\nfunction connectCodeName(error: unknown): string {\n return error instanceof ConnectError ? Code[error.code] : \"unknown\";\n}\n\n/**\n * Create RPCs for which a post-retry `AlreadyExists` may be treated as success.\n *\n * Membership is deliberately an allowlist, not `startsWith(\"Create\")`: swallowing\n * synthesizes an empty response (see `synthesizeEmptyUnaryResponse`), which is only\n * safe when every caller tolerates an empty response body. These are the deploy/apply\n * resource creations that fire under heavy parallelism and discard their response —\n * except `CreateSecretManagerSecret`, whose caller reads `secret.updateTime` but\n * degrades safely when it is absent (the next deploy re-updates the secret).\n *\n * Intentionally excluded because their callers read the response body — swallowing\n * would hand back an empty message and corrupt downstream state:\n * - `CreateIdPClient` (uses `resp.client.clientSecret` to seed the secret vault)\n * - `CreateWorkflowJobFunction` (uses `response.jobFunction.version`)\n * - `CreateWorkspace` / `CreatePersonalAccessToken` / `CreateDeployment` /\n * `CreateOrganizationFolder` (interactive commands that return created data)\n *\n * `CreateFunctionRegistry` is client-streaming and never reaches this path\n * (streaming requests bypass the retry loop entirely).\n *\n * An allowlist miss is safe: the resource simply loses race protection and an\n * `already_exists` surfaces loudly, as before — never a silent empty response.\n *\n * A drift guard (see client.test.ts) fails CI if any `client.create*` used in the\n * deploy flow is neither listed here nor explicitly classified as response-consuming,\n * so a newly added apply create cannot silently miss this list.\n * @internal\n */\nexport const RETRY_SAFE_CREATE_METHODS: ReadonlySet<string> = new Set([\n \"CreateAIGateway\",\n \"CreateApplication\",\n \"CreateAuthConnection\",\n \"CreateAuthHook\",\n \"CreateAuthIDPConfig\",\n \"CreateAuthMachineUser\",\n \"CreateAuthOAuth2Client\",\n \"CreateAuthSCIMConfig\",\n \"CreateAuthSCIMResource\",\n \"CreateAuthService\",\n \"CreateExecutorExecutor\",\n \"CreateIdPService\",\n \"CreatePipelineResolver\",\n \"CreatePipelineService\",\n \"CreateSecretManagerSecret\",\n \"CreateSecretManagerVault\",\n \"CreateStaticWebsite\",\n \"CreateTailorDBGQLPermission\",\n \"CreateTailorDBService\",\n \"CreateTailorDBType\",\n \"CreateTenantConfig\",\n \"CreateUserProfileConfig\",\n \"CreateWorkflow\",\n \"CreateWorkflowJobFunctionExecutionPolicy\",\n]);\n\n/**\n * Whether an error is an `AlreadyExists` from a retry-safe Create RPC.\n *\n * Only `AlreadyExists` stands in for \"my prior write already landed\"; for other\n * verbs/codes it would be a real conflict that must surface.\n * @param error - Error thrown by the request\n * @param methodName - RPC method name (e.g., \"CreateTailorDBType\")\n * @returns True if the error is an `AlreadyExists` from a retry-safe Create method\n */\nfunction isRetrySafeCreateAlreadyExists(error: unknown, methodName: string): boolean {\n return (\n error instanceof ConnectError &&\n error.code === Code.AlreadyExists &&\n RETRY_SAFE_CREATE_METHODS.has(methodName)\n );\n}\n\n/**\n * Build a default (empty) unary response for the request's output message.\n *\n * Used when a retried Create is determined to have already succeeded on a prior\n * attempt: callers in the deploy pipeline ignore Create response bodies, so an\n * empty message faithfully represents the already-applied state.\n * @param req - Unary request whose output schema is used\n * @returns A synthesized unary response with an empty output message\n */\nfunction synthesizeEmptyUnaryResponse(req: {\n service: UnaryResponse[\"service\"];\n method: UnaryResponse[\"method\"];\n}): UnaryResponse {\n return {\n stream: false,\n service: req.service,\n method: req.method,\n header: new Headers(),\n message: create(req.method.output),\n trailer: new Headers(),\n };\n}\n\n/**\n * Base delay (ms) for the first retry. Subsequent attempts double it.\n *\n * Kept relatively large so a retry does not immediately race an original request\n * that is still settling server-side under load (e.g. a compound create whose\n * response was lost), which is what triggers the `already_exists` race.\n */\nconst RETRY_BASE_DELAY_MS = 500;\n\n/** Maximum number of attempts, including the initial one, for a retried request. */\nconst MAX_RETRY_ATTEMPTS = 3;\n\n/**\n * Wait for an exponential backoff delay with jitter.\n * @param attempt - Current retry attempt number (1-based)\n * @returns Promise that resolves after the delay\n */\nfunction waitRetryBackoff(attempt: number) {\n const base = RETRY_BASE_DELAY_MS * 2 ** (attempt - 1);\n const jitter = 0.1 * (Math.random() * 2 - 1);\n const backoff = base * (1 + jitter);\n return new Promise((resolve) => setTimeout(resolve, backoff));\n}\n\n/**\n * Determine whether the given error is retriable for the method idempotency.\n * @param error - Error thrown by the request\n * @param idempotency - Method idempotency level\n * @returns True if the error should be retried\n */\nfunction isRetirable(error: unknown, idempotency: MethodOptions_IdempotencyLevel) {\n if (!(error instanceof ConnectError)) {\n return false;\n }\n\n switch (error.code) {\n case Code.ResourceExhausted:\n case Code.Unavailable:\n return true;\n case Code.Aborted:\n case Code.Internal:\n return (\n idempotency === MethodOptions_IdempotencyLevel.NO_SIDE_EFFECTS ||\n idempotency === MethodOptions_IdempotencyLevel.IDEMPOTENT\n );\n default:\n return false;\n }\n}\n\n/**\n * Create an interceptor that enhances error messages from the Operator API.\n * @internal\n * @returns Error handling interceptor\n */\nexport function errorHandlingInterceptor(): Interceptor {\n return (next) => async (req) => {\n try {\n return await next(req);\n } catch (error) {\n if (error instanceof ConnectError) {\n const { operation, resourceType } = parseMethodName(req.method.name);\n const identity = formatRequestIdentity(req.message, req.method.name);\n\n // Re-throw as ConnectError with enhanced message to avoid re-wrapping\n // Use rawMessage to avoid duplicating the error code prefix\n throw new ConnectError(\n `Failed to ${operation} ${resourceType}${identity}: ${error.rawMessage}`,\n error.code,\n error.metadata,\n );\n }\n throw error;\n }\n };\n}\n\n/**\n * @internal\n * @param methodName - RPC method name (e.g., \"CreateWorkspace\")\n * @returns Parsed operation and resource type\n */\nexport function parseMethodName(methodName: string): {\n operation: string;\n resourceType: string;\n} {\n const match = methodName.match(/^(Create|Update|Delete|Set|List|Get)(.+)$/);\n if (!match) {\n return { operation: \"perform\", resourceType: \"resource\" };\n }\n\n const [, action, resource] = match as [string, string, string];\n return { operation: action.toLowerCase(), resourceType: resource };\n}\n\n// Identifier fields surfaced in enhanced error messages. Never add fields\n// that can carry secrets or PII (tokens, scripts, query args, secret values,\n// emails), and never add a suffix that could match them (e.g. \"Key\" would\n// match future key material).\n//\n// Platform-wide naming conventions: on every API, a top-level string field\n// with one of these names or suffixes is a resource identifier.\nconst IDENTITY_KEYS = new Set([\"name\", \"id\"]);\nconst IDENTITY_KEY_SUFFIXES = [\"Name\", \"Id\", \"Namespace\"];\n// Key read from nested resource messages (e.g. the type in a create request).\n// Only materialized protobuf messages (marked by $typeName) qualify: map and\n// Struct fields materialize without one, and their entries can carry values\n// the SDK does not control (e.g. metadata labels merged from the remote).\nconst NESTED_IDENTITY_KEY = \"name\";\n// API-specific identifier fields, scoped to the RPC methods that define them\n// so a same-named field on an unrelated API is never surfaced by accident.\nconst METHOD_IDENTITY_KEYS: Readonly<Record<string, readonly string[]>> = {\n GetMetadata: [\"trn\"],\n SetMetadata: [\"trn\"],\n AddCustomDomain: [\"domain\"],\n GetCustomDomain: [\"domain\"],\n RemoveCustomDomain: [\"domain\"],\n CreateWorkflowJobFunctionExecutionPolicy: [\"executionPolicyKey\"],\n UpdateWorkflowJobFunctionExecutionPolicy: [\"executionPolicyKey\"],\n GetWorkflowJobFunctionExecutionPolicyByKey: [\"executionPolicyKey\"],\n};\n\nfunction isIdentityKey(key: string, methodName: string): boolean {\n if (key.startsWith(\"$\")) {\n return false;\n }\n return (\n IDENTITY_KEYS.has(key) ||\n IDENTITY_KEY_SUFFIXES.some((suffix) => key.endsWith(suffix)) ||\n (METHOD_IDENTITY_KEYS[methodName]?.includes(key) ?? false)\n );\n}\n\n/**\n * Format an allowlisted identity suffix for enhanced error messages.\n *\n * Only resource identifiers are included — the rest of the request payload\n * can carry credentials and must never reach terminal or CI logs.\n * @param message - Request message to extract identifiers from\n * @param methodName - RPC method name used to resolve method-scoped identifiers\n * @returns Identity suffix like \" (namespaceName: x, type.name: y)\", or an empty string\n */\nfunction formatRequestIdentity(message: unknown, methodName: string): string {\n if (typeof message !== \"object\" || message === null) {\n return \"\";\n }\n const parts: string[] = [];\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\" && value !== \"\" && isIdentityKey(key, methodName)) {\n parts.push(`${key}: ${value}`);\n } else if (\n !key.startsWith(\"$\") &&\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof (value as Record<string, unknown>).$typeName === \"string\"\n ) {\n const nestedName = (value as Record<string, unknown>)[NESTED_IDENTITY_KEY];\n if (typeof nestedName === \"string\" && nestedName !== \"\") {\n parts.push(`${key}.${NESTED_IDENTITY_KEY}: ${nestedName}`);\n }\n }\n }\n return parts.length === 0 ? \"\" : ` (${parts.join(\", \")})`;\n}\n\nexport const MAX_PAGE_SIZE = 1000;\n\n/**\n * Fetch all paginated resources by repeatedly calling the given function.\n * @template T\n * @param fn - Page fetcher returning items and next page token\n * @returns All fetched items\n */\nexport async function fetchAll<T>(\n fn: (pageToken: string, maxPageSize: number) => Promise<[T[], string]>,\n) {\n const items: T[] = [];\n let pageToken = \"\";\n\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const [batch, nextPageToken] = await fn(pageToken, MAX_PAGE_SIZE);\n items.push(...batch);\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!nextPageToken) break;\n pageToken = nextPageToken;\n }\n return items;\n}\n\n/**\n * @internal\n * @param error - Error value to inspect\n * @returns Whether the error is a Connect NotFound error\n */\nexport function isNotFoundError(error: unknown): boolean {\n return error instanceof ConnectError && error.code === Code.NotFound;\n}\n\n/**\n * Fetch all paginated resources, treating an absent resource group as empty.\n * @template T\n * @param fn - Page fetcher returning items and next page token\n * @returns Items fetched before pagination completes or the fetcher raises NotFound\n */\nexport async function fetchAllTolerant<T>(\n fn: (pageToken: string, maxPageSize: number) => Promise<[T[], string]>,\n): Promise<T[]> {\n return await fetchAll(async (pageToken, maxPageSize) => {\n try {\n return await fn(pageToken, maxPageSize);\n } catch (error) {\n if (isNotFoundError(error)) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n}\n\n/**\n * Fetch a single resource, treating NotFound as an absent value.\n * @template T\n * @param fn - Resource getter\n * @returns Fetched resource, or undefined when the getter raises NotFound\n */\nexport async function getOrNull<T>(fn: () => Promise<T>): Promise<T | undefined> {\n try {\n return await fn();\n } catch (error) {\n if (isNotFoundError(error)) {\n return undefined;\n }\n throw error;\n }\n}\n\ninterface FetchPagedOptions {\n /** Maximum number of items to return. 0 or undefined means unlimited. */\n limit?: number;\n}\n\n/**\n * Fetch paginated resources with an optional upper bound on the number of\n * items returned. When `limit` is 0 or undefined the function behaves\n * like `fetchAll` and returns every page. When `limit` is positive the\n * function stops once enough items are collected, requesting smaller\n * pages as it approaches the boundary.\n * @template T\n * @param fn - Page fetcher returning items and next page token\n * @param options - Pagination options\n * @returns Fetched items (length <= limit when limit > 0)\n */\nexport async function fetchPaged<T>(\n fn: (pageToken: string, pageSize: number) => Promise<[T[], string]>,\n options?: FetchPagedOptions,\n): Promise<T[]> {\n const limit = options?.limit;\n const unbounded = limit === undefined || limit === 0;\n const items: T[] = [];\n let pageToken = \"\";\n\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n while (true) {\n const pageSize = unbounded ? MAX_PAGE_SIZE : Math.min(limit - items.length, MAX_PAGE_SIZE);\n if (!unbounded && pageSize <= 0) break;\n\n const [batch, nextPageToken] = await fn(pageToken, pageSize);\n items.push(...batch);\n if (!unbounded && items.length >= limit) break;\n // loop exits when the platform stops returning a page token\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!nextPageToken) break;\n pageToken = nextPageToken;\n }\n\n if (!unbounded && items.length > limit) {\n return items.slice(0, limit);\n }\n return items;\n}\n\n/**\n * Fetch user info from the Tailor Platform userinfo endpoint.\n * @param accessToken - Access token for the current user\n * @param config - Optional platform connection settings\n * @returns Parsed user info\n */\nexport async function fetchUserInfo(accessToken: string, config?: PlatformClientConfig) {\n const userInfoUrl = new URL(\"/auth/platform/userinfo\", getPlatformBaseUrl(config)).href;\n const resp = await fetch(userInfoUrl, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"User-Agent\": await userAgent(),\n },\n });\n if (!resp.ok) {\n throw new Error(`Failed to fetch user info: ${resp.statusText}`);\n }\n\n const rawJson = await resp.json();\n // strip unknown keys\n const schema = z.object({\n sub: z.string(),\n email: z.string(),\n });\n return schema.parse(rawJson);\n}\n\n// Converting \"name:url\" patterns to actual Static Website URLs\n/**\n * Options for `resolveStaticWebsiteUrls`.\n */\nexport type ResolveStaticWebsiteUrlsOptions = {\n /**\n * Names of static websites that are defined locally in the current\n * configuration. When the platform-side lookup for a name in this set\n * fails specifically with a `NotFound` error, the warning is suppressed\n * and the original `name:url[/path]` pattern is returned unresolved\n * instead of being dropped.\n *\n * Use this from plan-phase callers to avoid noisy warnings on the first\n * deployment, where the static website will be created later in the same\n * apply run. Other failure modes (\"URL not yet assigned\", transient RPC\n * errors, permission errors) are intentionally not suppressed so that\n * real platform problems still surface during planning.\n */\n expectedLocalNames?: ReadonlySet<string>;\n};\n\n/**\n * Resolve \"name:url\" patterns to actual Static Website URLs.\n * @param client - Operator client instance\n * @param workspaceId - Workspace ID\n * @param urls - URLs or name:url patterns\n * @param context - Logging context (e.g., \"CORS\", \"OAuth2 redirect URIs\")\n * @param options - Optional behavior overrides\n * @returns Resolved URLs (or the original pattern for entries marked as\n * expected-but-not-yet-deployed via `options.expectedLocalNames`)\n */\nexport async function resolveStaticWebsiteUrls(\n client: OperatorClient,\n workspaceId: string,\n urls: string[] | undefined,\n context: string, // for logging context (e.g., \"CORS\", \"OAuth2 redirect URIs\")\n options: ResolveStaticWebsiteUrlsOptions = {},\n): Promise<string[]> {\n if (!urls) {\n return [];\n }\n\n const { expectedLocalNames } = options;\n\n const results = await Promise.all(\n urls.map(async (url) => {\n const urlPattern = /:url(\\/.*)?$/;\n const match = url.match(urlPattern);\n\n if (match && match.index !== undefined) {\n const siteName = url.substring(0, match.index);\n const pathSuffix = match[1] || \"\";\n\n try {\n const response = await client.getStaticWebsite({\n workspaceId,\n name: siteName,\n });\n\n if (response.staticwebsite?.url) {\n return [response.staticwebsite.url + pathSuffix];\n }\n logger.warn(\n `Static website \"${siteName}\" has no URL assigned yet. Excluding from ${context}.`,\n );\n return [];\n } catch (error) {\n if (isNotFoundError(error) && expectedLocalNames?.has(siteName)) {\n return [url];\n }\n logger.warn(\n `Static website \"${siteName}\" not found for ${context} configuration. Excluding from ${context}.`,\n );\n return [];\n }\n }\n return [url];\n }),\n );\n\n return results.flat();\n}\n\n/**\n * Fetch an OAuth2 access token for a machine user.\n * @param url - OAuth2 server base URL\n * @param clientId - Client ID for the machine user\n * @param clientSecret - Client secret for the machine user\n * @returns Access token\n */\nexport async function fetchMachineUserToken(url: string, clientId: string, clientSecret: string) {\n const tokenEndpoint = new URL(\"/oauth2/token\", url).href;\n const formData = new URLSearchParams();\n formData.append(\"grant_type\", \"client_credentials\");\n formData.append(\"client_id\", clientId);\n formData.append(\"client_secret\", clientSecret);\n\n const request = {\n method: \"POST\",\n headers: {\n \"User-Agent\": await userAgent(),\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: formData,\n };\n const resp = await withConnectTimeoutRetry(\"machine user token request\", () =>\n fetch(tokenEndpoint, request),\n );\n if (!resp.ok) {\n const body = await resp.text().catch(() => \"\");\n throw new Error(\n `Failed to fetch machine user token: ${resp.status} ${resp.statusText} ${body.slice(0, 500)}`,\n );\n }\n const rawJson = await resp.json();\n\n // strip unknown keys\n const schema = z.object({\n token_type: z.string(),\n access_token: z.string(),\n expires_in: z.number(),\n });\n return schema.parse(rawJson);\n}\n\nfunction isUndiciConnectTimeout(error: unknown): boolean {\n if (!(error instanceof TypeError)) {\n return false;\n }\n const cause = error.cause;\n return cause instanceof Error && \"code\" in cause && cause.code === \"UND_ERR_CONNECT_TIMEOUT\";\n}\n\n/**\n * Retry a request that failed before the connection was established.\n *\n * Only `UND_ERR_CONNECT_TIMEOUT` is retried: the request provably never reached\n * the server, so replaying it cannot duplicate a server-side effect.\n * @param label - Request description for the retry debug log\n * @param send - Sends the request; called once per attempt\n * @returns The first successful result\n */\nasync function withConnectTimeoutRetry<T>(label: string, send: () => Promise<T>): Promise<T> {\n for (let attempt = 1; ; attempt++) {\n try {\n return await send();\n } catch (error) {\n if (!isUndiciConnectTimeout(error) || attempt >= MAX_RETRY_ATTEMPTS) {\n throw error;\n }\n logger.debug(\n `retry: ${label} attempt ${attempt} failed with UND_ERR_CONNECT_TIMEOUT; retrying`,\n );\n await waitRetryBackoff(attempt);\n }\n }\n}\n\n/**\n * Fetch an OAuth2 token for a platform machine user via client_credentials grant.\n * @param clientId - Client ID for the platform machine user\n * @param clientSecret - Client secret for the platform machine user\n * @param config - Optional platform connection settings\n * @returns OAuth2 token\n */\nexport async function fetchPlatformMachineUserToken(\n clientId: string,\n clientSecret: string,\n config?: PlatformClientConfig,\n) {\n const server = getPlatformBaseUrl(config);\n // A new client per attempt: OAuth2Client caches its discovery promise even when\n // it rejects, so a reused client would replay the failure without re-requesting.\n return await withConnectTimeoutRetry(\"platform machine user token request\", () =>\n new OAuth2Client({\n clientId,\n clientSecret,\n server,\n discoveryEndpoint: oauth2DiscoveryEndpoint,\n }).clientCredentials(),\n );\n}\n\n/**\n * Close the global HTTP connection pool to prevent libuv UV_HANDLE_CLOSING\n * assertion failure on Windows at process exit (Node.js 23.x+).\n * See: https://github.com/nodejs/node/issues/56645\n *\n * The pool is reached through the global dispatcher symbol rather than the `undici`\n * package: importing that package installs its own Agent over these same globals,\n * replacing the HTTP stack Node's `fetch` already uses. The symbol is versioned per\n * Dispatcher API generation, and the newest one wins because older symbols hold a\n * wrapper around that same pool — closing both would destroy it twice.\n */\nexport async function closeConnectionPool() {\n const globals = globalThis as Record<symbol, { close?: () => Promise<void> } | undefined>;\n const dispatcher =\n globals[Symbol.for(\"undici.globalDispatcher.2\")] ??\n globals[Symbol.for(\"undici.globalDispatcher.1\")];\n if (typeof dispatcher?.close === \"function\") {\n await dispatcher.close();\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"pathe\";\n\n/**\n * Collect base directories for resolving plugin import paths.\n * @param configPath - Path to tailor.config.ts\n * @returns Ordered list of base directories\n */\nexport function getPluginImportBaseDirs(configPath?: string): string[] {\n if (configPath) {\n return [path.dirname(configPath)];\n }\n\n return [process.cwd()];\n}\n\n/**\n * Resolve a relative plugin import path against candidate base directories.\n * @param pluginImportPath - Relative plugin import path\n * @param baseDirs - Candidate base directories\n * @returns Absolute path if found, otherwise null\n */\nexport function resolveRelativePluginImportPath(\n pluginImportPath: string,\n baseDirs: string[],\n): string | null {\n if (!pluginImportPath.startsWith(\".\")) {\n return null;\n }\n\n for (const baseDir of baseDirs) {\n const absolutePath = path.resolve(baseDir, pluginImportPath);\n if (fs.existsSync(absolutePath)) {\n return absolutePath;\n }\n }\n\n return null;\n}\n","// Runtime guards and helpers for plugin authoring types.\n//\n// These live outside plugin/types.ts (a pure type module) because they are\n// runtime functions. The types they operate on are imported type-only.\nimport type {\n DependencyKind,\n PluginGeneratedExecutor,\n PluginGeneratedExecutorWithFile,\n} from \"./types\";\n\n/**\n * Reads a table name without assuming plugin output is a valid table object.\n * @param table - Raw table value returned by a plugin hook.\n * @returns The table name when it is a string; otherwise, undefined.\n */\nexport function getRawPluginTableName(table: unknown): string | undefined {\n const name =\n typeof table === \"object\" && table !== null && \"name\" in table ? table.name : undefined;\n return typeof name === \"string\" ? name : undefined;\n}\n\n/**\n * Collects the generation-time dependency kinds a plugin requires.\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\n/**\n * Checks if a plugin executor uses file-based resolution.\n * @param executor - The plugin executor to check.\n * @returns True if the executor uses file-based resolution.\n */\nexport function isPluginExecutorWithFile(\n executor: PluginGeneratedExecutor,\n): executor is PluginGeneratedExecutorWithFile {\n return \"resolve\" in executor && \"context\" in executor;\n}\n","/**\n * Plugin Executor Generator\n *\n * Generates TypeScript files for plugin-generated executors.\n * Supports both legacy format (inline trigger/operation) and new format (executorFile/context).\n */\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"pathe\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport {\n getPluginImportBaseDirs,\n resolveRelativePluginImportPath,\n} from \"#/cli/shared/plugin-import\";\nimport { isPluginExecutorWithFile } from \"#/plugin/guards\";\nimport {\n type PluginGeneratedExecutorLegacy,\n type PluginGeneratedExecutorWithFile,\n type PluginTriggerConfig,\n type PluginOperationConfig,\n type PluginInjectMap,\n type PluginExecutorContext,\n} from \"#/plugin/types\";\nimport { assertDefined } from \"#/utils/assert\";\nimport ml from \"#/utils/multiline\";\nimport type {\n PluginExecutorInfoExtended,\n PluginTableGenerationResult,\n SourceTableInfo,\n} from \"#/plugin/manager\";\n\n/**\n * Information needed for table import resolution.\n */\ninterface TableImportInfo {\n /** Variable name to use in generated code */\n variableName: string;\n /** Import path for the table */\n importPath: string;\n}\n\n/**\n * Generate TypeScript files for plugin-generated executors.\n * These files will be processed by the standard executor bundler.\n * @param executors - Array of plugin executor information\n * @param outputDir - Base output directory (e.g., .tailor)\n * @param tableGenerationResult - Result from plugin table generation (for import resolution)\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @param configPath - Path to tailor.config.ts (used for resolving plugin import paths)\n * @returns Array of generated file paths\n */\nexport function generatePluginExecutorFiles(\n executors: ReadonlyArray<PluginExecutorInfoExtended>,\n outputDir: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n configPath?: string,\n): string[] {\n if (executors.length === 0) {\n return [];\n }\n\n const generatedFiles: string[] = [];\n const baseDirs = getPluginImportBaseDirs(configPath);\n\n for (const info of executors) {\n const filePath = generateSingleExecutorFile(\n info,\n outputDir,\n tableGenerationResult,\n sourceTableInfoMap,\n baseDirs,\n );\n generatedFiles.push(filePath);\n\n const relativePath = path.relative(process.cwd(), filePath);\n logger.log(\n ` Plugin Executor File: ${styles.success(relativePath)} from plugin ${styles.info(info.pluginId)}`,\n );\n }\n\n return generatedFiles;\n}\n\n/**\n * Generate a single executor file.\n * @param info - Plugin executor metadata and definition\n * @param outputDir - Base output directory (e.g., .tailor)\n * @param tableGenerationResult - Result from plugin table generation\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns Absolute path to the generated file\n */\nfunction generateSingleExecutorFile(\n info: PluginExecutorInfoExtended,\n outputDir: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n baseDirs: string[] = [],\n): string {\n const pluginDir = sanitizePluginId(info.pluginId);\n const executorOutputDir = path.join(outputDir, pluginDir, \"executors\");\n fs.mkdirSync(executorOutputDir, { recursive: true });\n\n const fileName = sanitizeExecutorFileName(info.executor.name);\n const filePath = path.join(executorOutputDir, `${fileName}.ts`);\n\n let content: string;\n if (isPluginExecutorWithFile(info.executor)) {\n content = generateExecutorFileContentNew(\n info,\n info.executor,\n outputDir,\n tableGenerationResult,\n sourceTableInfoMap,\n baseDirs,\n );\n } else {\n content = generateExecutorFileContentLegacy(info.executor);\n }\n\n fs.writeFileSync(filePath, content);\n return filePath;\n}\n\n/**\n * Generate TypeScript file content for new format executor (dynamic import).\n * Uses the executor's resolve function to dynamically import the module.\n * @param info - Plugin executor information\n * @param executor - Executor definition with resolve\n * @param outputDir - Base output directory\n * @param tableGenerationResult - Result from plugin table generation\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns TypeScript source code for executor file\n */\nfunction generateExecutorFileContentNew(\n info: PluginExecutorInfoExtended,\n executor: PluginGeneratedExecutorWithFile,\n outputDir: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n baseDirs: string[] = [],\n): string {\n const { resolve, context } = executor;\n const pluginDir = sanitizePluginId(info.pluginId);\n const executorOutputDir = path.join(outputDir, pluginDir, \"executors\");\n\n const executorImportPath = resolveExecutorImportPath(\n resolve,\n info.pluginImportPath,\n executorOutputDir,\n baseDirs,\n );\n\n // Collect table imports from context\n const tableImports = collectTableImports(\n context,\n outputDir,\n info.pluginId,\n tableGenerationResult,\n sourceTableInfoMap,\n );\n\n // Generate import statements\n const imports: string[] = [];\n\n for (const [, importInfo] of tableImports) {\n imports.push(`import { ${importInfo.variableName} } from \"${importInfo.importPath}\";`);\n }\n\n // Generate context object code\n const contextCode = generateContextCode(context, tableImports);\n\n return ml /* ts */ `\n /**\n * Auto-generated executor by plugin: ${info.pluginId}\n * DO NOT EDIT - This file is generated by @tailor-platform/sdk\n */\n ${imports.join(\"\\n\")}\n\n const { default: executorFactory } = await import(${JSON.stringify(executorImportPath)});\n if (typeof executorFactory !== \"function\") {\n throw new Error(\n \"Plugin executor module must export a default function created by withPluginContext().\",\n );\n }\n export default executorFactory(${contextCode});\n `;\n}\n\n/**\n * Collect table imports needed for context.\n * @param context - Executor context values from plugin\n * @param outputDir - Base output directory for generated files\n * @param pluginId - Plugin identifier used for output paths\n * @param tableGenerationResult - Result from plugin table generation\n * @param sourceTableInfoMap - Map of source table names to their source info\n * @returns Map of context keys to their import information\n */\nfunction collectTableImports(\n context: PluginExecutorContext,\n outputDir: string,\n pluginId: string,\n tableGenerationResult?: PluginTableGenerationResult,\n sourceTableInfoMap?: Map<string, SourceTableInfo>,\n): Map<string, TableImportInfo> {\n const tableImports = new Map<string, TableImportInfo>();\n const pluginDir = sanitizePluginId(pluginId);\n const executorDir = path.join(outputDir, pluginDir, \"executors\");\n\n for (const [key, value] of Object.entries(context)) {\n if (isTableObject(value)) {\n const tableName = value.name;\n const sourceInfo = sourceTableInfoMap?.get(tableName);\n const variableName = sourceInfo?.exportName ?? toCamelCase(tableName);\n\n // Check if it's a generated table\n let importPath: string;\n\n if (tableGenerationResult?.tableFilePaths.has(tableName)) {\n // It's a generated table - import from plugin types directory\n const tableFilePath = assertDefined(\n tableGenerationResult.tableFilePaths.get(tableName),\n \"table file path missing\",\n );\n const absoluteTablePath = path.join(outputDir, tableFilePath);\n importPath = path.relative(executorDir, absoluteTablePath).replace(/\\.ts$/, \"\");\n if (!importPath.startsWith(\".\")) {\n importPath = `./${importPath}`;\n }\n } else if (sourceInfo) {\n // It's a user-defined table\n const sourceFilePath = sourceInfo.filePath;\n importPath = path.relative(executorDir, sourceFilePath).replace(/\\.ts$/, \"\");\n if (!importPath.startsWith(\".\")) {\n importPath = `./${importPath}`;\n }\n } else {\n // Fallback: generate relative path assumption\n // This might need adjustment based on actual project structure\n importPath = `../../../../tailordb/${toKebabCase(tableName)}`;\n }\n\n tableImports.set(key, {\n variableName,\n importPath,\n });\n }\n }\n\n return tableImports;\n}\n\n/**\n * Generate TypeScript code for context object.\n * @param context - Executor context values from plugin\n * @param tableImports - Resolved table import information for context keys\n * @returns TypeScript object literal code\n */\nfunction generateContextCode(\n context: PluginExecutorContext,\n tableImports: Map<string, TableImportInfo>,\n): string {\n const entries: string[] = [];\n\n for (const [key, value] of Object.entries(context)) {\n if (isTableObject(value)) {\n const importInfo = tableImports.get(key);\n if (importInfo) {\n entries.push(` ${key}: ${importInfo.variableName}`);\n }\n } else if (value !== undefined) {\n entries.push(` ${key}: ${JSON.stringify(value)}`);\n }\n }\n\n return `{\\n${entries.join(\",\\n\")},\\n}`;\n}\n\n/**\n * Check if a value is a TailorDB table object.\n * @param value - Value to inspect\n * @returns True if value is a table object with name and fields\n */\nfunction isTableObject(value: unknown): value is { name: string; fields: Record<string, unknown> } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"name\" in value &&\n \"fields\" in value &&\n typeof (value as { name: unknown }).name === \"string\"\n );\n}\n\n// ============================================================================\n// Legacy format support\n// ============================================================================\n\n/**\n * Generate TypeScript file content for legacy format executor (trigger/operation).\n * @param executor - Legacy executor definition\n * @returns TypeScript source code for executor file\n */\nfunction generateExecutorFileContentLegacy(executor: PluginGeneratedExecutorLegacy): string {\n const triggerCode = generateTriggerCode(executor.trigger);\n const operationCode = generateOperationCode(executor.operation);\n\n // Extract inject from function operation\n const inject = executor.operation.kind === \"function\" ? executor.operation.inject : undefined;\n const injectDeclarations = generateInjectDeclarations(inject);\n\n const descriptionLine = executor.description\n ? `\\n description: ${JSON.stringify(executor.description)},`\n : \"\";\n\n return ml /* ts */ `\n /**\n * Auto-generated executor by plugin\n * DO NOT EDIT - This file is generated by @tailor-platform/sdk\n */\n import { createExecutor } from \"@tailor-platform/sdk\";\n ${injectDeclarations}\n export default createExecutor({\n name: ${JSON.stringify(executor.name)},${descriptionLine}\n trigger: ${triggerCode},\n operation: ${operationCode},\n });\n `;\n}\n\n/**\n * Generate const declarations for injected variables.\n * @param inject - Map of injected values keyed by variable name\n * @returns TypeScript const declarations or empty string\n */\nfunction generateInjectDeclarations(inject: PluginInjectMap | undefined): string {\n if (!inject || Object.keys(inject).length === 0) {\n return \"\";\n }\n\n const declarations = Object.entries(inject)\n .map(([name, value]) => `const ${name} = ${JSON.stringify(value)};`)\n .join(\"\\n\");\n\n return `\\n// Injected variables from plugin\\n${declarations}\\n`;\n}\n\n/**\n * Generate TypeScript code for trigger configuration.\n * @param trigger - Trigger configuration for executor\n * @returns TypeScript code for trigger object\n */\nfunction generateTriggerCode(trigger: PluginTriggerConfig): string {\n switch (trigger.kind) {\n case \"tailordb\":\n return `{\n kind: ${JSON.stringify(trigger.kind)},\n events: ${JSON.stringify(trigger.events)},\n tableName: ${JSON.stringify(trigger.tableName)},\n }`;\n\n case \"schedule\":\n return `{\n kind: \"schedule\",\n cron: ${JSON.stringify(trigger.cron)},\n timezone: ${JSON.stringify(trigger.timezone ?? \"UTC\")},\n }`;\n\n case \"incomingWebhook\":\n return `{\n kind: \"incomingWebhook\",\n }`;\n\n default:\n throw new Error(`Unknown trigger kind: ${(trigger as PluginTriggerConfig).kind}`);\n }\n}\n\n/**\n * Generate TypeScript code for operation configuration.\n * @param operation - Operation configuration for executor\n * @returns TypeScript code for operation object\n */\nfunction generateOperationCode(operation: PluginOperationConfig): string {\n switch (operation.kind) {\n case \"graphql\": {\n const appNameLine = operation.appName\n ? `\\n appName: ${JSON.stringify(operation.appName)},`\n : \"\";\n const variablesLine = operation.variables ? `\\n variables: ${operation.variables},` : \"\";\n\n return `{\n kind: \"graphql\",\n query: \\`${escapeTemplateLiteral(operation.query)}\\`,${appNameLine}${variablesLine}\n }`;\n }\n\n case \"function\":\n return `{\n kind: \"function\",\n body: ${operation.body},\n }`;\n\n case \"webhook\":\n return `{\n kind: \"webhook\",\n url: () => ${JSON.stringify(operation.url)},\n }`;\n\n case \"workflow\":\n return `{\n kind: \"workflow\",\n workflowName: ${JSON.stringify(operation.workflowName)},\n }`;\n\n default:\n throw new Error(`Unknown operation kind: ${(operation as PluginOperationConfig).kind}`);\n }\n}\n\n/**\n * Escape special characters in template literal content.\n * @param str - Raw template literal content\n * @returns Escaped string safe for template literals\n */\nfunction escapeTemplateLiteral(str: string): string {\n return str.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\");\n}\n\n// ============================================================================\n// Utility functions\n// ============================================================================\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Resolve the import path for a plugin executor module.\n * @param resolve - Executor resolve function\n * @param pluginImportPath - Plugin's import path\n * @param executorOutputDir - Directory where the generated executor will be written\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns Import path string for the executor module\n */\nfunction resolveExecutorImportPath(\n resolve: () => Promise<{ default: unknown }>,\n pluginImportPath: string,\n executorOutputDir: string,\n baseDirs: string[],\n): string {\n const specifier = extractDynamicImportSpecifier(resolve);\n if (!specifier.startsWith(\".\")) {\n return specifier;\n }\n\n const pluginBaseDir = resolvePluginBaseDir(pluginImportPath, baseDirs);\n if (!pluginBaseDir) {\n throw new Error(\n `Unable to resolve plugin import base for \"${pluginImportPath}\". ` +\n `Tried base dirs: ${baseDirs.join(\", \") || \"(none)\"}. ` +\n `Use an absolute import specifier in resolve(), or ensure the plugin path is resolvable.`,\n );\n }\n\n const absolutePath = path.resolve(pluginBaseDir, specifier);\n let relativePath = path.relative(executorOutputDir, absolutePath).replace(/\\\\/g, \"/\");\n relativePath = stripSourceExtension(relativePath);\n if (!relativePath.startsWith(\".\")) {\n relativePath = `./${relativePath}`;\n }\n return relativePath;\n}\n\n/**\n * Extract the dynamic import specifier from a resolve function.\n * @param resolve - Executor resolve function\n * @returns The module specifier string\n */\nfunction extractDynamicImportSpecifier(resolve: () => Promise<{ default: unknown }>): string {\n const source = resolve.toString();\n const match = source.match(/import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/);\n if (!match) {\n throw new Error(\n `resolve() must return a dynamic import, e.g. \\`async () => await import(\"./executors/on-create\")\\`.`,\n );\n }\n return assertDefined(match[1], \"dynamic import specifier capture group missing\");\n}\n\n/**\n * Resolve plugin base directory for relative imports.\n * @param pluginImportPath - Plugin import path\n * @param baseDirs - Base directories for resolving plugin import paths\n * @returns Directory path or null if not resolvable\n */\nfunction resolvePluginBaseDir(pluginImportPath: string, baseDirs: string[]): string | null {\n if (pluginImportPath.startsWith(\".\")) {\n const resolvedPath =\n resolveRelativePluginImportPath(pluginImportPath, baseDirs) ??\n path.resolve(baseDirs[0] ?? process.cwd(), pluginImportPath);\n if (fs.existsSync(resolvedPath)) {\n const stats = fs.statSync(resolvedPath);\n return stats.isDirectory() ? resolvedPath : path.dirname(resolvedPath);\n }\n return path.extname(resolvedPath) ? path.dirname(resolvedPath) : resolvedPath;\n }\n\n for (const baseDir of baseDirs) {\n try {\n const resolved = require.resolve(pluginImportPath, { paths: [baseDir] });\n return path.dirname(resolved);\n } catch {\n continue;\n }\n }\n return null;\n}\n\n/**\n * Strip TypeScript source extensions from import paths.\n * @param importPath - Path to normalize\n * @returns Path without .ts/.tsx extension\n */\nfunction stripSourceExtension(importPath: string): string {\n return importPath.replace(/\\.(ts|tsx)$/, \"\");\n}\n\n/**\n * Convert plugin ID to safe directory name.\n * @param pluginId - Plugin identifier (e.g., \"@scope/name\")\n * @returns Safe directory name\n */\nfunction sanitizePluginId(pluginId: string): string {\n return pluginId.replace(/^@/, \"\").replace(/\\//g, \"-\");\n}\n\n/**\n * Convert executor name to safe filename.\n * @param executorName - Executor name\n * @returns Safe filename without extension\n */\nfunction sanitizeExecutorFileName(executorName: string): string {\n const baseName = path.basename(executorName);\n const withoutExtension = baseName.replace(/\\.[^/.]+$/, \"\");\n const sanitized = withoutExtension.replace(/[^a-zA-Z0-9_-]/g, \"-\");\n if (!sanitized) {\n throw new Error(`Invalid executor name: \"${executorName}\"`);\n }\n return sanitized;\n}\n\n/**\n * Convert string to camelCase.\n * @param str - Input string to convert\n * @returns camelCase string\n */\nfunction toCamelCase(str: string): string {\n const result = str.replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : \"\"));\n return result.charAt(0).toLowerCase() + result.slice(1);\n}\n\n/**\n * Convert string to kebab-case.\n * @param str - Input string to convert\n * @returns kebab-case string\n */\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n","/**\n * Plugin Table Generator\n *\n * Generates TypeScript files for plugin-generated TailorDB tables.\n * These files can be imported by plugin executors to reference generated tables.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"pathe\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport ml from \"#/utils/multiline\";\nimport type { PluginGeneratedTableInfo, PluginTableGenerationResult } from \"#/plugin/manager\";\nimport type { PluginGeneratedTable } from \"#/plugin/types\";\n\ntype FieldMetadata = {\n required?: boolean;\n index?: boolean;\n unique?: boolean;\n description?: string;\n allowedValues?: ReadonlyArray<{ value: string }>;\n};\n\ntype FieldDefinition = {\n type?: string;\n _metadata?: FieldMetadata;\n metadata?: FieldMetadata;\n};\n\nfunction isFieldDefinition(value: unknown): value is FieldDefinition {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * Generate TypeScript files for plugin-generated tables.\n * These files export the table definition and can be imported by executor files.\n * @param tables - Array of plugin table information\n * @param outputDir - Base output directory (e.g., .tailor)\n * @returns Generation result with file paths\n */\nexport function generatePluginTableFiles(\n tables: ReadonlyArray<PluginGeneratedTableInfo>,\n outputDir: string,\n): PluginTableGenerationResult {\n const tableFilePaths = new Map<string, string>();\n const generatedFiles: string[] = [];\n\n if (tables.length === 0) {\n return { tableFilePaths, generatedFiles };\n }\n\n const seenTableNames = new Map<string, PluginGeneratedTableInfo>();\n\n for (const info of tables) {\n const existing = seenTableNames.get(info.table.name);\n if (existing) {\n throw new Error(\n `Duplicate plugin-generated table name \"${info.table.name}\" detected. ` +\n `First: plugin \"${existing.pluginId}\" (kind: \"${existing.kind}\", source: \"${existing.sourceTableName}\"), ` +\n `Second: plugin \"${info.pluginId}\" (kind: \"${info.kind}\", source: \"${info.sourceTableName}\"). ` +\n `Plugin-generated table names must be unique.`,\n );\n }\n seenTableNames.set(info.table.name, info);\n\n const pluginDir = sanitizePluginId(info.pluginId);\n const tableOutputDir = path.join(outputDir, pluginDir, \"types\");\n fs.mkdirSync(tableOutputDir, { recursive: true });\n\n const fileName = `${toKebabCase(info.table.name)}.ts`;\n const filePath = path.join(tableOutputDir, fileName);\n const content = generateTableFileContent(info);\n\n fs.writeFileSync(filePath, content);\n generatedFiles.push(filePath);\n\n // Store relative path from outputDir for import resolution\n const relativePath = path.relative(outputDir, filePath);\n tableFilePaths.set(info.table.name, relativePath);\n\n const displayPath = path.relative(process.cwd(), filePath);\n logger.log(\n ` Plugin Table File: ${styles.success(displayPath)} (${styles.dim(info.kind)}) from plugin ${styles.info(info.pluginId)}`,\n );\n }\n\n return { tableFilePaths, generatedFiles };\n}\n\n/**\n * Generate TypeScript file content for a single table.\n * @param info - Plugin table information\n * @returns TypeScript source code\n */\nfunction generateTableFileContent(info: PluginGeneratedTableInfo): string {\n const { table, pluginId, sourceTableName, kind } = info;\n const variableName = toCamelCase(table.name);\n const fieldsCode = generateFieldsCode(table);\n\n return ml /* ts */ `\n /**\n * Auto-generated table by plugin: ${pluginId}\n * Source: ${sourceTableName}\n * Kind: ${kind}\n *\n * DO NOT EDIT - This file is generated by @tailor-platform/sdk\n */\n import { db } from \"@tailor-platform/sdk\";\n\n export const ${variableName} = db.table(${JSON.stringify(table.name)}, ${fieldsCode});\n\n export type ${table.name} = typeof ${variableName};\n `;\n}\n\n/**\n * Generate TypeScript code for field definitions.\n * This creates a simplified version of the table's fields.\n * @param table - TailorDB table\n * @returns TypeScript code for fields object\n */\nfunction generateFieldsCode(table: PluginGeneratedTable): string {\n const fieldEntries: string[] = [];\n\n for (const [fieldName, field] of Object.entries(table.fields)) {\n if (!isFieldDefinition(field)) continue;\n const fieldCode = generateSingleFieldCode(field);\n if (fieldCode) {\n fieldEntries.push(` ${fieldName}: ${fieldCode}`);\n }\n }\n\n return `{\\n${fieldEntries.join(\",\\n\")},\\n}`;\n}\n\n/**\n * Map from TailorDB table to SDK method name.\n */\nconst typeToMethodMap: Record<string, string> = {\n string: \"string\",\n integer: \"int\",\n float: \"float\",\n boolean: \"bool\",\n uuid: \"uuid\",\n datetime: \"datetime\",\n date: \"date\",\n time: \"time\",\n enum: \"enum\",\n nested: \"nested\",\n};\n\n/**\n * Generate TypeScript code for a single field definition.\n * @param field - Field definition object\n * @returns TypeScript code for the field\n */\nfunction generateSingleFieldCode(field: FieldDefinition): string | null {\n const fieldType = field.type;\n if (!fieldType) {\n return null;\n }\n\n const method = typeToMethodMap[fieldType] ?? fieldType;\n const metadata: FieldMetadata = field._metadata ?? field.metadata ?? {};\n\n // Build options object\n const optionParts: string[] = [];\n if (metadata.required === false) {\n optionParts.push(\"optional: true\");\n }\n\n const optionsArg = optionParts.length > 0 ? `{ ${optionParts.join(\", \")} }` : \"\";\n\n // Handle enum type with values\n if (fieldType === \"enum\") {\n // Extract enum values from allowedValues array\n const allowedValues = metadata.allowedValues;\n let enumValues: string[] = [];\n if (Array.isArray(allowedValues)) {\n enumValues = allowedValues.map((v: { value: string }) => v.value);\n }\n\n let code = `db.enum(${JSON.stringify(enumValues)}${optionsArg ? `, ${optionsArg}` : \"\"})`;\n if (metadata.index) {\n code += \".index()\";\n }\n if (metadata.unique) {\n code += \".unique()\";\n }\n if (metadata.description) {\n code += `.description(${JSON.stringify(metadata.description)})`;\n }\n return code;\n }\n\n // Build method chain for other types\n let code = `db.${method}(${optionsArg})`;\n\n // Add index if present\n if (metadata.index) {\n code += \".index()\";\n }\n\n // Add unique if present\n if (metadata.unique) {\n code += \".unique()\";\n }\n\n // Add description if present\n if (metadata.description) {\n code += `.description(${JSON.stringify(metadata.description)})`;\n }\n\n return code;\n}\n\n/**\n * Convert plugin ID to safe directory name.\n * @param pluginId - Plugin identifier (e.g., \"@tailor-platform/change-history\")\n * @returns Safe directory name (e.g., \"tailor-platform-change-history\")\n */\nfunction sanitizePluginId(pluginId: string): string {\n return pluginId.replace(/^@/, \"\").replace(/\\//g, \"-\");\n}\n\n/**\n * Convert string to kebab-case.\n * @param str - Input string\n * @returns kebab-case string\n */\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .replace(/[\\s_]+/g, \"-\")\n .toLowerCase();\n}\n\n/**\n * Convert string to camelCase.\n * @param str - Input string\n * @returns camelCase string\n */\nfunction toCamelCase(str: string): string {\n const result = str.replace(/[-_\\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : \"\"));\n return result.charAt(0).toLowerCase() + result.slice(1);\n}\n","import type { Plugin } from \"rolldown\";\n\ntype DepCollectorResult = {\n plugin: Plugin;\n getResult: () => string[];\n};\n\n/**\n * Create a rolldown plugin that collects all resolved module paths during a build.\n * The plugin is purely observational and does not modify any code or behavior.\n * Collected paths exclude node_modules and generated entry files.\n * node_modules changes (package upgrades) are not tracked per-bundle;\n * lockfile hash and SDK version changes invalidate the entire cache.\n * @returns An object containing the plugin and a getResult function that returns sorted, deduplicated paths\n */\nexport function createDepCollectorPlugin(): DepCollectorResult {\n const collectedPaths = new Set<string>();\n\n const plugin: Plugin = {\n name: \"cache-dep-collector\",\n load: {\n filter: {\n id: {\n // Match all file types (not just JS/TS) so that JSON, CJS,\n // and other imported files are tracked for cache invalidation.\n include: [/\\.[^/]+$/],\n },\n },\n handler(id) {\n if (!id.includes(\"node_modules\") && !id.endsWith(\".entry.js\")) {\n collectedPaths.add(id);\n }\n return null;\n },\n },\n };\n\n function getResult(): string[] {\n return Array.from(collectedPaths).toSorted();\n }\n\n return { plugin, getResult };\n}\n","import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\n\n/**\n * Compute the SHA-256 hex digest of an arbitrary string.\n * @param content - The string content to hash\n * @returns Hex-encoded SHA-256 hash\n */\nfunction hashContent(content: string): string {\n return crypto.createHash(\"sha256\").update(content, \"utf-8\").digest(\"hex\");\n}\n\n/**\n * Read a file and return its SHA-256 hex digest.\n * @param filePath - Absolute path to the file\n * @returns Hex-encoded SHA-256 hash of the file content\n */\nfunction hashFile(filePath: string): string {\n const content = fs.readFileSync(filePath);\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n// A path that does not exist hashes to a fixed marker rather than throwing, so\n// a dependency set may include files a build only probed for. Creating such a\n// file later changes the marker to a content hash, which invalidates the entry.\nconst MISSING_FILE_MARKER = \"<missing>\";\n\n/**\n * Compute a deterministic SHA-256 hash for multiple files.\n *\n * Paths are sorted alphabetically before hashing so that the result\n * is independent of the order the paths are supplied (e.g. glob ordering).\n * Each file's individual hash is concatenated and then hashed again. A path\n * that does not exist contributes a fixed marker instead of a content hash.\n * @param filePaths - Array of absolute file paths\n * @returns Hex-encoded SHA-256 hash representing all files\n */\nfunction hashFiles(filePaths: string[]): string {\n const sorted = filePaths.toSorted();\n const combined = sorted.map((fp) => hashFileOrMissing(fp)).join(\"\");\n return hashContent(combined);\n}\n\nfunction hashFileOrMissing(filePath: string): string {\n try {\n return hashFile(filePath);\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return MISSING_FILE_MARKER;\n }\n throw error;\n }\n}\n\nexport { hashContent, hashFile, hashFiles };\n","import * as path from \"pathe\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { createDepCollectorPlugin } from \"./dep-collector-plugin\";\nimport { hashContent, hashFile, hashFiles } from \"./hasher\";\nimport type { CacheStore } from \"./store\";\nimport type { Plugin } from \"rolldown\";\n\ntype BundleKind =\n | \"resolver\"\n | \"executor\"\n | \"workflow-job\"\n | \"auth-hook\"\n | \"http-adapter-input\"\n | \"http-adapter-output\";\n\ntype BundleCacheRestoreParams = {\n kind: BundleKind;\n namespace?: string;\n name: string;\n /** Optional hash of non-file context (e.g., env variables) to include in cache validation. */\n contextHash?: string;\n};\n\ntype BundleCacheSaveParams = {\n kind: BundleKind;\n namespace?: string;\n name: string;\n sourceFile: string;\n content: string;\n dependencyPaths: string[];\n /** Optional hash of non-file context (e.g., env variables) to include in cache key computation. */\n contextHash?: string;\n};\n\n/**\n * Cache strategy that determines whether a bundled output can be\n * restored from cache or needs rebuilding.\n */\ntype BundleCache = {\n /** Attempt to restore cached bundle content. Returns the code string if cache is valid, undefined otherwise. */\n tryRestore(params: BundleCacheRestoreParams): string | undefined;\n /** Save bundle content and its metadata to the cache. */\n save(params: BundleCacheSaveParams): void;\n};\n\nfunction buildCacheKey(kind: string, name: string, namespace?: string): string {\n return namespace ? `${kind}:${namespace}:${name}` : `${kind}:${name}`;\n}\n\nfunction combineHash(fileHash: string, contextHash?: string): string {\n if (!contextHash) return fileHash;\n return hashContent(fileHash + contextHash);\n}\n\ntype ComputeBundlerContextHashParams = {\n sourceFile: string;\n extraContext: string;\n tsconfig?: string;\n inlineSourcemap?: boolean;\n bundleLogLevel?: string;\n prefix?: string;\n};\n\n/**\n * Compute a context hash for cache invalidation across bundlers.\n *\n * Combines the source file path, a caller-supplied extra context string\n * (e.g. serialized workflow start-call bindings, or an HTTP adapter's method\n * list), tsconfig hash, sourcemap mode, bundle log level, and an optional\n * prefix (e.g., serialized env variables) into a single SHA-256 hash.\n * @param params - Context hash computation parameters\n * @returns SHA-256 hex digest of the combined context\n */\nfunction computeBundlerContextHash(params: ComputeBundlerContextHashParams): string {\n const { sourceFile, extraContext, tsconfig, inlineSourcemap, bundleLogLevel, prefix } = params;\n return hashContent(\n (prefix ?? \"\") +\n path.resolve(sourceFile) +\n extraContext +\n (tsconfig ? hashFile(tsconfig) : \"\") +\n String(inlineSourcemap ?? false) +\n (bundleLogLevel ?? \"\"),\n );\n}\n\ntype WithCacheParams = {\n cache: BundleCache | undefined;\n kind: BundleKind;\n namespace?: string;\n name: string;\n sourceFile: string;\n contextHash: string | undefined;\n build: (plugins: Plugin[], trackDependency: (filePath: string) => void) => Promise<string>;\n};\n\n/**\n * Run a build with optional cache restore/save around it.\n * When caching is active, attempts to restore from cache first,\n * and saves the build result (with collected dependencies) on a cache miss.\n * @param params - Cache and build parameters\n * @returns The bundled code string\n */\nasync function withCache(params: WithCacheParams): Promise<string> {\n const { cache, kind, namespace, name, sourceFile, contextHash, build } = params;\n\n if (!cache) {\n return await build([], () => {});\n }\n\n const content = cache.tryRestore({ kind, namespace, name, contextHash });\n if (content !== undefined) {\n logger.debug(` ${styles.dim(\"cached\")}: ${name}`);\n return content;\n }\n\n // Files a build reads without rolldown loading them as modules — tsconfigs\n // consulted for path aliases — still have to invalidate the entry.\n const extraDependencies = new Set<string>();\n const { plugin, getResult } = createDepCollectorPlugin();\n const code = await build([plugin], (filePath) => extraDependencies.add(filePath));\n\n cache.save({\n kind,\n namespace,\n name,\n sourceFile,\n content: code,\n dependencyPaths: [...getResult(), ...extraDependencies],\n contextHash,\n });\n\n return code;\n}\n\n/**\n * Create a bundle cache backed by the given store.\n * @param store - The cache store for persistence\n * @returns A BundleCache instance\n */\nfunction createBundleCache(store: CacheStore): BundleCache {\n function tryRestore(params: BundleCacheRestoreParams): string | undefined {\n const cacheKey = buildCacheKey(params.kind, params.name, params.namespace);\n const entry = store.getEntry(cacheKey);\n\n if (!entry) {\n return undefined;\n }\n\n // Recompute hash of all stored dependency paths. A path that has appeared or\n // disappeared since the entry was saved changes the hash, so it lands on the\n // mismatch below rather than needing its own branch.\n let currentHash: string;\n try {\n currentHash = combineHash(hashFiles(entry.dependencyPaths), params.contextHash);\n } catch {\n return undefined;\n }\n\n if (currentHash !== entry.inputHash) {\n return undefined;\n }\n\n const content = store.restoreBundleContent(cacheKey);\n const output = entry.outputFiles.find((file) => file.outputPath === cacheKey);\n if (content === undefined || !output || hashContent(content) !== output.contentHash) {\n return undefined;\n }\n return content;\n }\n\n function save(params: BundleCacheSaveParams): void {\n const { kind, namespace, name, sourceFile, content, dependencyPaths, contextHash } = params;\n const cacheKey = buildCacheKey(kind, name, namespace);\n // Always include sourceFile in dependency paths so that changes to the\n // source file itself are detected even when dep-collector only finds\n // node_modules imports (which are filtered out).\n const allDeps = dependencyPaths.includes(sourceFile)\n ? dependencyPaths\n : [sourceFile, ...dependencyPaths];\n\n // Mirror tryRestore()'s tolerance: a non-ENOENT read error (e.g. EISDIR)\n // should give up on caching this entry rather than fail the build.\n let inputHash: string;\n try {\n inputHash = combineHash(hashFiles(allDeps), contextHash);\n } catch {\n return;\n }\n\n const contentHash = hashContent(content);\n\n store.storeBundleContent(cacheKey, content);\n\n store.setEntry(cacheKey, {\n kind: \"bundle\",\n inputHash,\n dependencyPaths: allDeps,\n outputFiles: [{ outputPath: cacheKey, contentHash }],\n createdAt: new Date().toISOString(),\n });\n }\n\n return { tryRestore, save };\n}\n\nexport { computeBundlerContextHash, createBundleCache, withCache };\nexport type { BundleCache };\n","import { assertDefined } from \"#/utils/assert\";\nimport type {\n Expression,\n CallExpression,\n StaticMemberExpression,\n ObjectPropertyKind,\n ObjectProperty,\n ArrowFunctionExpression,\n Function as FunctionExpression,\n} from \"@oxc-project/types\";\n\n/** A generic AST node for walking purposes */\nexport type ASTNode = Record<string, unknown>;\n\nexport interface Replacement {\n start: number;\n end: number;\n text: string;\n}\n\nexport interface StartCallInfo {\n identifierName: string;\n callRange: { start: number; end: number };\n argsText: string;\n optionsText?: string;\n}\n\nexport interface FoundProperty {\n key: ObjectProperty[\"key\"];\n value: Expression;\n start: number;\n end: number;\n}\n\n/**\n * Read an import or export name from an OXC identifier or string-literal node.\n * @param node - Import/export name node\n * @returns Module binding name, or undefined for an unsupported node\n */\nexport function getModuleExportName(node: unknown): string | undefined {\n if (!node || typeof node !== \"object\") return undefined;\n const exportName = node as { name?: string; value?: unknown };\n if (exportName.name) return exportName.name;\n return typeof exportName.value === \"string\" ? exportName.value : undefined;\n}\n\n/**\n * Check if a module source is from the Tailor SDK package (including subpaths)\n * @param source - Module source string\n * @returns True if the source is from the Tailor SDK package\n */\nexport function isTailorSdkSource(source: string): boolean {\n return /^@tailor-platform\\/sdk(\\/|$)/.test(source);\n}\n\n/**\n * Get the source string from a dynamic import or require call\n * @param node - AST node to inspect\n * @returns Resolved import/require source string or null\n */\nexport function getImportSource(node: Expression | null | undefined): string | null {\n if (!node) return null;\n // await import(\"@tailor-platform/sdk\")\n if (node.type === \"ImportExpression\") {\n const importExpr = node;\n const source = importExpr.source;\n if (source.type === \"Literal\" && typeof source.value === \"string\") {\n return source.value;\n }\n }\n // require(\"@tailor-platform/sdk\")\n if (node.type === \"CallExpression\") {\n const callExpr = node;\n if (callExpr.callee.type === \"Identifier\" && callExpr.callee.name === \"require\") {\n const arg = callExpr.arguments[0];\n if (\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n arg &&\n \"type\" in arg &&\n arg.type === \"Literal\" &&\n \"value\" in arg &&\n typeof arg.value === \"string\"\n ) {\n return arg.value;\n }\n }\n }\n return null;\n}\n\nfunction argumentSourceText(arg: unknown, sourceText: string): string | undefined {\n if (arg && typeof arg === \"object\" && \"start\" in arg && \"end\" in arg) {\n return sourceText.slice(arg.start as number, arg.end as number);\n }\n return undefined;\n}\n\n/**\n * Get metadata for a static `identifier.start(...)` call.\n * @param node - AST node to inspect\n * @param sourceText - Source code text\n * @returns Start call metadata, or null when the node is not a start call\n */\nexport function getStartCallInfo(\n node: ASTNode | null | undefined,\n sourceText: string,\n): StartCallInfo | null {\n if (!node || typeof node !== \"object\" || node.type !== \"CallExpression\") {\n return null;\n }\n\n const callExpr = node as unknown as CallExpression;\n const callee = callExpr.callee;\n if (callee.type !== \"MemberExpression\") {\n return null;\n }\n\n const memberExpr = callee as unknown as StaticMemberExpression;\n if (\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n memberExpr.computed ||\n memberExpr.property.name !== \"start\" ||\n memberExpr.object.type !== \"Identifier\"\n ) {\n return null;\n }\n\n return {\n identifierName: memberExpr.object.name,\n callRange: { start: callExpr.start, end: callExpr.end },\n argsText: argumentSourceText(callExpr.arguments[0], sourceText) ?? \"\",\n optionsText: argumentSourceText(callExpr.arguments[1], sourceText),\n };\n}\n\n/**\n * Unwrap AwaitExpression to get the inner expression\n * @param node - AST expression node\n * @returns Inner expression if node is an AwaitExpression\n */\nexport function unwrapAwait(node: Expression | null | undefined): Expression | null | undefined {\n if (node?.type === \"AwaitExpression\") {\n return node.argument;\n }\n return node;\n}\n\n/**\n * Check if a node is a string literal\n * @param node - AST expression node\n * @returns True if node is a string literal\n */\nexport function isStringLiteral(\n node: Expression | null | undefined,\n): node is Expression & { type: \"Literal\"; value: string } {\n // Note: oxc uses \"Literal\" for all literals, distinguishing by value type\n return node?.type === \"Literal\" && typeof (node as { value?: unknown }).value === \"string\";\n}\n\n/**\n * Check if a node is a function expression (arrow or regular)\n * @param node - AST expression node\n * @returns True if node is a function expression\n */\nexport function isFunctionExpression(\n node: Expression | null | undefined,\n): node is ArrowFunctionExpression | FunctionExpression {\n return node?.type === \"ArrowFunctionExpression\" || node?.type === \"FunctionExpression\";\n}\n\n/**\n * Find a property in an object expression\n * @param properties - Object properties to search\n * @param name - Property name to find\n * @returns Found property info or null\n */\nexport function findProperty(properties: ObjectPropertyKind[], name: string): FoundProperty | null {\n for (const prop of properties) {\n // Note: oxc uses \"Property\" for object properties\n if (prop.type === \"Property\") {\n const objProp = prop;\n const keyName =\n objProp.key.type === \"Identifier\"\n ? objProp.key.name\n : objProp.key.type === \"Literal\"\n ? (objProp.key as { value?: string }).value\n : null;\n if (keyName === name) {\n return {\n key: objProp.key,\n value: objProp.value,\n start: objProp.start,\n end: objProp.end,\n };\n }\n }\n }\n return null;\n}\n\n/**\n * Apply string replacements to source code\n * Replacements are applied from end to start to maintain positions\n * Ranges must not overlap; applying an overlapping range on top of an\n * already-shifted string would splice at stale offsets and corrupt the output,\n * so overlap is rejected up front\n * @param source - Original source code\n * @param replacements - Replacements to apply\n * @returns Transformed source code\n */\nexport function applyReplacements(source: string, replacements: Replacement[]): string {\n const sorted = replacements.toSorted((a, b) => b.start - a.start);\n for (let i = 0; i + 1 < sorted.length; i++) {\n const current = assertDefined(sorted[i], `replacement missing at index ${i}`);\n const previous = assertDefined(sorted[i + 1], `replacement missing at index ${i + 1}`);\n if (previous.end > current.start) {\n throw new Error(\n `applyReplacements: overlapping replacement ranges ` +\n `[${previous.start}, ${previous.end}) and [${current.start}, ${current.end})`,\n );\n }\n }\n let result = source;\n for (const r of sorted) {\n result = result.slice(0, r.start) + r.text + result.slice(r.end);\n }\n return result;\n}\n\n/**\n * Find the end of a statement including any trailing newline\n * @param source - Source code\n * @param position - Start position of the statement\n * @returns Index of the end of the statement including trailing newline\n */\nexport function findStatementEnd(source: string, position: number): number {\n let i = position;\n // Skip any trailing semicolons and whitespace on the same line\n while (i < source.length && (source[i] === \";\" || source[i] === \" \" || source[i] === \"\\t\")) {\n i++;\n }\n // Include the newline if present\n if (i < source.length && source[i] === \"\\n\") {\n i++;\n }\n return i;\n}\n","import { type ASTNode, isTailorSdkSource, getImportSource, unwrapAwait } from \"./ast-utils\";\nimport type {\n Program,\n ImportDeclaration,\n VariableDeclaration,\n CallExpression,\n StaticMemberExpression,\n} from \"@oxc-project/types\";\n\n/**\n * Collect all import bindings for a specific function from the Tailor SDK package\n * Returns a Set of local names that refer to the function\n * @param program - Parsed TypeScript program\n * @param functionName - Function name to collect bindings for\n * @returns Set of local names bound to the SDK function\n */\nexport function collectSdkBindings(program: Program, functionName: string): Set<string> {\n const bindings = new Set<string>();\n\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n\n const nodeType = node.type as string | undefined;\n\n // Static imports: import { createWorkflowJob } from \"@tailor-platform/sdk\"\n if (nodeType === \"ImportDeclaration\") {\n const importDecl = node as unknown as ImportDeclaration;\n const source = importDecl.source.value;\n if (typeof source === \"string\" && isTailorSdkSource(source)) {\n for (const specifier of importDecl.specifiers) {\n // import { createWorkflowJob } from \"@tailor-platform/sdk\"\n // import { createWorkflowJob as create } from \"@tailor-platform/sdk\"\n if (specifier.type === \"ImportSpecifier\") {\n const importSpec = specifier;\n const imported =\n importSpec.imported.type === \"Identifier\"\n ? importSpec.imported.name\n : (importSpec.imported as { value?: string }).value;\n if (imported === functionName) {\n bindings.add(importSpec.local.name);\n }\n }\n // import sdk from \"@tailor-platform/sdk\" → sdk.createWorkflowJob\n // import * as sdk from \"@tailor-platform/sdk\" → sdk.createWorkflowJob\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable typescript/no-unnecessary-condition\n else if (\n specifier.type === \"ImportDefaultSpecifier\" ||\n specifier.type === \"ImportNamespaceSpecifier\"\n // oxlint-enable typescript/no-unnecessary-condition\n ) {\n const spec = specifier;\n // Store namespace/default with special prefix to track member access\n bindings.add(`__namespace__:${spec.local.name}`);\n }\n }\n }\n }\n\n // Dynamic imports and require:\n // const sdk = await import(\"@tailor-platform/sdk\")\n // const sdk = require(\"@tailor-platform/sdk\")\n // const { createWorkflowJob } = await import(\"@tailor-platform/sdk\")\n // const { createWorkflowJob } = require(\"@tailor-platform/sdk\")\n if (nodeType === \"VariableDeclaration\") {\n const varDecl = node as unknown as VariableDeclaration;\n for (const decl of varDecl.declarations) {\n const init = unwrapAwait(decl.init);\n const source = getImportSource(init);\n\n if (source && isTailorSdkSource(source)) {\n const id = decl.id;\n\n // const sdk = await import(...) / const sdk = require(...)\n if (id.type === \"Identifier\") {\n bindings.add(`__namespace__:${id.name}`);\n }\n // const { createWorkflowJob } = await import(...) / require(...)\n // const { createWorkflowJob: create } = await import(...) / require(...)\n else if (id.type === \"ObjectPattern\") {\n const objPattern = id;\n for (const prop of objPattern.properties) {\n if (prop.type === \"Property\") {\n const bindingProp = prop;\n const keyName =\n bindingProp.key.type === \"Identifier\"\n ? bindingProp.key.name\n : (bindingProp.key as { value?: string }).value;\n if (keyName === functionName) {\n const localName =\n bindingProp.value.type === \"Identifier\" ? bindingProp.value.name : keyName;\n bindings.add(localName);\n }\n }\n }\n }\n }\n }\n }\n\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return bindings;\n}\n\n/**\n * Check if a CallExpression is a call to a specific SDK function\n * @param node - AST node to inspect\n * @param bindings - Collected SDK bindings\n * @param functionName - SDK function name\n * @returns True if node is a call to the SDK function\n */\nexport function isSdkFunctionCall(\n node: ASTNode,\n bindings: Set<string>,\n functionName: string,\n): node is ASTNode & { type: \"CallExpression\" } {\n if (node.type !== \"CallExpression\") return false;\n\n const callExpr = node as unknown as CallExpression;\n const callee = callExpr.callee;\n\n // Direct call: createWorkflowJob(...) or create(...)\n if (callee.type === \"Identifier\") {\n const identifier = callee;\n return bindings.has(identifier.name);\n }\n\n // Member access: sdk.createWorkflowJob(...)\n // Note: oxc uses MemberExpression with computed: false for static member access\n if (callee.type === \"MemberExpression\") {\n const memberExpr = callee as unknown as StaticMemberExpression;\n // callee may be a ComputedMemberExpression at runtime\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n if (!memberExpr.computed) {\n const object = memberExpr.object;\n const property = memberExpr.property;\n if (\n object.type === \"Identifier\" &&\n bindings.has(`__namespace__:${object.name}`) &&\n property.name === functionName\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n","import { assertDefined } from \"#/utils/assert\";\nimport { type ASTNode, isStringLiteral, isFunctionExpression, findProperty } from \"./ast-utils\";\nimport { collectSdkBindings, isSdkFunctionCall } from \"./sdk-binding-collector\";\nimport type { Program, CallExpression } from \"@oxc-project/types\";\n\nexport interface JobLocation {\n name: string;\n exportName?: string;\n nameRange: { start: number; end: number };\n bodyValueRange: { start: number; end: number };\n // Range of the entire variable declaration statement (for removal)\n statementRange?: { start: number; end: number };\n}\n\n/**\n * Find all workflow jobs by detecting createWorkflowJob calls from `@tailor-platform/sdk`\n * @param program - Parsed TypeScript program\n * @param _sourceText - Source code text (currently unused)\n * @returns Detected job locations\n */\nexport function findAllJobs(program: Program, _sourceText: string): JobLocation[] {\n const jobs: JobLocation[] = [];\n const bindings = collectSdkBindings(program, \"createWorkflowJob\");\n\n function walk(node: ASTNode | null | undefined, parents: ASTNode[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Detect createWorkflowJob(...) calls\n if (isSdkFunctionCall(node, bindings, \"createWorkflowJob\")) {\n const callExpr = node as unknown as CallExpression;\n const args = callExpr.arguments;\n const firstArg = args[0];\n if (args.length >= 1 && firstArg?.type === \"ObjectExpression\") {\n const configObj = assertDefined(firstArg, \"createWorkflowJob first argument missing\");\n const nameProp = findProperty(configObj.properties, \"name\");\n const bodyProp = findProperty(configObj.properties, \"body\");\n\n if (\n nameProp &&\n isStringLiteral(nameProp.value) &&\n bodyProp &&\n isFunctionExpression(bodyProp.value)\n ) {\n // Find the outermost enclosing statement and export name\n // Iterate from closest parent (end of array) to farthest (start of array)\n let statementRange: { start: number; end: number } | undefined;\n let exportName: string | undefined;\n for (let i = parents.length - 1; i >= 0; i--) {\n const parent = assertDefined(parents[i], `parent at index ${i} missing`);\n if (parent.type === \"VariableDeclarator\") {\n const declarator = parent as unknown as {\n id?: { type?: string; name?: string };\n };\n if (declarator.id?.type === \"Identifier\") {\n exportName = declarator.id.name;\n }\n }\n // Keep track of the outermost statement (ExportNamedDeclaration > VariableDeclaration)\n if (parent.type === \"ExportNamedDeclaration\" || parent.type === \"VariableDeclaration\") {\n statementRange = {\n start: parent.start as number,\n end: parent.end as number,\n };\n // Don't break - continue to find ExportNamedDeclaration if it exists\n }\n }\n\n jobs.push({\n name: nameProp.value.value,\n exportName,\n nameRange: { start: nameProp.start, end: nameProp.end },\n bodyValueRange: {\n start: bodyProp.value.start,\n end: bodyProp.value.end,\n },\n statementRange,\n });\n }\n }\n }\n\n const newParents = [...parents, node];\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null, newParents));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode, newParents);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return jobs;\n}\n","import { assertDefined } from \"#/utils/assert\";\nimport { type ASTNode, isStringLiteral, findProperty } from \"./ast-utils\";\nimport { collectSdkBindings, isSdkFunctionCall } from \"./sdk-binding-collector\";\nimport type { Program, CallExpression } from \"@oxc-project/types\";\n\nexport interface WorkflowLocation {\n name: string;\n exportName?: string;\n isDefaultExport?: boolean;\n}\n\n/**\n * Find all workflows by detecting createWorkflow calls from `@tailor-platform/sdk`\n * @param program - Parsed TypeScript program\n * @param _sourceText - Source code text (currently unused)\n * @returns Detected workflows\n */\nexport function findAllWorkflows(program: Program, _sourceText: string): WorkflowLocation[] {\n const workflows: WorkflowLocation[] = [];\n const bindings = collectSdkBindings(program, \"createWorkflow\");\n\n function walk(node: ASTNode | null | undefined, parents: ASTNode[] = []): void {\n if (!node || typeof node !== \"object\") return;\n\n // Detect createWorkflow(...) calls\n if (isSdkFunctionCall(node, bindings, \"createWorkflow\")) {\n const callExpr = node as unknown as CallExpression;\n const args = callExpr.arguments;\n const firstArg = args[0];\n if (args.length >= 1 && firstArg?.type === \"ObjectExpression\") {\n const configObj = assertDefined(firstArg, \"createWorkflow first argument missing\");\n const nameProp = findProperty(configObj.properties, \"name\");\n\n if (nameProp && isStringLiteral(nameProp.value)) {\n // Find export name from parent declarations\n let exportName: string | undefined;\n let isDefaultExport = false;\n for (let i = parents.length - 1; i >= 0; i--) {\n const parent = assertDefined(parents[i], `parent at index ${i} missing`);\n if (parent.type === \"VariableDeclarator\") {\n const declarator = parent as unknown as {\n id?: { type?: string; name?: string };\n };\n if (declarator.id?.type === \"Identifier\") {\n exportName = declarator.id.name;\n break;\n }\n }\n // Check for export default createWorkflow(...)\n if (parent.type === \"ExportDefaultDeclaration\") {\n isDefaultExport = true;\n }\n }\n\n workflows.push({\n name: nameProp.value.value,\n exportName,\n isDefaultExport,\n });\n }\n }\n }\n\n const newParents = [...parents, node];\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null, newParents));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode, newParents);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return workflows;\n}\n","import * as fs from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport { loadFilesWithIgnores, type FileLoadConfig } from \"#/cli/services/file-loader\";\nimport { getModuleExportName, type ASTNode } from \"#/cli/services/workflow/ast-utils\";\nimport { findAllJobs } from \"#/cli/services/workflow/job-detector\";\nimport { findAllWorkflows } from \"#/cli/services/workflow/workflow-detector\";\nimport { logger } from \"#/cli/shared/logger\";\n\nexport interface StartTarget {\n kind: \"job\" | \"workflow\";\n name: string;\n}\n\nexport interface StartModuleBindings {\n sourceFile: string;\n localBindings: Map<string, StartTarget>;\n exports: Map<string, StartTarget>;\n}\n\nexport interface StartContext {\n modules: Map<string, StartModuleBindings>;\n authNamespace?: string;\n}\n\n/**\n * Normalize a source module path for start-call binding lookup.\n * @param filePath - Source file path or extensionless relative import path\n * @returns Absolute path without a JavaScript or TypeScript extension\n */\nexport function normalizeFilePath(filePath: string): string {\n return path.resolve(filePath.replace(/[?#].*$/, \"\")).replace(/\\.(ts|mts|cts|js|mjs|cjs)$/, \"\");\n}\n\nfunction createModuleBindings(\n sourceFile: string,\n program: ReturnType<typeof parseSync>[\"program\"],\n source: string,\n) {\n const localBindings = new Map<string, StartTarget>();\n const exports = new Map<string, StartTarget>();\n\n for (const workflow of findAllWorkflows(program, source)) {\n const target = { kind: \"workflow\", name: workflow.name } as const;\n if (workflow.exportName) localBindings.set(workflow.exportName, target);\n if (workflow.isDefaultExport) exports.set(\"default\", target);\n }\n\n for (const job of findAllJobs(program, source)) {\n if (job.exportName) {\n localBindings.set(job.exportName, { kind: \"job\", name: job.name });\n }\n }\n\n for (const statement of program.body as unknown as ASTNode[]) {\n if (statement.type === \"ExportDefaultDeclaration\") {\n const declaration = statement.declaration as ASTNode | undefined;\n if (declaration?.type === \"Identifier\") {\n const target = localBindings.get(declaration.name as string);\n if (target) exports.set(\"default\", target);\n }\n continue;\n }\n\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const declaration = statement.declaration as ASTNode | undefined;\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of declaration.declarations as ASTNode[]) {\n const id = declarator.id as ASTNode | undefined;\n if (id?.type !== \"Identifier\") continue;\n const localName = id.name as string;\n const target = localBindings.get(localName);\n if (target) exports.set(localName, target);\n }\n }\n\n if (statement.source) continue;\n for (const specifier of (statement.specifiers as ASTNode[] | undefined) ?? []) {\n const localName = getModuleExportName(specifier.local);\n const exportedName = getModuleExportName(specifier.exported);\n if (!localName || !exportedName) continue;\n const target = localBindings.get(localName);\n if (target) exports.set(exportedName, target);\n }\n }\n\n return { sourceFile, localBindings, exports } satisfies StartModuleBindings;\n}\n\n/**\n * Build start-call context from configured workflow source files.\n * @param workflowConfig - Workflow file loading configuration\n * @param authNamespace - Auth service namespace (optional, used for string-literal invoker expansion)\n * @param baseDir - Directory the workflow config's file patterns are resolved against (defaults to process.cwd())\n * @returns Module-local workflow and job binding metadata\n */\nexport async function buildStartContext(\n workflowConfig: FileLoadConfig | undefined,\n authNamespace?: string,\n baseDir = process.cwd(),\n): Promise<StartContext> {\n const modules = new Map<string, StartModuleBindings>();\n if (!workflowConfig) return { modules, authNamespace };\n\n for (const file of loadFilesWithIgnores(workflowConfig, baseDir)) {\n try {\n const source = await fs.promises.readFile(file, \"utf-8\");\n const { program, errors } = parseSync(file, source);\n if (errors.length > 0) {\n logger.warn(\n `Failed to parse workflow file ${file}: ${errors.map((e) => e.message).join(\"; \")}`,\n { mode: \"stream\" },\n );\n continue;\n }\n modules.set(normalizeFilePath(file), createModuleBindings(file, program, source));\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(`Failed to process workflow file ${file}: ${errorMessage}`, {\n mode: \"stream\",\n });\n }\n }\n\n return { modules, authNamespace };\n}\n\nfunction sortedTargets(bindings: Map<string, StartTarget>) {\n return [...bindings]\n .toSorted(([a], [b]) => a.localeCompare(b))\n .map(([binding, target]) => [binding, target.kind, target.name]);\n}\n\n/**\n * Serialize start-call context to a deterministic cache input.\n * @param context - Start-call context to serialize\n * @returns Deterministic string, or an empty string when context is absent\n */\nexport function serializeStartContext(context: StartContext | undefined): string {\n if (!context) return \"\";\n const modules = [...context.modules]\n .toSorted(([a], [b]) => a.localeCompare(b))\n .map(([file, bindings]) => [\n file,\n sortedTargets(bindings.localBindings),\n sortedTargets(bindings.exports),\n ]);\n return JSON.stringify(modules) + (context.authNamespace ?? \"\");\n}\n","import { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport { logger } from \"#/cli/shared/logger\";\nimport {\n normalizeFilePath,\n type StartContext,\n type StartModuleBindings,\n type StartTarget,\n} from \"#/cli/shared/start-context\";\nimport {\n type ASTNode,\n type Replacement,\n type StartCallInfo,\n applyReplacements,\n getModuleExportName,\n getStartCallInfo,\n} from \"./ast-utils\";\nimport type { Program } from \"@oxc-project/types\";\nimport type { Plugin } from \"rolldown\";\n\nexport interface ResolvedStartCall extends StartCallInfo {\n kind: \"job\" | \"workflow\";\n targetName: string;\n}\n\nconst START_CALL_RE = /\\.start(?:\\s|\\/\\*[\\s\\S]*?\\*\\/|\\/\\/[^\\n]*\\n)*\\(/;\n\n/**\n * Fast pre-check for whether `code` contains a `.start(` call, tolerating\n * whitespace, newlines, and comments between `.start` and `(` that a plain\n * substring check would miss.\n * @param code - Source text to scan\n * @returns Whether `code` contains a `.start(` call\n */\nexport function hasStartCall(code: string): boolean {\n return START_CALL_RE.test(code);\n}\n\nconst NORMALIZER_IDENTIFIER = \"__tailor_normalizeStartOptions\";\n\n/**\n * Build the source text of the injected normalizer helper.\n *\n * Renames an `invoker` in the start options to the `authInvoker` form the\n * platform RPC expects: a plain string (machine user name) becomes\n * `{ namespace, machineUserName }`, while an object form passes through\n * as-is. Any other options value is unchanged. The auth namespace is baked\n * in at bundle time.\n * @param authNamespace - Auth service namespace to embed\n * @returns Source line defining the helper\n */\nfunction buildNormalizerHelperSource(authNamespace: string): string {\n return `const ${NORMALIZER_IDENTIFIER} = (o) => { if (!o) return o; const { invoker, ...rest } = o; return typeof invoker === \"string\" ? { ...rest, authInvoker: { namespace: ${JSON.stringify(authNamespace)}, machineUserName: invoker } } : typeof invoker === \"object\" ? { ...rest, authInvoker: invoker } : o; };\\n`;\n}\n\nfunction collectBindingNames(node: ASTNode | null | undefined, names: Set<string>): void {\n if (!node || typeof node !== \"object\") return;\n\n switch (node.type) {\n case \"Identifier\":\n names.add(node.name as string);\n return;\n case \"ObjectPattern\":\n for (const property of node.properties as ASTNode[]) {\n collectBindingNames(\n property.type === \"RestElement\"\n ? (property.argument as ASTNode)\n : (property.value as ASTNode),\n names,\n );\n }\n return;\n case \"ArrayPattern\":\n for (const element of node.elements as Array<ASTNode | null>) {\n collectBindingNames(element, names);\n }\n return;\n case \"AssignmentPattern\":\n collectBindingNames(node.left as ASTNode, names);\n return;\n case \"RestElement\":\n collectBindingNames(node.argument as ASTNode, names);\n return;\n case \"TSParameterProperty\":\n collectBindingNames(node.parameter as ASTNode, names);\n }\n}\n\nfunction declarationNode(statement: ASTNode): ASTNode | undefined {\n return statement.type === \"ExportNamedDeclaration\" ||\n statement.type === \"ExportDefaultDeclaration\"\n ? (statement.declaration as ASTNode | undefined)\n : statement;\n}\n\nfunction collectBlockBindings(statements: ASTNode[], names: Set<string>): void {\n for (const statement of statements) {\n const declaration = declarationNode(statement);\n if (!declaration) continue;\n\n if (declaration.type === \"VariableDeclaration\") {\n if (declaration.kind === \"var\") continue;\n for (const declarator of declaration.declarations as ASTNode[]) {\n collectBindingNames(declarator.id as ASTNode, names);\n }\n } else if (\n declaration.type === \"FunctionDeclaration\" ||\n declaration.type === \"ClassDeclaration\"\n ) {\n collectBindingNames(declaration.id as ASTNode | undefined, names);\n }\n }\n}\n\nfunction collectFunctionVarBindings(root: ASTNode, names: Set<string>): void {\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n if (\n node !== root &&\n (node.type === \"FunctionDeclaration\" ||\n node.type === \"FunctionExpression\" ||\n node.type === \"ArrowFunctionExpression\" ||\n node.type === \"StaticBlock\")\n ) {\n return;\n }\n if (node.type === \"VariableDeclaration\" && node.kind === \"var\") {\n for (const declarator of node.declarations as ASTNode[]) {\n collectBindingNames(declarator.id as ASTNode, names);\n }\n }\n for (const key of Object.keys(node)) {\n if (key === \"parent\") continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) walk(item as ASTNode | null);\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(root);\n}\n\nfunction collectScopeBindings(node: ASTNode): Set<string> | undefined {\n const names = new Set<string>();\n\n if (\n node.type === \"FunctionDeclaration\" ||\n node.type === \"FunctionExpression\" ||\n node.type === \"ArrowFunctionExpression\"\n ) {\n collectBindingNames(node.id as ASTNode | undefined, names);\n for (const parameter of node.params as ASTNode[]) {\n collectBindingNames(parameter, names);\n }\n collectFunctionVarBindings(node, names);\n return names;\n }\n\n if (node.type === \"BlockStatement\") {\n collectBlockBindings(node.body as ASTNode[], names);\n return names;\n }\n\n if (node.type === \"CatchClause\") {\n collectBindingNames(node.param as ASTNode | undefined, names);\n return names;\n }\n\n if (\n node.type === \"ForStatement\" ||\n node.type === \"ForInStatement\" ||\n node.type === \"ForOfStatement\"\n ) {\n const declaration = (node.init ?? node.left) as ASTNode | undefined;\n if (declaration?.type === \"VariableDeclaration\" && declaration.kind !== \"var\") {\n for (const declarator of declaration.declarations as ASTNode[]) {\n collectBindingNames(declarator.id as ASTNode, names);\n }\n }\n return names;\n }\n\n return undefined;\n}\n\nfunction addShadowedBindings(\n shadowedNames: ReadonlySet<string>,\n bindings: Set<string> | undefined,\n targetNames: ReadonlySet<string>,\n): ReadonlySet<string> {\n if (!bindings) return shadowedNames;\n const relevantBindings = [...bindings].filter((name) => targetNames.has(name));\n return relevantBindings.length === 0\n ? shadowedNames\n : new Set([...shadowedNames, ...relevantBindings]);\n}\n\nfunction walkBindingAware(\n program: Program,\n targetNames: ReadonlySet<string>,\n visitor: (\n node: ASTNode,\n shadowedNames: ReadonlySet<string>,\n parentNode?: ASTNode,\n parentKey?: string,\n ) => void,\n): void {\n function walk(\n node: ASTNode | null | undefined,\n shadowedNames: ReadonlySet<string>,\n parentNode?: ASTNode,\n parentKey?: string,\n ): void {\n if (!node || typeof node !== \"object\" || node.type === \"ImportDeclaration\") return;\n\n const nestedShadowedNames =\n node.type === \"Program\"\n ? shadowedNames\n : addShadowedBindings(shadowedNames, collectScopeBindings(node), targetNames);\n visitor(node, nestedShadowedNames, parentNode, parentKey);\n\n for (const key of Object.keys(node)) {\n if (key === \"parent\") continue;\n const child = node[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n walk(item as ASTNode | null, nestedShadowedNames, node, key);\n }\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode, nestedShadowedNames, node, key);\n }\n }\n }\n\n walk(program as unknown as ASTNode, new Set());\n}\n\nfunction resolveRelativeImport(\n context: StartContext,\n currentFilePath: string,\n importSource: string,\n): StartModuleBindings | undefined {\n if (!importSource.startsWith(\".\")) return undefined;\n const currentDirectory = path.dirname(currentFilePath.replace(/[?#].*$/, \"\"));\n const modulePath = normalizeFilePath(path.resolve(currentDirectory, importSource));\n return context.modules.get(modulePath) ?? context.modules.get(path.join(modulePath, \"index\"));\n}\n\nfunction collectLocalTargets(\n program: Program,\n context: StartContext,\n currentFilePath: string,\n): Map<string, StartTarget> {\n const targets = new Map<string, StartTarget>();\n const currentModule = context.modules.get(normalizeFilePath(currentFilePath));\n if (currentModule) {\n for (const [localName, target] of currentModule.localBindings) {\n targets.set(localName, target);\n }\n }\n\n for (const statement of program.body) {\n if (statement.type !== \"ImportDeclaration\" || statement.importKind === \"type\") continue;\n const importSource = statement.source.value;\n if (typeof importSource !== \"string\") continue;\n const importedModule = resolveRelativeImport(context, currentFilePath, importSource);\n if (!importedModule) continue;\n\n for (const specifier of statement.specifiers) {\n if (specifier.type === \"ImportNamespaceSpecifier\") continue;\n if (specifier.type === \"ImportSpecifier\" && specifier.importKind === \"type\") continue;\n\n const importedName =\n specifier.type === \"ImportDefaultSpecifier\"\n ? \"default\"\n : getModuleExportName(specifier.imported);\n if (!importedName) continue;\n const target = importedModule.exports.get(importedName);\n if (!target) continue;\n targets.set(specifier.local.name, target);\n }\n }\n\n return targets;\n}\n\nfunction detectStartCallsWithTargets(\n program: Program,\n sourceText: string,\n targets: Map<string, StartTarget>,\n): ResolvedStartCall[] {\n const calls: ResolvedStartCall[] = [];\n const targetNames = new Set(targets.keys());\n\n walkBindingAware(program, targetNames, (node, shadowedNames) => {\n const startCall = getStartCallInfo(node, sourceText);\n if (!startCall || shadowedNames.has(startCall.identifierName)) return;\n const target = targets.get(startCall.identifierName);\n if (target) {\n calls.push({ ...startCall, kind: target.kind, targetName: target.name });\n }\n });\n\n return calls;\n}\n\nexport function detectResolvedStartCalls(\n program: Program,\n sourceText: string,\n context: StartContext,\n currentFilePath: string,\n): ResolvedStartCall[] {\n return detectStartCallsWithTargets(\n program,\n sourceText,\n collectLocalTargets(program, context, currentFilePath),\n );\n}\n\nexport function transformStartCalls(\n source: string,\n startContext: StartContext,\n currentFilePath: string,\n): string {\n const { program } = parseSync(\"input.ts\", source);\n const localTargets = collectLocalTargets(program, startContext, currentFilePath);\n const { authNamespace } = startContext;\n const allStartCalls = detectStartCallsWithTargets(program, source, localTargets);\n const nestedStartCalls: Array<{ call: ResolvedStartCall; parent: ResolvedStartCall }> = [];\n const startCalls = allStartCalls.filter((call) => {\n const parent = allStartCalls.find(\n (other) =>\n other !== call &&\n other.callRange.start <= call.callRange.start &&\n call.callRange.end <= other.callRange.end,\n );\n if (!parent) return true;\n nestedStartCalls.push({ call, parent });\n return false;\n });\n\n for (const { call, parent } of nestedStartCalls) {\n logger.warn(\n `Nested start call \"${call.identifierName}.start(...)\" inside \"${parent.identifierName}.start(...)\" cannot be converted. Move it to a separate statement and pass the result instead.`,\n );\n }\n\n const replacements: Replacement[] = [];\n // Whether any workflow start invoker was wrapped with the runtime\n // normalizer. Used to decide whether to inject the helper at the top.\n let needsNormalizerHelper = false;\n\n for (const call of startCalls) {\n let transformedCall: string;\n if (call.kind === \"workflow\") {\n let optionsPart = \"\";\n if (call.optionsText !== undefined) {\n if (authNamespace) {\n optionsPart = `, ${NORMALIZER_IDENTIFIER}(${call.optionsText})`;\n needsNormalizerHelper = true;\n } else {\n optionsPart = `, ${call.optionsText}`;\n }\n }\n transformedCall = `tailor.workflow.startWorkflow(${JSON.stringify(call.targetName)}, ${call.argsText || \"undefined\"}${optionsPart})`;\n } else {\n const optionsPart = call.optionsText !== undefined ? `, ${call.optionsText}` : \"\";\n transformedCall = `tailor.workflow.execJobFunction(${JSON.stringify(call.targetName)}, ${call.argsText || \"undefined\"}${optionsPart})`;\n }\n replacements.push({\n start: call.callRange.start,\n end: call.callRange.end,\n text: transformedCall,\n });\n }\n\n const transformed = applyReplacements(source, replacements);\n return needsNormalizerHelper && authNamespace\n ? buildNormalizerHelperSource(authNamespace) + transformed\n : transformed;\n}\n\nexport function createStartTransformPlugin(\n startContext: StartContext | undefined,\n): Plugin | undefined {\n if (!startContext || startContext.modules.size === 0) return undefined;\n\n return {\n name: \"start-transform\",\n transform: {\n filter: { id: { include: [/\\.(ts|mts|cts|js|mjs|cjs)$/] } },\n handler(code, id) {\n if (!hasStartCall(code)) return null;\n return { code: transformStartCalls(code, startContext, id) };\n },\n },\n };\n}\n","import { CLIError } from \"#/cli/shared/errors\";\nimport { getNodeBuiltinMessage, isNodeBuiltinImport } from \"#/utils/node-builtins\";\nimport type * as rolldown from \"rolldown\";\n\n// rolldown externalizes an import it cannot resolve and reports it as a\n// warning, so a bundle that still contains the bare specifier would otherwise\n// deploy as a success and only fail once the platform runs it. `logLevel`\n// cannot stay `\"silent\"` here: rolldown's level gate drops warnings before\n// `onLog` is ever consulted, so the escalation only sees the log at `\"warn\"`.\n// Every other log stays suppressed by never delegating to `defaultHandler`.\nconst ESCALATED_LOG_CODE = \"UNRESOLVED_IMPORT\";\n\nexport interface BundleLogOptions {\n /** Absolute path of the tsconfig handed to rolldown, when one was resolved. */\n tsconfig?: string;\n}\n\ninterface BundleLogRolldownOptions {\n logLevel: \"warn\";\n onLog: NonNullable<rolldown.InputOptions[\"onLog\"]>;\n}\n\nexport interface BundleLog {\n options: BundleLogRolldownOptions;\n assertAllResolved(): void;\n}\n\n/**\n * Collect unresolved imports while keeping every other rolldown log suppressed.\n * @param options - Context used to explain which tsconfig was in effect\n * @returns Rolldown options and a post-build assertion\n */\nexport function createBundleLog(options: BundleLogOptions = {}): BundleLog {\n const unresolvedImports = new Map<string, rolldown.RollupLog>();\n return {\n options: {\n logLevel: \"warn\",\n onLog: (_level, log) => {\n if (log.code !== ESCALATED_LOG_CODE) return;\n unresolvedImports.set(JSON.stringify([log.exporter, log.id]), log);\n },\n },\n assertAllResolved() {\n if (unresolvedImports.size > 0) {\n throw unresolvedImportError([...unresolvedImports.values()], options.tsconfig);\n }\n },\n };\n}\n\nfunction unresolvedImportError(logs: rolldown.RollupLog[], tsconfig: string | undefined): Error {\n const imports = logs.map(formatUnresolvedImport);\n const message =\n imports.length === 1\n ? `Could not resolve ${imports[0]}.`\n : `Could not resolve ${imports.length} imports.`;\n const details = imports.length === 1 ? undefined : imports.map((item) => `- ${item}`).join(\"\\n\");\n const suggestion = unresolvedImportSuggestion(logs, tsconfig);\n return CLIError({\n code: \"UNRESOLVED_IMPORT\",\n message,\n details,\n suggestion,\n });\n}\n\nfunction unresolvedImportSuggestion(\n logs: rolldown.RollupLog[],\n tsconfig: string | undefined,\n): string {\n const nodeSuggestions = logs\n .map((log) => log.exporter)\n .filter((specifier): specifier is string => specifier !== undefined)\n .filter(isNodeBuiltinImport)\n .map(getNodeBuiltinMessage);\n const hasOtherImports = logs.some(\n (log) => log.exporter === undefined || !isNodeBuiltinImport(log.exporter),\n );\n const pathSuggestion = tsconfig\n ? `Check that each import path is correct, and that a \\`compilerOptions.paths\\` entry covering it is declared in the importing file's own tsconfig.json or an ancestor. The build used \"${tsconfig}\".`\n : \"No tsconfig.json was found, so `compilerOptions.paths` aliases were not applied. Add a tsconfig.json declaring the aliases these files import.\";\n return [...new Set([...nodeSuggestions, ...(hasOtherImports ? [pathSuggestion] : [])])].join(\n \"\\n\",\n );\n}\n\nfunction formatUnresolvedImport(log: rolldown.RollupLog): string {\n const specifier = log.exporter ?? \"an imported module\";\n // A virtual entry's id carries a leading `\\0`, which renders as a stray\n // control character; name the bundler's generated entry instead.\n const importerId = log.id?.startsWith(\"\\0\")\n ? `a generated entry (${log.id.slice(1)})`\n : log.id && `\"${log.id}\"`;\n const importer = importerId ? ` imported from ${importerId}` : \"\";\n return `\"${specifier}\"${importer}`;\n}\n","import { isLogLevel, LOG_LEVELS } from \"#/parser/app-config/log-level\";\nimport type { LogLevel, LogLevelInput } from \"#/configure/config/types\";\nimport type { TreeshakingOptions } from \"rolldown\";\n\nconst INFO_LEVEL_CONSOLE_METHODS = [\n \"console.info\",\n \"console.table\",\n \"console.dir\",\n \"console.dirxml\",\n \"console.count\",\n \"console.countReset\",\n \"console.time\",\n \"console.timeLog\",\n \"console.timeEnd\",\n \"console.group\",\n \"console.groupCollapsed\",\n \"console.groupEnd\",\n \"console.clear\",\n] as const;\n\n// `console.log` is treated as a DEBUG-level method to stay consistent with the\n// platform's OpenTelemetry severity mapping, where the deployment runtime emits\n// `console.log` at DEBUG severity rather than INFO.\nconst DEBUG_LEVEL_CONSOLE_METHODS = [\"console.debug\", \"console.log\", \"console.trace\"] as const;\n\nconst WARN_LEVEL_CONSOLE_METHODS = [\"console.warn\"] as const;\n\n// `console.assert` is intentionally excluded: on the deployment runtime\n// (deno_core/V8) only log/debug/info/warn/error are wrapped with a log\n// severity, so `console.assert` sits outside the platform's severity system\n// and is never dropped by the log-level treeshaking.\nconst ERROR_LEVEL_CONSOLE_METHODS = [\"console.error\"] as const;\n\n// `@tailor-platform/sdk/runtime`'s `logger` wrapper calls\n// `(globalThis as {...}).tailor.logger.*` (see runtime/logger.ts); the `as`\n// cast is erased by the time treeshaking runs, so the callee this matches\n// against is the `globalThis.tailor.logger.*` member chain, not `tailor.logger.*`.\nconst DEBUG_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.debug\"] as const;\n\nconst INFO_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.info\"] as const;\n\nconst WARN_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.warn\"] as const;\n\nconst ERROR_LEVEL_LOGGER_METHODS = [\"globalThis.tailor.logger.error\"] as const;\n\nconst MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL: Record<LogLevel, readonly string[]> = {\n DEBUG: [],\n INFO: [...DEBUG_LEVEL_CONSOLE_METHODS, ...DEBUG_LEVEL_LOGGER_METHODS],\n WARN: [\n ...DEBUG_LEVEL_CONSOLE_METHODS,\n ...INFO_LEVEL_CONSOLE_METHODS,\n ...DEBUG_LEVEL_LOGGER_METHODS,\n ...INFO_LEVEL_LOGGER_METHODS,\n ],\n ERROR: [\n ...DEBUG_LEVEL_CONSOLE_METHODS,\n ...INFO_LEVEL_CONSOLE_METHODS,\n ...WARN_LEVEL_CONSOLE_METHODS,\n ...DEBUG_LEVEL_LOGGER_METHODS,\n ...INFO_LEVEL_LOGGER_METHODS,\n ...WARN_LEVEL_LOGGER_METHODS,\n ],\n SILENT: [\n ...DEBUG_LEVEL_CONSOLE_METHODS,\n ...INFO_LEVEL_CONSOLE_METHODS,\n ...WARN_LEVEL_CONSOLE_METHODS,\n ...ERROR_LEVEL_CONSOLE_METHODS,\n ...DEBUG_LEVEL_LOGGER_METHODS,\n ...INFO_LEVEL_LOGGER_METHODS,\n ...WARN_LEVEL_LOGGER_METHODS,\n ...ERROR_LEVEL_LOGGER_METHODS,\n ],\n};\n\nexport function normalizeBundleLogLevel(value: string): LogLevel | undefined {\n const normalized = value.trim().toUpperCase();\n return isLogLevel(normalized) ? normalized : undefined;\n}\n\nexport function resolveBundleLogLevel(configValue?: LogLevelInput): LogLevel {\n if (configValue === undefined) return \"DEBUG\";\n const resolved = normalizeBundleLogLevel(configValue);\n if (resolved) return resolved;\n\n throw new Error(`Invalid logLevel \"${configValue}\". Expected one of: ${LOG_LEVELS.join(\", \")}`);\n}\n\nexport function manualPureFunctionsForLogLevel(logLevel: LogLevel): readonly string[] {\n return MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL[logLevel];\n}\n\nexport function createLogLevelTreeshakeOptions(logLevel: LogLevel): TreeshakingOptions {\n const manualPureFunctions = manualPureFunctionsForLogLevel(logLevel);\n return manualPureFunctions.length > 0 ? { manualPureFunctions } : {};\n}\n","import type { TreeshakingOptions } from \"rolldown\";\n\nconst BASE_FUNCTION_TREESHAKE_OPTIONS = {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n} as const satisfies TreeshakingOptions;\n\nexport function mergeFunctionTreeshakeOptions(\n fragments: readonly TreeshakingOptions[],\n): TreeshakingOptions {\n const merged: TreeshakingOptions = {};\n const manualPureFunctions = new Set<string>();\n\n for (const fragment of fragments) {\n Object.assign(merged, fragment);\n for (const name of fragment.manualPureFunctions ?? []) {\n manualPureFunctions.add(name);\n }\n }\n\n if (manualPureFunctions.size > 0) {\n merged.manualPureFunctions = [...manualPureFunctions];\n } else {\n delete merged.manualPureFunctions;\n }\n\n return merged;\n}\n\nexport function composeFunctionTreeshakeOptions(\n fragments: readonly TreeshakingOptions[] = [],\n): TreeshakingOptions {\n return mergeFunctionTreeshakeOptions([BASE_FUNCTION_TREESHAKE_OPTIONS, ...fragments]);\n}\n","import type * as rolldown from \"rolldown\";\n\n// Match the exact `process.env.__TAILOR_PLATFORM_BUNDLE` member-expression: the\n// leading lookbehind rejects a longer owner (`foo.process.env…`) or identifier,\n// the trailing `\\b` rejects a longer key (`…_BUNDLE_MODE`).\nconst GATE = /(?<![\\w$.])process\\.env\\.__TAILOR_PLATFORM_BUNDLE\\b/g;\n\n// Fold the gate to `true` so the minifier DCEs the test-only workflow\n// registry/serialize runner. Apply in every bundler that builds runnable\n// functions; a missed path leaves the env read in place and fails loudly on the\n// Platform's Web runtime (no `process`), which an e2e catches. rolldown exposes\n// no `define`, so this is a transform-level replace rather than a define.\n//\n// The fold above only proves the branch dead after transform+parse; rolldown\n// still resolves every top-level import a module contains before it can shake\n// the dead branch out of the output. `createWorkflowJob`'s test-only invoker\n// wrapper (test-env-key.ts, reachable from every bundler through the public\n// `createWorkflowJob` export) needs `node:async_hooks` for correct scoping\n// across concurrent local job invocations, but that specifier is never\n// available on the Platform runtime and is unreachable there once the gate\n// folds — so resolve it as external rather than failing the build over an\n// import that never survives to the bundled output.\nexport const platformBundleDefinePlugin: rolldown.Plugin = {\n name: \"tailor-platform-bundle-define\",\n transform(code) {\n if (!code.includes(\"process.env.__TAILOR_PLATFORM_BUNDLE\")) return null;\n return { code: code.replace(GATE, \"true\") };\n },\n resolveId(source) {\n if (source === \"node:async_hooks\") return { id: source, external: true };\n return null;\n },\n};\n","import { resolveTSConfig } from \"pkg-types\";\nimport { logger } from \"#/cli/shared/logger\";\n\n// resolveTSConfigWithFallback is called once per bundler/service, so a\n// single generate/apply run can call it multiple times for the same baseDir\n// (once per resolver/executor/tailordb/etc. config sharing that directory).\n// Track which baseDirs have already warned so each one only warns once per run.\nconst warnedBaseDirs = new Set<string>();\n\n/**\n * Resolve the nearest tsconfig.json for baseDir, falling back to the tsconfig\n * resolved from the invocation cwd when baseDir's own ancestry has none.\n * @param baseDir - Directory to resolve the tsconfig against\n * @returns Absolute path to the resolved tsconfig.json, or undefined if none was found\n */\nexport async function resolveTSConfigWithFallback(baseDir: string): Promise<string | undefined> {\n const tsconfig = await tryResolve(baseDir);\n if (tsconfig || baseDir === process.cwd()) {\n return tsconfig;\n }\n\n // v1 compatibility fallback: pre-existing configs may rely on a tsconfig\n // discoverable from the invocation cwd rather than baseDir. Remove this\n // fallback in v2, once such configs are expected to have migrated.\n const fallback = await tryResolve(process.cwd());\n if (fallback && !warnedBaseDirs.has(baseDir)) {\n warnedBaseDirs.add(baseDir);\n logger.warn(\n `No tsconfig found from \"${baseDir}\"; falling back to the tsconfig resolved from ` +\n `process.cwd(). Move (or extend) a tsconfig into this directory before ` +\n `v2, when this fallback will be removed.`,\n );\n }\n return fallback;\n}\n\nasync function tryResolve(dir: string): Promise<string | undefined> {\n try {\n return await resolveTSConfig(dir);\n } catch {\n return undefined;\n }\n}\n","import { type Cache, createPathsMatcher, getTsconfig } from \"get-tsconfig\";\nimport * as path from \"pathe\";\nimport type * as rolldown from \"rolldown\";\n\n// A bundler hands rolldown a single tsconfig, so its normal resolution applies\n// one `paths` table to every module in the graph. When that resolution misses an\n// import from another TypeScript project, this plugin retries it against the\n// importing file's nearest tsconfig, matching the runtime hook's lookup.\n//\n// Strictly a last resort. rolldown's `order: \"post\"` only orders this hook\n// against other plugins — it still runs ahead of the builtin resolver, and a\n// non-null return wins outright. So the handler asks rolldown to resolve the\n// specifier first and bails out when that succeeds, which keeps a real\n// node_modules package ahead of a `\"*\"` catch-all alias.\n\ntype ResolutionContext = {\n matcher: (specifier: string) => string[];\n};\n\n/**\n * The lookup cache {@link createTsconfigPathsPlugin} maintains internally by\n * default. Share one instance across every bundle in a CLI run (via the\n * `cache` option) so bundling many items — hundreds of resolvers, say — reads\n * and parses each ancestor tsconfig once instead of once per item.\n *\n * `get-tsconfig`'s `Cache` is a plain `Map`; concurrent bundles racing to\n * populate the same key recompute the same deterministic value and simply\n * overwrite each other, so sharing it across `withBundleConcurrency` workers\n * is safe.\n */\nexport interface TsconfigLookupCache {\n tsconfigCache: Cache;\n contextCache: Map<string, ResolutionContext | null>;\n}\n\n/**\n * Create a {@link TsconfigLookupCache} to share across every bundle in a CLI run.\n * @returns A fresh, empty lookup cache\n */\nexport function createTsconfigLookupCache(): TsconfigLookupCache {\n return { tsconfigCache: new Map(), contextCache: new Map() };\n}\n\nexport interface TsconfigPathsPluginOptions {\n /**\n * Source file a bundler's virtual entry was built from. A virtual entry has no\n * directory of its own to resolve against, so an entry that inlines the user's\n * own import statements must name the file they came from.\n */\n virtualEntrySourceFile?: string;\n /**\n * Called with each file path the tsconfig lookup depends on, including config\n * candidates that do not exist yet and package metadata used to resolve an\n * `extends` target. A cached bundler must treat these as inputs: tsconfigs are\n * never loaded as modules, so nothing else notices when an ancestor's `paths`\n * table changes or a nearer tsconfig.json appears.\n */\n onTsconfigRead?: (tsconfigPath: string) => void;\n /**\n * Lookup cache to share across multiple bundles in one CLI run. Defaults to\n * a fresh cache scoped to this plugin instance when omitted.\n */\n cache?: TsconfigLookupCache;\n}\n\n/**\n * Create the rolldown plugin that falls back to tsconfig `paths` aliases from\n * the importing file's own nearest tsconfig.\n * @param options - Resolution context for bundlers whose entry inlines user code\n * @returns Rolldown plugin to add to a bundler's plugin list\n */\nexport function createTsconfigPathsPlugin(\n options: TsconfigPathsPluginOptions = {},\n): rolldown.Plugin {\n const { tsconfigCache, contextCache } = options.cache ?? createTsconfigLookupCache();\n\n return {\n name: \"tailor-tsconfig-paths\",\n resolveId: {\n order: \"post\",\n async handler(source, importer) {\n if (!importer) return null;\n if (source.startsWith(\".\") || source.startsWith(\"/\") || source.startsWith(\"\\0\")) {\n return null;\n }\n\n const resolutionBasis = importer.startsWith(\"\\0\")\n ? options.virtualEntrySourceFile\n : importer;\n if (!resolutionBasis) return null;\n\n // Deliberately ahead of the resolvability check below: the lookup reports\n // the tsconfigs this import depends on, and a caching bundler needs them\n // even when the import resolves without any alias today. Editing those\n // tsconfigs later can change the outcome.\n const resolution = getResolutionContext(\n path.dirname(resolutionBasis),\n tsconfigCache,\n contextCache,\n options.onTsconfigRead,\n );\n if (!resolution) return null;\n\n const candidates = resolution.matcher(source);\n if (candidates.length === 0) return null;\n\n const alreadyResolvable = await this.resolve(source, importer, { skipSelf: true });\n if (alreadyResolvable) return null;\n\n // Each mapped candidate goes back through rolldown as an absolute\n // specifier, so extension substitution, directory index files and\n // `package.json` `main`/`exports` all behave exactly as they do for a\n // relative import. Probing the filesystem here instead would have to\n // restate those rules and would drift from them.\n for (const candidate of candidates) {\n const resolved = await this.resolve(candidate, importer, { skipSelf: true });\n if (resolved) return resolved;\n }\n return null;\n },\n },\n };\n}\n\nfunction getResolutionContext(\n startDir: string,\n tsconfigCache: Cache,\n contextCache: Map<string, ResolutionContext | null>,\n onTsconfigRead?: (tsconfigPath: string) => void,\n): ResolutionContext | null {\n const cached = contextCache.get(startDir);\n if (cached !== undefined) {\n // A shared cache (see TsconfigLookupCache) may have resolved this exact\n // startDir already for a different bundle; that bundle's own dependency\n // list must not become this caller's, so still report every tsconfig\n // reachable from tsconfigCache — a superset is safe (extra invalidation\n // at worst), missing one is not (a stale bundle never rebuilds).\n reportTsconfigDependencies(tsconfigCache, onTsconfigRead);\n return cached;\n }\n\n const tsconfig = getTsconfig(startDir, \"tsconfig.json\", tsconfigCache);\n reportTsconfigDependencies(tsconfigCache, onTsconfigRead);\n const paths = tsconfig?.config.compilerOptions?.paths;\n const matcher = paths && Object.keys(paths).length > 0 ? createPathsMatcher(tsconfig) : null;\n const resolution = matcher ? { matcher } : null;\n\n contextCache.set(startDir, resolution);\n return resolution;\n}\n\nfunction reportTsconfigDependencies(\n cache: Cache,\n onTsconfigRead?: (tsconfigPath: string) => void,\n): void {\n if (!onTsconfigRead) return;\n\n const directories = new Set<string>();\n const dependencies = new Set<string>();\n for (const [key, value] of cache) {\n const dependencyPath = dependencyPathFromCacheKey(key);\n if (!dependencyPath) continue;\n if (key.startsWith(\"statSync:\") && isDirectoryStat(value)) {\n directories.add(dependencyPath);\n } else {\n dependencies.add(dependencyPath);\n }\n }\n for (const dependencyPath of dependencies) {\n if (!directories.has(dependencyPath)) onTsconfigRead(dependencyPath);\n }\n}\n\nfunction dependencyPathFromCacheKey(key: string): string | undefined {\n const readFilePrefix = \"readFileSync:\";\n const readFileSuffix = \":utf8\";\n if (key.startsWith(readFilePrefix) && key.endsWith(readFileSuffix)) {\n return key.slice(readFilePrefix.length, -readFileSuffix.length);\n }\n for (const prefix of [\"existsSync:\", \"statSync:\"]) {\n if (key.startsWith(prefix)) return key.slice(prefix.length);\n }\n return undefined;\n}\n\nfunction isDirectoryStat(value: unknown): boolean {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"isDirectory\" in value &&\n typeof value.isDirectory === \"function\" &&\n value.isDirectory()\n );\n}\n","import * as path from \"pathe\";\nimport type { Plugin } from \"rolldown\";\n\ntype VirtualEntry = {\n input: string;\n plugin: Plugin;\n};\n\n/**\n * Create an in-memory rolldown entry module with a deterministic ID.\n * @param name - Logical entry name\n * @param code - Entry module source\n * @param sourceType - Parser type for the generated module\n * @param resolutionBasis - Source file whose directory resolves generated imports\n * @returns Rolldown input and plugin for loading the entry\n */\nexport function createVirtualEntry(\n name: string,\n code: string,\n sourceType: \"js\" | \"ts\" = \"js\",\n resolutionBasis?: string,\n): VirtualEntry {\n const input = `tailor-entry:${name}.${sourceType}`;\n const resolvedId = `\\0${input}`;\n\n return {\n input,\n plugin: {\n name: \"tailor-virtual-entry\",\n async resolveId(source, importer) {\n if (source === input && importer === undefined) return resolvedId;\n if (\n importer !== resolvedId ||\n !resolutionBasis ||\n source.startsWith(\".\") ||\n path.isAbsolute(source) ||\n source.startsWith(\"\\0\")\n ) {\n return null;\n }\n return this.resolve(source, resolutionBasis, { skipSelf: true });\n },\n load(id) {\n return id === resolvedId ? code : null;\n },\n },\n };\n}\n\n/**\n * Resolve bare imports in a generated on-disk entry from its owning project.\n *\n * Generated entries live under the CLI output directory, which may be outside\n * the project selected by a config path. Resolving their injected dependencies\n * from that output directory would ignore the selected project's installation.\n * @param entryPath - Absolute path of the generated entry\n * @param projectDir - Directory whose dependencies the generated entry uses\n * @returns Rolldown plugin that rebases generated bare imports\n */\nexport function createGeneratedEntryResolverPlugin(entryPath: string, projectDir: string): Plugin {\n const normalizedEntryPath = path.resolve(entryPath);\n const resolutionBasis = path.join(path.resolve(projectDir), \"__tailor_sdk_generated_entry__.js\");\n\n return {\n name: \"tailor-generated-entry-resolver\",\n async resolveId(source, importer) {\n if (\n importer === undefined ||\n path.resolve(importer) !== normalizedEntryPath ||\n source.startsWith(\".\") ||\n path.isAbsolute(source) ||\n source.startsWith(\"\\0\")\n ) {\n return null;\n }\n return this.resolve(source, resolutionBasis, { skipSelf: true });\n },\n };\n}\n","import * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { createStartTransformPlugin } from \"#/cli/services/workflow/start-transformer\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\n/**\n * Options for bundling auth hooks\n */\nexport interface BundleAuthHooksOptions {\n /** Absolute path to the config file that exports the auth definition */\n configPath: string;\n /** Auth namespace name */\n authName: string;\n /** Dot-path expression to reach the handler from the config's default export */\n handlerAccessPath: string;\n /** Environment variables to inject into the hook args */\n env?: Record<string, string | number | boolean>;\n /** Start context for workflow/job transformations */\n startContext?: StartContext;\n /** Optional bundle cache for skipping unchanged builds */\n cache?: BundleCache;\n /** Whether to enable inline sourcemaps */\n inlineSourcemap?: boolean;\n /** Controls which console calls are kept in bundled code */\n bundleLogLevel?: LogLevel;\n /** Directory the tsconfig is resolved against */\n baseDir: string;\n /** Optional tsconfig lookup cache shared across bundles in this CLI run */\n tsconfigCache?: TsconfigLookupCache;\n}\n\n/**\n * Bundle a single auth hook handler.\n *\n * Follows the same pattern as the executor bundler:\n * 1. Generate an in-memory entry module that re-exports the handler as `main`\n * 2. Bundle with rolldown + tree-shaking\n * @param options - Bundle options\n * @returns Map of function name to bundled code\n */\nexport async function bundleAuthHooks(\n options: BundleAuthHooksOptions,\n): Promise<Map<string, string>> {\n const {\n configPath,\n authName,\n handlerAccessPath,\n env = {},\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n baseDir,\n tsconfigCache,\n } = options;\n\n logger.newline();\n logger.log(`Bundling auth hook for ${styles.info(`\"${authName}\"`)}`);\n\n const absoluteConfigPath = path.resolve(configPath);\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n const functionName = `auth-hook--${authName}--before-login`;\n\n const serializedStartContext = serializeStartContext(startContext);\n\n // Include sorted env variables as a prefix so that env changes invalidate the cache\n const sortedEnvPrefix = JSON.stringify(\n Object.fromEntries(Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))),\n );\n const contextHash = computeBundlerContextHash({\n sourceFile: absoluteConfigPath,\n extraContext: serializedStartContext,\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n prefix: sortedEnvPrefix,\n });\n\n const code = await withCache({\n cache,\n kind: \"auth-hook\",\n name: functionName,\n sourceFile: absoluteConfigPath,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const entryContent = ml /* js */ `\n import _config from \"${absoluteConfigPath}\";\n const __auth_hook_function = _config.${handlerAccessPath};\n export async function main(args) {\n const env = ${JSON.stringify(env)};\n return await __auth_hook_function({ ...args, env });\n }\n `;\n const entry = createVirtualEntry(\n `auth-hook:${functionName}`,\n entryContent,\n \"js\",\n absoluteConfigPath,\n );\n\n const startPlugin = createStartTransformPlugin(startContext);\n const plugins: rolldown.Plugin[] = [entry.plugin];\n if (startPlugin) {\n plugins.push(startPlugin);\n }\n plugins.push(\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n transform: {\n define: {\n \"process.env.TAILOR_APP_LOG_LEVEL\": JSON.stringify(bundleLogLevel),\n },\n },\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n return result.output[0].code;\n },\n });\n\n logger.log(`${styles.success(\"Bundled\")} auth hook for ${styles.info(`\"${authName}\"`)}`);\n\n const bundledCode = new Map<string, string>();\n bundledCode.set(functionName, code);\n return bundledCode;\n}\n","import { parseSync } from \"oxc-parser\";\n\nconst MAX_GENERATED_CODE_LENGTH = 2_000;\n\nfunction formatGeneratedCode(expr: string): string {\n if (expr.length <= MAX_GENERATED_CODE_LENGTH) {\n return `Generated code:\\n${expr}`;\n }\n return (\n `Generated code (truncated to ${MAX_GENERATED_CODE_LENGTH} of ${expr.length} characters):\\n` +\n `${expr.slice(0, MAX_GENERATED_CODE_LENGTH)}\\n...`\n );\n}\n\n/**\n * Assert that a generated script expression is syntactically valid JavaScript.\n * Invalid generated code would otherwise surface much later as a confusing\n * bundler or platform-side syntax error, far from the definition that caused it.\n * @param expr - Generated JavaScript expression\n * @param context - What generated the expression, used to label the error\n * @returns The expression unchanged when it parses successfully\n */\nexport function assertParsableExpression(expr: string, context: string): string {\n const { errors } = parseSync(\"generated-expr.js\", `(${expr}\\n);`);\n if (errors.length === 0) {\n return expr;\n }\n const details = errors.map((error) => ` - ${error.message}`).join(\"\\n\");\n throw new Error(\n `Generated ${context} script is not valid JavaScript.\\n` +\n `Parse errors:\\n${details}\\n` +\n formatGeneratedCode(expr),\n );\n}\n","import type { ScriptExprKind } from \"./types\";\n\n// Identifier the table-level wrapper (buildTypeScripts in type-script.ts) binds\n// tailorPrincipalMap's result to, at most once per table, so per-hook exprs\n// below can reference it instead of re-embedding the full mapping on every hook.\nexport const PRINCIPAL_VAR = \"_principal\";\n\n/**\n * Build the call-argument list a script expression is invoked with, keyed by the\n * kind of hook/validator it wraps. Shared by every caller that assembles a\n * `(${normalized})(${callArgs})` script expression - both `field.ts` and the CLI's\n * hook-precompilation bundler - so the two never drift apart.\n * @param kind - Kind of hook/validator the expression is for\n * @returns The literal source of the arguments (an object literal for every kind\n * except `typeValidate`, which also appends a trailing `__issues` argument)\n */\nexport function buildHookCallArgs(kind: ScriptExprKind): string {\n switch (kind) {\n case \"validate\":\n return `{ value: _value }`;\n case \"hooks.create\":\n return `{ input: _value, invoker: ${PRINCIPAL_VAR}, now: _now }`;\n case \"hooks.update\":\n return `{ input: _value, oldValue: _oldValue, invoker: ${PRINCIPAL_VAR}, now: _now }`;\n case \"typeHook.create\":\n case \"typeHook.update\":\n return `{ input: _input, oldRecord: _oldRecord, invoker: ${PRINCIPAL_VAR}, now: _now }`;\n case \"typeValidate\":\n return `{ newRecord: _newRecord, oldRecord: _oldRecord, invoker: ${PRINCIPAL_VAR} }, __issues`;\n default:\n throw new Error(`Unknown script expr kind: ${kind satisfies never}`);\n }\n}\n","import type { PrecompiledScriptExprKey, PrecompiledScriptExprMap, ScriptExprKind } from \"./types\";\n\nconst PRECOMPILED_EXPR_KEY: PrecompiledScriptExprKey =\n \"tailor-platform/sdk:precompiled-script-expr\";\nconst PRECOMPILED_EXPR_SYMBOL = Symbol.for(PRECOMPILED_EXPR_KEY);\n\ntype AnyFunction = (...args: never[]) => unknown;\n\nconst precompiledExprs = new WeakMap<AnyFunction, PrecompiledScriptExprMap>();\n\n/**\n * Store a precompiled script expression for a function.\n * Keyed by role so one function reused across roles keeps a distinct expression per role.\n * @param fn - Hook or validator function the expression was compiled from.\n * @param kind - Role the expression was compiled for.\n * @param expr - Precompiled script expression.\n */\nexport function setPrecompiledScriptExpr(fn: AnyFunction, kind: ScriptExprKind, expr: string) {\n const entry = precompiledExprs.get(fn) ?? {};\n entry[kind] = expr;\n precompiledExprs.set(fn, entry);\n}\n\n/**\n * Read a precompiled script expression for a function.\n * @param fn - Hook or validator function the expression was compiled from.\n * @param kind - Role the expression was compiled for.\n * @returns Precompiled script expression if attached for that role.\n */\nexport function getPrecompiledScriptExpr(\n fn: AnyFunction,\n kind: ScriptExprKind,\n): string | undefined {\n const pinnedExprs = Object.hasOwn(fn, PRECOMPILED_EXPR_SYMBOL)\n ? (fn as unknown as Record<symbol, unknown>)[PRECOMPILED_EXPR_SYMBOL]\n : undefined;\n if (typeof pinnedExprs === \"object\" && pinnedExprs !== null && Object.hasOwn(pinnedExprs, kind)) {\n const pinnedExpr = (pinnedExprs as Partial<Record<ScriptExprKind, unknown>>)[kind];\n if (typeof pinnedExpr === \"string\") {\n return pinnedExpr;\n }\n }\n return precompiledExprs.get(fn)?.[kind];\n}\n","import { parseSync } from \"oxc-parser\";\nimport { assertParsableExpression } from \"#/utils/script-expr\";\nimport { buildHookCallArgs } from \"./hook-args-object\";\nimport { getPrecompiledScriptExpr } from \"./hooks-validate-precompiled-expr\";\nimport type {\n TailorAnyDBField,\n DBFieldMetadata,\n RawRelationConfig,\n} from \"#/configure/services/tailordb/types\";\nimport type { OperatorFieldConfig, ScriptExprKind } from \"#/parser/service/tailordb/types\";\nimport type { TailorDBTypeRaw as TailorDBTypeSchemaOutput } from \"#/types/tailordb.generated\";\n\ntype FieldScriptContext = {\n tableName: string;\n fieldPath: readonly string[];\n};\n\ntype ScriptFunction = (...args: never[]) => unknown;\n\ntype ScriptContextKind = Extract<ScriptExprKind, \"hooks.create\" | \"hooks.update\" | \"validate\">;\n\nconst NIL_UUID = \"00000000-0000-0000-0000-000000000000\";\n\n/**\n * Per-source field expressions for {@link makePrincipalExpr}. Each value is a JS\n * snippet evaluated against the raw server payload bound to `$raw`.\n */\ninterface PrincipalFieldExprs {\n /**\n * Raw type accessor. `raw` is matched against `USER_TYPE_*` when normalizing;\n * `fallback` (defaulting to `raw`) supplies the type for non-matching values,\n * which lets sources whose primary field is empty fall back to a secondary.\n */\n type: { raw: string; fallback?: string };\n /** Raw id accessor. */\n id: string;\n workspaceId: string;\n attributes: string;\n attributeList: string;\n}\n\ninterface MakePrincipalExprOptions {\n source: string;\n fields: PrincipalFieldExprs;\n normalize: boolean;\n requireId?: boolean;\n}\n\n/**\n * Build the server→SDK principal mapping expression shared across services.\n *\n * All principal-bearing call sites (`caller`, `actor`, `invoker`) must agree on\n * the `TailorPrincipal | null` shape, so they are generated here rather than\n * hand-written per service.\n * @param options - Mapping source and field expressions\n * @param options.source - Expression yielding the raw server payload (e.g. `user`)\n * @param options.fields - Per-source accessors for each principal field\n * @param options.normalize - When true, map `USER_TYPE_*` to SDK type literals and\n * return `null` for unspecified types or the nil-UUID id; when false, the\n * payload is already in SDK shape and only `null` pass-through is applied\n * @param options.requireId - When true, missing ids are also mapped to `null`\n * @returns A JS expression string evaluating to `TailorPrincipal | null`\n */\nexport function makePrincipalExpr(options: MakePrincipalExprOptions): string {\n const { source, fields, normalize, requireId = false } = options;\n const body = /* js */ `{\n id,\n type,\n workspaceId: ${fields.workspaceId},\n attributes: ${fields.attributes},\n attributeList: ${fields.attributeList},\n }`;\n if (!normalize) {\n return /* js */ `(($raw) => {\n if (!$raw) {\n return null;\n }\n const id = ${fields.id};\n const type = ${fields.type.raw};\n return ${body};\n})(${source})`;\n }\n const missingIdGuard = requireId ? \" || !id\" : \"\";\n return /* js */ `(($raw) => {\n if (!$raw) {\n return null;\n }\n const type = ${fields.type.raw} === \"USER_TYPE_USER\"\n ? \"user\"\n : ${fields.type.raw} === \"USER_TYPE_MACHINE_USER\"\n ? \"machine_user\"\n : ${fields.type.fallback ?? fields.type.raw};\n const id = ${fields.id};\n if (!type || type === \"USER_TYPE_UNSPECIFIED\" || id === \"${NIL_UUID}\"${missingIdGuard}) {\n return null;\n }\n return ${body};\n})(${source})`;\n}\n\n// Since there's naming difference between platform and SDK, use this mapping in\n// all scripts to provide variables that match `TailorPrincipal | null`.\nexport const tailorPrincipalMap = makePrincipalExpr({\n source: \"user\",\n normalize: true,\n fields: {\n type: { raw: \"$raw?.type\" },\n id: \"$raw.id\",\n workspaceId: \"$raw.workspace_id ?? $raw.workspaceId\",\n attributes: \"$raw.attribute_map ?? $raw.attributeMap ?? {}\",\n attributeList: \"$raw.attributes ?? []\",\n },\n});\n\n/**\n * Parse `wrapped` and return the first property of the top-level parenthesized\n * object expression, or `undefined` if it does not parse as one.\n * @param wrapped - Source wrapped as `({ ... })`\n * @returns The first object property, or `undefined`\n */\nconst firstObjectProperty = (wrapped: string) => {\n const parseResult = parseSync(\"stringify-function.ts\", wrapped, { sourceType: \"module\" });\n if (parseResult.errors.length > 0) {\n return undefined;\n }\n const expressionStatement = parseResult.program.body[0];\n const objectExpression =\n expressionStatement?.type === \"ExpressionStatement\" &&\n expressionStatement.expression.type === \"ParenthesizedExpression\"\n ? expressionStatement.expression.expression\n : undefined;\n return objectExpression?.type === \"ObjectExpression\" ? objectExpression.properties[0] : undefined;\n};\n\n/**\n * Convert a function to a string representation.\n * Handles method shorthand syntax (e.g., `create() { ... }`) by converting it to\n * an anonymous function expression (e.g., `function () { ... }`), including\n * `async` and generator variants and shorthand bodies that themselves contain\n * arrow functions. The result is anonymous (rather than reusing the method\n * name) so a body that references an outer variable of the same name is not\n * shadowed by the generated function's own binding.\n * @param fn - Function to stringify\n * @returns Stringified function source\n */\n// oxlint-disable-next-line typescript/no-unsafe-function-type\nexport const stringifyFunction = (fn: Function): string => {\n const src = fn.toString().trim();\n // `src` is already a valid function/arrow expression (e.g. `function () {}`,\n // `() => {}`) if it parses as an object property value as-is; leave it untouched.\n if (firstObjectProperty(`({m: ${src}})`)) {\n return src;\n }\n // Otherwise, method shorthand (e.g. `create() {}`, `async create() {}`) is\n // only valid inside an object literal, so parse it as an object property to\n // detect and convert it via the AST rather than guessing from source text.\n const wrapped = `({${src}})`;\n const property = firstObjectProperty(wrapped);\n\n if (property?.type === \"Property\" && property.method && property.computed) {\n throw new Error(\n \"Computed-key method shorthand cannot be converted to a TailorDB script expression. \" +\n \"Use an arrow function or function expression instead.\",\n );\n }\n if (\n property?.type === \"Property\" &&\n property.method &&\n property.value.type === \"FunctionExpression\"\n ) {\n const { async, generator } = property.value;\n const body = wrapped.slice(property.value.start, property.value.end);\n return `${async ? \"async \" : \"\"}function${generator ? \"*\" : \"\"} ${body}`;\n }\n return src;\n};\n\nfunction formatScriptContext(kind: ScriptContextKind, context: FieldScriptContext | undefined) {\n if (!context) {\n return kind === \"validate\" ? kind : \"hooks\";\n }\n return `${kind} for ${context.tableName}.${context.fieldPath.join(\".\")}`;\n}\n\n/**\n * Convert a hook or validator function to a script expression.\n * @param fn - Hook or validator function\n * @param kind - Label naming the source of the expression in conversion errors\n * @param context - Optional field context for conversion errors\n * @returns JavaScript expression calling the function\n */\nconst convertToScriptExpr = (\n fn: ScriptFunction,\n kind: ScriptContextKind,\n context: FieldScriptContext | undefined,\n): string => {\n const precompiledExpr = getPrecompiledScriptExpr(fn, kind);\n if (precompiledExpr) {\n return precompiledExpr;\n }\n const normalized = stringifyFunction(fn);\n return assertParsableExpression(\n `(${normalized})(${buildHookCallArgs(kind)})`,\n formatScriptContext(kind, context),\n );\n};\n\n// oxlint-disable-next-line typescript/no-unsafe-function-type\nexport const convertTypeHookToExpr = (fn: Function, op: \"create\" | \"update\"): string => {\n const kind = `typeHook.${op}` as const;\n const precompiledExpr = getPrecompiledScriptExpr(fn as (...args: never[]) => unknown, kind);\n if (precompiledExpr) {\n return precompiledExpr;\n }\n const normalized = stringifyFunction(fn);\n return assertParsableExpression(`(${normalized})(${buildHookCallArgs(kind)})`, \"type-hook\");\n};\n\n// oxlint-disable-next-line typescript/no-unsafe-function-type\nexport const convertTypeValidateToExpr = (fn: Function): string => {\n const precompiledExpr = getPrecompiledScriptExpr(\n fn as (...args: never[]) => unknown,\n \"typeValidate\",\n );\n if (precompiledExpr) {\n return precompiledExpr;\n }\n const normalized = stringifyFunction(fn);\n return assertParsableExpression(\n `(${normalized})(${buildHookCallArgs(\"typeValidate\")})`,\n \"type-validate\",\n );\n};\n\n/**\n * Parse TailorDBField into OperatorFieldConfig.\n * This transforms user-defined functions into script expressions.\n * @param field - TailorDB field definition\n * @param context - Optional field context for conversion errors\n * @returns Parsed operator field configuration\n */\nexport function parseFieldConfig(\n field: TailorDBTypeSchemaOutput[\"fields\"][string],\n context?: FieldScriptContext,\n): OperatorFieldConfig {\n const metadata = field.metadata as DBFieldMetadata;\n const fieldType = field.type;\n // Access rawRelation via getter (if available)\n const rawRelation = (field as unknown as { rawRelation?: RawRelationConfig }).rawRelation;\n\n if (context && context.fieldPath.length > 1 && metadata.default !== undefined) {\n throw new Error(\n `Field \"${context.fieldPath.join(\".\")}\" on table \"${context.tableName}\": ` +\n `.default() cannot be used on nested inner fields`,\n );\n }\n\n if (context && context.fieldPath.length > 1 && metadata.hooks) {\n throw new Error(\n `Field \"${context.fieldPath.join(\".\")}\" on table \"${context.tableName}\": ` +\n `.hooks() cannot be used on nested inner fields`,\n );\n }\n\n const nestedFields = field.fields as Record<string, TailorAnyDBField> | undefined;\n return {\n type: fieldType,\n ...metadata,\n rawRelation,\n ...(fieldType === \"nested\" && nestedFields && Object.keys(nestedFields).length > 0\n ? {\n fields: Object.entries(nestedFields).reduce(\n (acc, [key, nestedField]) => {\n acc[key] = parseFieldConfig(\n nestedField,\n context && {\n ...context,\n fieldPath: [...context.fieldPath, key],\n },\n );\n return acc;\n },\n {} as Record<string, OperatorFieldConfig>,\n ),\n }\n : {}),\n validate: metadata.validate?.map((fn) => ({\n script: {\n expr: convertToScriptExpr(fn, \"validate\", context),\n },\n errorMessage: \"\",\n })),\n hooks: metadata.hooks\n ? {\n create: metadata.hooks.create\n ? {\n expr: convertToScriptExpr(\n metadata.hooks.create as ScriptFunction,\n \"hooks.create\",\n context,\n ),\n }\n : undefined,\n update: metadata.hooks.update\n ? {\n expr: convertToScriptExpr(\n metadata.hooks.update as ScriptFunction,\n \"hooks.update\",\n context,\n ),\n }\n : undefined,\n }\n : undefined,\n serial: metadata.serial\n ? {\n start: metadata.serial.start,\n maxValue: metadata.serial.maxValue,\n format: \"format\" in metadata.serial ? metadata.serial.format : undefined,\n }\n : undefined,\n };\n}\n","type NormalizedPermit = \"allow\" | \"deny\";\n\nexport interface NormalizedActionPermission<Condition> {\n conditions: Condition[];\n permit: NormalizedPermit;\n description?: string;\n}\n\n/**\n * Check whether a permission rule uses the object format (`{ conditions, permit?, description? }`).\n * @param p - A raw permission rule\n * @returns Whether the rule is in object format\n */\nfunction isObjectPermissionFormat(\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 isSingleConditionFormat(cond: readonly unknown[]): boolean {\n return cond.length >= 2 && typeof cond[1] === \"string\"; // Check if middle element is an operator\n}\n\nfunction normalizeOperand(operand: unknown): unknown {\n if (operand === null) {\n throw new Error(\"Invalid permission operand: null\");\n }\n if (typeof operand === \"object\" && !Array.isArray(operand)) {\n if (\"user\" in operand) {\n const user = operand.user;\n return { user: user === \"id\" ? \"_id\" : user };\n }\n }\n return operand;\n}\n\n/**\n * Build the permission normalizer shared by the services that accept the\n * condition-triple permission formats (object form, single-condition\n * shorthand, and condition-array shorthand).\n *\n * The services differ only in their operator vocabulary and in the type they\n * give the normalized conditions, so both are parameters.\n * @param operatorMap - Service-specific map from source operators to normalized names\n * @returns `normalizeConditions` and `normalizeActionPermission` for the service\n */\nexport function createPermissionNormalizer<Operator extends string, Condition>(\n operatorMap: Record<Operator, string>,\n) {\n type RawCondition = readonly [unknown, Operator, unknown];\n\n function normalizeConditions(conditions: readonly RawCondition[]): Condition[] {\n return conditions.map((cond) => {\n const [left, operator, right] = cond;\n return [normalizeOperand(left), operatorMap[operator], normalizeOperand(right)];\n }) as Condition[];\n }\n\n function normalizeActionPermission(permission: unknown): NormalizedActionPermission<Condition> {\n // object format\n if (isObjectPermissionFormat(permission)) {\n const conditions = permission.conditions as RawCondition | readonly RawCondition[];\n return {\n conditions: normalizeConditions(\n isSingleConditionFormat(conditions)\n ? [conditions as RawCondition]\n : (conditions as readonly RawCondition[]),\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 // Single condition shorthand, with an optional trailing permit boolean\n if (isSingleConditionFormat(permission)) {\n const [op1, operator, op2, permit] = [...permission, true] as [\n unknown,\n Operator,\n unknown,\n boolean,\n ];\n return {\n conditions: normalizeConditions([[op1, operator, op2]]),\n permit: permit ? \"allow\" : \"deny\",\n };\n }\n\n // Array of conditions format, with an optional permit boolean among the items\n const conditions: RawCondition[] = [];\n let permit = true;\n for (const item of permission as readonly unknown[]) {\n if (typeof item === \"boolean\") {\n permit = item;\n continue;\n }\n conditions.push(item as RawCondition);\n }\n\n return {\n conditions: normalizeConditions(conditions),\n permit: permit ? \"allow\" : \"deny\",\n };\n }\n\n return { normalizeConditions, normalizeActionPermission };\n}\n\n/**\n * Whether an object-format rule omits `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 such rules to nudge authors toward setting `permit`\n * explicitly.\n * @param rule - A raw permission rule\n * @returns Whether the rule is object-format with `permit` omitted\n */\nexport function hasOmittedPermit(rule: unknown): boolean {\n return isObjectPermissionFormat(rule) && rule.permit === undefined;\n}\n","import { createPermissionNormalizer, hasOmittedPermit } from \"#/parser/service/permission\";\nimport type {\n StandardTailorTypePermission,\n StandardTailorTypeGqlPermission,\n StandardActionPermission,\n StandardPermissionCondition,\n StandardGqlPermissionPolicy,\n Permissions,\n} from \"#/parser/service/tailordb/types\";\nimport type { GqlOperations, RawPermissions } from \"#/types/tailordb.generated\";\n\n// Raw permission types for normalize function parameters\ntype PermissionOperator = \"=\" | \"!=\" | \"in\" | \"not in\" | \"hasAny\" | \"not hasAny\";\n\ntype PermissionCondition = readonly [unknown, PermissionOperator, unknown];\n\nconst { normalizeConditions, normalizeActionPermission: normalizeRawActionPermission } =\n createPermissionNormalizer<PermissionOperator, StandardPermissionCondition>({\n \"=\": \"eq\",\n \"!=\": \"ne\",\n in: \"in\",\n \"not in\": \"nin\",\n hasAny: \"hasAny\",\n \"not hasAny\": \"nhasAny\",\n });\n\ntype GqlPermissionPolicy = {\n conditions: readonly PermissionCondition[];\n actions: \"all\" | readonly GqlPermissionAction[];\n permit?: boolean;\n description?: string;\n};\n\ntype GqlPermissionAction = \"read\" | \"create\" | \"update\" | \"delete\" | \"aggregate\" | \"bulkUpsert\";\n\n/**\n * Normalize record-level permissions into a standard structure.\n * @param permission - Tailor table permission\n * @returns Normalized record permissions\n */\nfunction normalizePermission(\n permission: NonNullable<RawPermissions[\"record\"]>,\n): StandardTailorTypePermission {\n const keys = Object.keys(permission) as Array<keyof typeof permission>;\n return keys.reduce((acc, action) => {\n acc[action] = permission[action].map((p) => normalizeActionPermission(p));\n return acc;\n // oxlint-disable-next-line no-explicit-any\n }, {} as any);\n}\n\n/**\n * Normalize GraphQL permissions into a standard structure.\n * @param permission - Tailor GQL permission\n * @returns Normalized GQL permissions\n */\nexport function normalizeGqlPermission(\n permission: NonNullable<RawPermissions[\"gql\"]>,\n): StandardTailorTypeGqlPermission {\n return (permission as readonly GqlPermissionPolicy[]).map((policy) => normalizeGqlPolicy(policy));\n}\n\nfunction normalizeGqlPolicy(policy: GqlPermissionPolicy): StandardGqlPermissionPolicy {\n return {\n conditions: normalizeConditions(policy.conditions),\n actions: policy.actions === \"all\" ? [\"all\"] : policy.actions,\n permit: policy.permit ? \"allow\" : \"deny\",\n description: policy.description,\n } as StandardGqlPermissionPolicy;\n}\n\n/**\n * Parse raw permissions into normalized permissions.\n * This is the main entry point for permission parsing in the parser layer.\n * @param rawPermissions - Raw permissions definition\n * @returns Normalized permissions\n */\nexport function parsePermissions(rawPermissions: RawPermissions): Permissions {\n return {\n ...(rawPermissions.record && {\n record: normalizePermission(rawPermissions.record),\n }),\n ...(rawPermissions.gql && {\n gql: normalizeGqlPermission(rawPermissions.gql),\n }),\n };\n}\n\n/**\n * Normalize a single action permission into the standard format.\n * @param permission - Raw permission definition\n * @returns Normalized action permission\n */\nexport function normalizeActionPermission(permission: unknown): StandardActionPermission {\n return normalizeRawActionPermission(permission);\n}\n\n/**\n * Find object-format permission rules that omit `permit` (which defaults to\n * `deny` there, unlike the array shorthand), so the CLI can warn about them.\n * @param rawPermissions - Raw permissions definition\n * @returns Dotted locations of offending rules, e.g. `record.read[0]`, `gql[1]`\n */\nexport function findOmittedPermitRules(rawPermissions: RawPermissions): string[] {\n const locations: string[] = [];\n\n const record = rawPermissions.record;\n if (record) {\n for (const action of Object.keys(record) as Array<keyof typeof record>) {\n record[action].forEach((rule: unknown, index: number) => {\n if (hasOmittedPermit(rule)) {\n locations.push(`record.${String(action)}[${index}]`);\n }\n });\n }\n }\n\n // GQL policies are always object form, so no isObjectFormat guard is needed.\n const gql = rawPermissions.gql;\n if (gql) {\n (gql as readonly GqlPermissionPolicy[]).forEach((policy, index) => {\n if (policy.permit === undefined) {\n locations.push(`gql[${index}]`);\n }\n });\n }\n\n return locations;\n}\n\n/**\n * Check whether GraphQL exposure is fully disabled for a table, given its\n * effective gqlOperations (the table's own setting, falling back to the\n * TailorDB namespace default). `undefined` means the default of all\n * operations enabled, so it is never considered fully disabled.\n * @param gqlOperations - Effective, normalized gqlOperations configuration\n * @returns Whether create, update, delete, and read are all explicitly disabled\n */\nexport function isGqlOperationsFullyDisabled(gqlOperations: GqlOperations | undefined): boolean {\n if (!gqlOperations) {\n return false;\n }\n return (\n gqlOperations.create === false &&\n gqlOperations.update === false &&\n gqlOperations.delete === false &&\n gqlOperations.read === false\n );\n}\n\n/**\n * Missing permission configuration detected for a TailorDB table.\n */\nexport interface MissingTypePermissionConfig {\n /** Whether record-level permission (`.permission()`) is missing */\n missingPermission: boolean;\n /** Whether GraphQL permission (`.gqlPermission()`) is missing while GraphQL exposure is enabled */\n missingGqlPermission: boolean;\n}\n\n/**\n * Find missing permission configuration for a TailorDB table.\n *\n * Record-level permission is always required: TailorDB denies all record\n * operations for a table without it, regardless of whether the table is\n * exposed via GraphQL. GraphQL permission is required whenever GraphQL\n * exposure is enabled for the table (the default, unless every operation is\n * explicitly disabled via `gqlOperations`).\n * @param rawPermissions - Raw permissions definition for the table\n * @param effectiveGqlOperations - The table's own gqlOperations, falling back to the namespace default\n * @returns Which permission configuration, if any, is missing\n */\nexport function findMissingPermissionConfig(\n rawPermissions: RawPermissions,\n effectiveGqlOperations: GqlOperations | undefined,\n): MissingTypePermissionConfig {\n return {\n missingPermission: !rawPermissions.record,\n missingGqlPermission:\n !rawPermissions.gql && !isGqlOperationsFullyDisabled(effectiveGqlOperations),\n };\n}\n","import * as inflection from \"inflection\";\nimport { isPluginGeneratedTable } from \"#/parser/service/tailordb/type-source\";\nimport { convertTypeHookToExpr, convertTypeValidateToExpr, parseFieldConfig } from \"./field\";\nimport { parsePermissions } from \"./permission\";\nimport {\n validateRelationConfig,\n processRelationMetadata,\n buildRelationInfo,\n applyRelationMetadataToFieldConfig,\n} from \"./relation\";\nimport type { TailorDBField } from \"#/configure/services/tailordb/types\";\nimport type {\n TypeSourceInfo,\n ParsedField,\n ParsedRelationship,\n TailorDBType,\n} from \"#/parser/service/tailordb/types\";\nimport type { TailorDBTypeRaw as TailorDBTypeSchemaOutput } from \"#/types/tailordb.generated\";\n\n/**\n * Parse multiple TailorDB tables, build relationships, and validate uniqueness.\n * This is the main entry point for parsing TailorDB tables.\n * @param rawTypes - Raw TailorDB tables keyed by name\n * @param namespace - TailorDB namespace name\n * @param typeSourceInfo - Optional table source information\n * @returns Parsed tables\n */\nexport function parseTypes(\n rawTypes: Record<string, TailorDBTypeSchemaOutput>,\n namespace: string,\n typeSourceInfo?: TypeSourceInfo,\n): Record<string, TailorDBType> {\n const types = createRecord<TailorDBType>();\n const allTableNames = new Set(Object.keys(rawTypes));\n\n for (const [tableName, type] of Object.entries(rawTypes)) {\n types[tableName] = parseTailorDBType(type, allTableNames, rawTypes, typeSourceInfo);\n }\n\n buildBackwardRelationships(types, namespace, typeSourceInfo);\n validatePluralFormUniqueness(types, namespace, typeSourceInfo);\n\n return types;\n}\n\n/**\n * Parse a TailorDBTypeSchemaOutput into a TailorDBType.\n * @param type - TailorDB table to parse\n * @param allTableNames - Set of all TailorDB table names\n * @param rawTypes - All raw TailorDB tables keyed by name\n * @param typeSourceInfo - Optional table source information\n * @returns Parsed TailorDB table\n */\nfunction parseTailorDBType(\n type: TailorDBTypeSchemaOutput,\n allTableNames: Set<string>,\n rawTypes: Record<string, TailorDBTypeSchemaOutput>,\n typeSourceInfo?: TypeSourceInfo,\n): TailorDBType {\n const metadata = type.metadata;\n const pluralForm = metadata.settings?.pluralForm || inflection.pluralize(type.name);\n const typeLocation = formatTypeSourceLocation(getTypeSourceInfo(typeSourceInfo, type.name));\n\n const fields = createRecord<ParsedField>();\n const forwardRelationships = createRecord<ParsedRelationship>();\n\n for (const [fieldName, fieldDef] of Object.entries(type.fields) as [\n string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- TailorDBField requires generic type parameters\n TailorDBField<any, any>,\n ][]) {\n const context = { tableName: type.name, fieldName, allTableNames };\n let fieldConfig = parseFieldConfig(fieldDef, {\n tableName: type.name,\n fieldPath: [fieldName],\n });\n const rawRelation = fieldConfig.rawRelation;\n\n // Process relation if rawRelation is present\n if (rawRelation) {\n validateRelationConfig(rawRelation, context);\n\n // Validate that n-1/manyToOne relations cannot have explicit unique\n const isNToOne = [\"n-1\", \"manyToOne\", \"N-1\"].includes(rawRelation.type);\n if (isNToOne && fieldConfig.unique) {\n throw new Error(\n `Field \"${fieldName}\" on table \"${type.name}\": cannot set unique on n-1 (manyToOne) relation. ` +\n `Use 1-1 (oneToOne) relation instead, or remove the unique constraint.`,\n );\n }\n\n const relationMetadata = processRelationMetadata(rawRelation, context, fieldConfig.array);\n fieldConfig = applyRelationMetadataToFieldConfig(fieldConfig, relationMetadata);\n }\n\n // Validate that index/unique are not set on array fields\n if (fieldConfig.array && fieldConfig.index) {\n throw new Error(\n `Field \"${fieldName}\" on table \"${type.name}\": index cannot be set on array fields`,\n );\n }\n if (fieldConfig.array && fieldConfig.unique) {\n throw new Error(\n `Field \"${fieldName}\" on table \"${type.name}\": unique cannot be set on array fields`,\n );\n }\n\n const parsedField: ParsedField = { name: fieldName, config: fieldConfig };\n\n // Build relation info for forward/backward relationships\n const relationInfo = rawRelation ? buildRelationInfo(rawRelation, context) : undefined;\n if (relationInfo) {\n parsedField.relation = { ...relationInfo };\n const forwardName = relationInfo.forwardName;\n\n if (forwardName.length === 0) {\n throw new Error(\n `Forward relation name for field \"${fieldName}\" on table \"${type.name}\"${typeLocation} cannot be empty. ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a non-empty name.`,\n );\n }\n\n const existingForward = forwardRelationships[forwardName];\n if (existingForward) {\n throw new Error(\n `Forward relation name \"${forwardName}\" on table \"${type.name}\"${typeLocation} is duplicated ` +\n `between fields \"${existingForward.targetField}\" and \"${fieldName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a unique name.`,\n );\n }\n if (Object.hasOwn(type.fields, forwardName)) {\n const message =\n forwardName === fieldName\n ? `Forward relation name \"${forwardName}\" on table \"${type.name}\"${typeLocation} is the same as its own relation field \"${fieldName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a different name.`\n : `Forward relation name \"${forwardName}\" from field \"${fieldName}\" on table \"${type.name}\"${typeLocation} ` +\n `conflicts with existing field \"${forwardName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a different name.`;\n throw new Error(message);\n }\n if (Object.hasOwn(metadata.files, forwardName)) {\n throw new Error(\n `Forward relation name \"${forwardName}\" from field \"${fieldName}\" on table \"${type.name}\"${typeLocation} ` +\n `conflicts with files field \"${forwardName}\". ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) to specify a different name.`,\n );\n }\n\n const targetType = rawTypes[relationInfo.targetType];\n forwardRelationships[forwardName] = {\n name: forwardName,\n targetType: relationInfo.targetType,\n targetField: fieldName,\n sourceField: relationInfo.key,\n isArray: false,\n description: targetType?.metadata.description || \"\",\n };\n }\n\n fields[fieldName] = parsedField;\n }\n\n return {\n name: type.name,\n pluralForm,\n description: metadata.description,\n fields,\n forwardRelationships,\n backwardRelationships: createRecord<ParsedRelationship>(),\n settings: metadata.settings ?? {},\n permissions: parsePermissions(metadata.permissions),\n indexes: metadata.indexes,\n files: metadata.files,\n ...(metadata.typeHook && {\n typeHookExpr: {\n ...(typeof metadata.typeHook.create === \"function\" && {\n create: convertTypeHookToExpr(metadata.typeHook.create, \"create\"),\n }),\n ...(typeof metadata.typeHook.update === \"function\" && {\n update: convertTypeHookToExpr(metadata.typeHook.update, \"update\"),\n }),\n },\n }),\n ...(typeof metadata.typeValidate === \"function\" && {\n typeValidateExpr: convertTypeValidateToExpr(metadata.typeValidate),\n }),\n };\n}\n\n/**\n * Build backward relationships between parsed tables.\n * Also validates that backward relation names are unique within each table.\n * @param types - Parsed tables\n * @param namespace - TailorDB namespace name\n * @param typeSourceInfo - Optional table source information\n */\nfunction buildBackwardRelationships(\n types: Record<string, TailorDBType>,\n namespace: string,\n typeSourceInfo?: TypeSourceInfo,\n): void {\n // Track backward name sources for duplicate detection\n // Map: targetTypeName -> backwardName -> array of source info\n const backwardNameSources: Record<\n string,\n Record<string, { sourceType: string; fieldName: string }[]>\n > = Object.create(null);\n\n // Initialize tracking for all tables\n for (const tableName of Object.keys(types)) {\n backwardNameSources[tableName] = Object.create(null) as Record<\n string,\n { sourceType: string; fieldName: string }[]\n >;\n }\n\n // Build backward relationships and track sources\n for (const [tableName, type] of Object.entries(types)) {\n for (const [otherTypeName, otherType] of Object.entries(types)) {\n for (const [fieldName, field] of Object.entries(otherType.fields)) {\n if (field.relation && field.relation.targetType === tableName) {\n let backwardName = field.relation.backwardName;\n\n if (!backwardName) {\n const lowerName = inflection.camelize(otherTypeName, true);\n backwardName = field.relation.unique\n ? inflection.singularize(lowerName)\n : inflection.pluralize(lowerName);\n }\n\n // Track the source of this backward name\n const tableBackwardNames = backwardNameSources[tableName];\n if (tableBackwardNames === undefined) {\n throw new Error(`backward name sources not initialized for table: ${tableName}`);\n }\n if (!tableBackwardNames[backwardName]) {\n tableBackwardNames[backwardName] = [];\n }\n const sources = tableBackwardNames[backwardName];\n if (sources === undefined) {\n throw new Error(`backward name sources entry not initialized for: ${backwardName}`);\n }\n sources.push({\n sourceType: otherTypeName,\n fieldName,\n });\n\n type.backwardRelationships[backwardName] = {\n name: backwardName,\n targetType: otherTypeName,\n targetField: fieldName,\n sourceField: field.relation.key,\n isArray: !field.relation.unique,\n description: otherType.description || \"\",\n };\n }\n }\n }\n }\n\n // Check for duplicates and collect errors\n const errors: string[] = [];\n\n for (const [targetTypeName, backwardNames] of Object.entries(backwardNameSources)) {\n const targetType = types[targetTypeName];\n if (targetType === undefined) {\n throw new Error(`type not found: ${targetTypeName}`);\n }\n const targetTypeSourceInfo = getTypeSourceInfo(typeSourceInfo, targetTypeName);\n const targetLocation = formatTypeSourceLocation(targetTypeSourceInfo);\n\n for (const [backwardName, sources] of Object.entries(backwardNames)) {\n // Check for duplicate backward relation names\n if (sources.length > 1) {\n const sourceList = sources\n .map((s) => {\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, s.sourceType);\n const location = formatTypeSourceLocation(sourceInfo);\n return `${s.sourceType}.${s.fieldName}${location}`;\n })\n .join(\", \");\n errors.push(\n `Backward relation name \"${backwardName}\" on table \"${targetTypeName}\" is duplicated from: ${sourceList}. ` +\n `Use the \"backward\" option in .relation() to specify unique names.`,\n );\n }\n\n // Check for conflict with existing fields\n if (Object.hasOwn(targetType.fields, backwardName)) {\n const source = sources[0];\n if (source === undefined) {\n throw new Error(`no source found for backward name: ${backwardName}`);\n }\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, source.sourceType);\n const sourceLocation = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Backward relation name \"${backwardName}\" from ${source.sourceType}.${source.fieldName}${sourceLocation} ` +\n `conflicts with existing field \"${backwardName}\" on table \"${targetTypeName}\"${targetLocation}. ` +\n `Use the \"backward\" option in .relation() to specify a different name.`,\n );\n }\n\n // Check for conflict with files fields\n if (targetType.files && Object.hasOwn(targetType.files, backwardName)) {\n const source = sources[0];\n if (source === undefined) {\n throw new Error(`no source found for backward name: ${backwardName}`);\n }\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, source.sourceType);\n const sourceLocation = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Backward relation name \"${backwardName}\" from ${source.sourceType}.${source.fieldName}${sourceLocation} ` +\n `conflicts with files field \"${backwardName}\" on table \"${targetTypeName}\"${targetLocation}. ` +\n `Use the \"backward\" option in .relation() to specify a different name.`,\n );\n }\n\n if (Object.hasOwn(targetType.forwardRelationships, backwardName)) {\n const source = sources[0];\n if (source === undefined) {\n throw new Error(`no source found for backward name: ${backwardName}`);\n }\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, source.sourceType);\n const sourceLocation = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Relation name \"${backwardName}\" on table \"${targetTypeName}\"${targetLocation} is used by both ` +\n `a forward relationship and a backward relationship from ${source.sourceType}.${source.fieldName}${sourceLocation}. ` +\n `Use the \"as\" option in .relation({ toward: { as: ... } }) or the \"backward\" option in .relation() to specify unique names.`,\n );\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(\n `Backward relation name conflicts detected in TailorDB service \"${namespace}\".\\n` +\n `${errors.map((e) => ` - ${e}`).join(\"\\n\")}`,\n );\n }\n}\n\n/**\n * Validate GraphQL query field name uniqueness.\n * Checks for:\n * 1. Each table's singular query name != plural query name\n * 2. No duplicate query names across all tables\n * @param types - Parsed tables\n * @param namespace - TailorDB namespace name\n * @param typeSourceInfo - Optional table source information\n */\nfunction validatePluralFormUniqueness(\n types: Record<string, TailorDBType>,\n namespace: string,\n typeSourceInfo?: TypeSourceInfo,\n): void {\n const errors: string[] = [];\n\n // Check 1: Each table's singular and plural query names must be different\n for (const [, parsedType] of Object.entries(types)) {\n const singularQuery = inflection.camelize(parsedType.name, true);\n const pluralQuery = inflection.camelize(parsedType.pluralForm, true);\n\n if (singularQuery === pluralQuery) {\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, parsedType.name);\n const location = formatTypeSourceLocation(sourceInfo);\n errors.push(\n `Table \"${parsedType.name}\"${location} has identical singular and plural query names \"${singularQuery}\". ` +\n `Use db.table([\"${parsedType.name}\", \"UniquePluralForm\"], {...}) to set a unique pluralForm.`,\n );\n }\n }\n\n // Check 2: All query names must be unique across tables\n const queryNameToSource = new Map<string, { tableName: string; kind: string }[]>();\n\n for (const parsedType of Object.values(types)) {\n const singularQuery = inflection.camelize(parsedType.name, true);\n const pluralQuery = inflection.camelize(parsedType.pluralForm, true);\n\n const singularSources = queryNameToSource.get(singularQuery) ?? [];\n singularSources.push({\n tableName: parsedType.name,\n kind: \"singular\",\n });\n queryNameToSource.set(singularQuery, singularSources);\n\n if (singularQuery !== pluralQuery) {\n const pluralSources = queryNameToSource.get(pluralQuery) ?? [];\n pluralSources.push({\n tableName: parsedType.name,\n kind: \"plural\",\n });\n queryNameToSource.set(pluralQuery, pluralSources);\n }\n }\n\n const duplicates = [...queryNameToSource].filter(([, sources]) => sources.length > 1);\n\n for (const [queryName, sources] of duplicates) {\n const sourceList = sources\n .map((s) => {\n const sourceInfo = getTypeSourceInfo(typeSourceInfo, s.tableName);\n const location = formatTypeSourceLocation(sourceInfo);\n return `\"${s.tableName}\"${location} (${s.kind})`;\n })\n .join(\", \");\n errors.push(`GraphQL query field \"${queryName}\" conflicts between: ${sourceList}`);\n }\n\n if (errors.length > 0) {\n throw new Error(\n `GraphQL field name conflicts detected in TailorDB service \"${namespace}\".\\n` +\n `${errors.map((e) => ` - ${e}`).join(\"\\n\")}`,\n );\n }\n}\n\nfunction getTypeSourceInfo(\n typeSourceInfo: TypeSourceInfo | undefined,\n tableName: string,\n): TypeSourceInfo[string] | undefined {\n return typeSourceInfo && Object.hasOwn(typeSourceInfo, tableName)\n ? typeSourceInfo[tableName]\n : undefined;\n}\n\nfunction formatTypeSourceLocation(sourceInfo: TypeSourceInfo[string] | undefined): string {\n if (!sourceInfo) {\n return \"\";\n }\n return isPluginGeneratedTable(sourceInfo)\n ? ` (plugin: ${sourceInfo.pluginId})`\n : ` (${sourceInfo.filePath})`;\n}\n\nfunction createRecord<T>(): Record<string, T> {\n return Object.create(null) as Record<string, T>;\n}\n","import { parseSync } from \"oxc-parser\";\nimport { ES_BUILTINS } from \"#/utils/es-builtins\";\nimport type { BindingPattern, Node, ParamPattern } from \"@oxc-project/types\";\n\n/** Fields that contain TypeScript type annotations (not runtime references). */\nexport const TS_TYPE_FIELDS = new Set([\n \"typeAnnotation\",\n \"typeParameters\",\n \"returnType\",\n \"superTypeArguments\",\n \"typeArguments\",\n]);\n\n/**\n * Recursively extract binding names from a destructuring pattern node.\n * @param pattern - The binding pattern AST node.\n * @param bindings - Set to collect binding names into.\n */\nfunction collectBindingsFromPattern(pattern: BindingPattern, bindings: Set<string>): void {\n switch (pattern.type) {\n case \"Identifier\":\n bindings.add(pattern.name);\n break;\n case \"ObjectPattern\":\n for (const prop of pattern.properties) {\n if (prop.type === \"RestElement\") {\n collectBindingsFromPattern(prop.argument, bindings);\n } else {\n collectBindingsFromPattern(prop.value, bindings);\n }\n }\n break;\n case \"ArrayPattern\":\n for (const elem of pattern.elements) {\n if (elem) {\n if (elem.type === \"RestElement\") {\n collectBindingsFromPattern(elem.argument, bindings);\n } else {\n collectBindingsFromPattern(elem, bindings);\n }\n }\n }\n break;\n case \"AssignmentPattern\":\n collectBindingsFromPattern(pattern.left, bindings);\n break;\n }\n}\n\nfunction isBindingPattern(param: ParamPattern): param is BindingPattern {\n return param.type !== \"TSParameterProperty\";\n}\n\n/**\n * A function-scope boundary (function declaration/expression, arrow\n * function, or the module root). Declarations resolve within the scope they\n * are collected into; references are checked against this chain at the end,\n * once every scope's bindings have been fully collected. Block-level\n * scoping (`let`/`const`/`catch` shadowing within an `if`/`for`/`{}`) is not\n * modeled — such bindings are attached to their nearest enclosing function\n * scope, which is safe for detecting a forbidden global reachable from\n * outside the block but does not detect one shadowed only within it.\n */\ninterface Scope {\n bindings: Set<string>;\n parent: Scope | null;\n}\n\nfunction isBoundInScope(scope: Scope, name: string): boolean {\n for (let s: Scope | null = scope; s; s = s.parent) {\n if (s.bindings.has(name)) return true;\n }\n return false;\n}\n\nconst NEGATIVE_EQUALITY_OPERATORS = new Set([\"!==\", \"!=\"]);\nconst POSITIVE_EQUALITY_OPERATORS = new Set([\"===\", \"==\"]);\n\n/**\n * Read the static string value of a string literal or a template literal with\n * no interpolated expressions (e.g. `` `object` ``, which minifiers use in\n * place of `\"object\"` — both are the same string at runtime).\n * @param node - Candidate literal AST node.\n * @returns The literal's string value, or undefined if `node` isn't one.\n */\nfunction staticStringValue(node: Node): string | undefined {\n if (node.type === \"Literal\" && typeof node.value === \"string\") return node.value;\n if (\n node.type === \"TemplateLiteral\" &&\n node.expressions.length === 0 &&\n node.quasis.length === 1\n ) {\n return node.quasis[0]?.value.cooked ?? undefined;\n }\n return undefined;\n}\n\n/**\n * If `expr` is a `typeof x === \"...\"` / `typeof x !== \"...\"` comparison that\n * is only true while `x` is declared, return `x`'s name. `typeof` never\n * throws on an undeclared identifier, so `typeof x !== \"undefined\" && x` (and\n * `typeof x === \"<anything but undefined>\" && x`) cannot actually reference\n * `x` when it is undeclared — this is the cross-environment global-detection\n * idiom used by es-toolkit, lodash, core-js, etc. The opposite direction —\n * `typeof x === \"undefined\" && x` or `typeof x !== \"<anything but\n * undefined>\" && x` — is true precisely when `x` is NOT safely usable (or\n * says nothing about it), so it must not be treated as a guard. Loose\n * equality (`==`/`!=`) is included because minifiers rewrite `===`/`!==`\n * against a `typeof` result to the loose form (the result is always a\n * string, so the two are equivalent there).\n * @param expr - Candidate comparison AST node.\n * @returns The guarded identifier's name, or undefined if `expr` doesn't guard one.\n */\nfunction typeofGuardTarget(expr: Node): string | undefined {\n if (expr.type !== \"BinaryExpression\") return undefined;\n const { left, right, operator } = expr;\n const [typeofSide, literalSide] =\n left.type === \"UnaryExpression\" &&\n left.operator === \"typeof\" &&\n left.argument.type === \"Identifier\"\n ? [left, right]\n : right.type === \"UnaryExpression\" &&\n right.operator === \"typeof\" &&\n right.argument.type === \"Identifier\"\n ? [right, left]\n : [undefined, undefined];\n if (!typeofSide) return undefined;\n const literalValue = staticStringValue(literalSide);\n if (literalValue === undefined) return undefined;\n const comparesToUndefined = literalValue === \"undefined\";\n const isSafe =\n (NEGATIVE_EQUALITY_OPERATORS.has(operator) && comparesToUndefined) ||\n (POSITIVE_EQUALITY_OPERATORS.has(operator) && !comparesToUndefined);\n if (!isSafe) return undefined;\n return (typeofSide.argument as { name: string }).name;\n}\n\n/**\n * Check whether `node` is `guardedName` itself, or a member-expression chain\n * rooted at it (`x.y`, `x.y[z]`), as in `typeof x !== \"undefined\" && x.y`.\n * Computed property expressions along the chain are still walked for their\n * own free variables (e.g. the `z` in `x.y[z]`) — only the guarded root\n * identifier is treated as safe.\n * @param node - Candidate right-hand side of a `typeof`-guarded `&&`.\n * @param guardedName - The identifier name the `typeof` check guards.\n * @param walk - The AST walker, used to visit computed property expressions.\n * @returns Whether `node` is entirely covered by the guard.\n */\nfunction walkGuardedChain(\n node: Node,\n guardedName: string,\n walk: (n: Node | null | undefined) => void,\n): boolean {\n if (node.type === \"Identifier\") {\n return node.name === guardedName;\n }\n if (node.type === \"MemberExpression\") {\n if (!walkGuardedChain(node.object, guardedName, walk)) return false;\n if (node.computed) walk(node.property);\n return true;\n }\n return false;\n}\n\n/**\n * Parse a code string with oxc-parser and return identifiers that are referenced\n * but never bound anywhere in the snippet (free variables), excluding ES builtins.\n * @param code - Valid JavaScript code to analyze.\n * @returns Set of undefined variable names.\n */\nexport function findUndefinedReferences(code: string): Set<string> {\n const { program, errors } = parseSync(\"_.js\", code);\n if (errors.length > 0) {\n const details = errors.map((error) => ` - ${error.message}`).join(\"\\n\");\n throw new Error(`Failed to parse code for free-variable analysis.\\nParse errors:\\n${details}`);\n }\n const references: { name: string; scope: Scope }[] = [];\n const rootScope: Scope = { bindings: new Set(), parent: null };\n let currentScope: Scope = rootScope;\n\n const walk = (node: Node | null | undefined): void => {\n if (!node) return;\n\n switch (node.type) {\n case \"VariableDeclarator\":\n collectBindingsFromPattern(node.id, currentScope.bindings);\n walk(node.init);\n return;\n\n case \"ImportDeclaration\":\n for (const specifier of node.specifiers) {\n currentScope.bindings.add(specifier.local.name);\n }\n return;\n\n case \"FunctionDeclaration\":\n case \"FunctionExpression\": {\n if (node.type === \"FunctionDeclaration\" && node.id) {\n currentScope.bindings.add(node.id.name);\n }\n const functionScope: Scope = { bindings: new Set(), parent: currentScope };\n if (node.type === \"FunctionExpression\" && node.id) {\n functionScope.bindings.add(node.id.name);\n }\n for (const param of node.params) {\n if (isBindingPattern(param)) {\n collectBindingsFromPattern(param, functionScope.bindings);\n }\n }\n const outerScope = currentScope;\n currentScope = functionScope;\n for (const param of node.params) {\n if (isBindingPattern(param)) walk(param);\n }\n walk(node.body);\n currentScope = outerScope;\n return;\n }\n\n case \"ArrowFunctionExpression\": {\n const functionScope: Scope = { bindings: new Set(), parent: currentScope };\n for (const param of node.params) {\n if (isBindingPattern(param)) {\n collectBindingsFromPattern(param, functionScope.bindings);\n }\n }\n const outerScope = currentScope;\n currentScope = functionScope;\n for (const param of node.params) {\n if (isBindingPattern(param)) walk(param);\n }\n walk(node.body);\n currentScope = outerScope;\n return;\n }\n\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n if (node.id) currentScope.bindings.add(node.id.name);\n walk(node.superClass);\n walk(node.body);\n return;\n\n case \"CatchClause\":\n if (node.param) collectBindingsFromPattern(node.param, currentScope.bindings);\n walk(node.body);\n return;\n\n case \"MemberExpression\":\n walk(node.object);\n if (node.computed) walk(node.property);\n return;\n\n case \"UnaryExpression\":\n if (node.operator === \"typeof\" && node.argument.type === \"Identifier\") {\n return;\n }\n walk(node.argument);\n return;\n\n case \"LogicalExpression\": {\n const guardedName = node.operator === \"&&\" ? typeofGuardTarget(node.left) : undefined;\n walk(node.left);\n if (guardedName && walkGuardedChain(node.right, guardedName, walk)) {\n return;\n }\n walk(node.right);\n return;\n }\n\n case \"Property\":\n if (node.computed) walk(node.key);\n walk(node.value);\n return;\n\n case \"MethodDefinition\":\n case \"TSAbstractMethodDefinition\":\n case \"PropertyDefinition\":\n case \"TSAbstractPropertyDefinition\":\n case \"AccessorProperty\":\n case \"TSAbstractAccessorProperty\":\n for (const decorator of node.decorators) walk(decorator.expression);\n if (node.computed) walk(node.key);\n walk(node.value);\n return;\n\n case \"LabeledStatement\":\n walk(node.body);\n return;\n\n case \"Identifier\":\n references.push({ name: node.name, scope: currentScope });\n return;\n\n default:\n break;\n }\n\n // Generic child walk for all other node types, skipping TS type-annotation fields\n const rec = node as unknown as Record<string, unknown>;\n for (const [key, value] of Object.entries(rec)) {\n if (key === \"type\" || TS_TYPE_FIELDS.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) walk(item as Node);\n } else if (value && typeof value === \"object\" && \"type\" in value) {\n walk(value as Node);\n }\n }\n };\n\n walk(program);\n\n // Free variables = references not bound in their own or any enclosing scope, minus builtins\n const freeVars = new Set<string>();\n for (const { name, scope } of references) {\n if (!isBoundInScope(scope, name) && !ES_BUILTINS.has(name)) {\n freeVars.add(name);\n }\n }\n return freeVars;\n}\n","import { readFileSync } from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport { resolve } from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { findUndefinedReferences, TS_TYPE_FIELDS } from \"#/cli/shared/free-variables\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { createTsconfigPathsPlugin } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport { stringifyFunction } from \"#/parser/service/tailordb/field\";\nimport { buildHookCallArgs } from \"#/parser/service/tailordb/hook-args-object\";\nimport {\n getPrecompiledScriptExpr,\n setPrecompiledScriptExpr,\n} from \"#/parser/service/tailordb/hooks-validate-precompiled-expr\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { assertParsableExpression } from \"#/utils/script-expr\";\nimport type { ScriptExprKind } from \"#/parser/service/tailordb/types\";\nimport type { TailorDBTypeRaw as TailorDBTypeSchemaOutput } from \"#/types/tailordb.generated\";\n\ntype ScriptFunction = (...args: unknown[]) => unknown;\n\ntype ScriptTarget = {\n fn: ScriptFunction;\n kind: ScriptExprKind;\n};\n\n/** Binding found in the source file: either an import or a top-level declaration */\nexport type SourceBinding = {\n name: string;\n /** The original source text of the import/declaration statement */\n sourceText: string;\n kind: \"import\" | \"declaration\";\n};\n\nfunction toScriptFunction(value: unknown, kind: ScriptExprKind): ScriptFunction | undefined {\n if (typeof value !== \"function\") return undefined;\n // Already pinned (e.g. a built-in SDK hook, see `db.fields.timestamps()`) - bundling\n // it again would derive a new expr from this build's `Function.prototype.toString()`\n // output and overwrite the pin.\n if (getPrecompiledScriptExpr(value as ScriptFunction, kind)) return undefined;\n return value as unknown as ScriptFunction;\n}\n\nfunction collectScriptTargets(type: TailorDBTypeSchemaOutput): ScriptTarget[] {\n const targets: ScriptTarget[] = [];\n\n const collectFieldTargets = (field: TailorDBTypeSchemaOutput[\"fields\"][string]) => {\n const metadata = field.metadata;\n\n const createHook = toScriptFunction(metadata.hooks?.create, \"hooks.create\");\n if (createHook) {\n targets.push({ fn: createHook, kind: \"hooks.create\" });\n }\n const updateHook = toScriptFunction(metadata.hooks?.update, \"hooks.update\");\n if (updateHook) {\n targets.push({ fn: updateHook, kind: \"hooks.update\" });\n }\n\n for (const validateInput of metadata.validate ?? []) {\n const validateFn = toScriptFunction(validateInput, \"validate\");\n if (validateFn) targets.push({ fn: validateFn, kind: \"validate\" });\n }\n\n if (field.type === \"nested\" && field.fields) {\n for (const nestedField of Object.values(field.fields as TailorDBTypeSchemaOutput[\"fields\"])) {\n collectFieldTargets(nestedField);\n }\n }\n };\n\n for (const field of Object.values(type.fields)) {\n collectFieldTargets(field);\n }\n\n if (type.metadata.typeHook) {\n for (const op of [\"create\", \"update\"] as const) {\n const kind = `typeHook.${op}` as const;\n const fn = toScriptFunction(type.metadata.typeHook[op], kind);\n if (fn) {\n targets.push({ fn, kind });\n }\n }\n }\n\n const typeValidateFn = toScriptFunction(type.metadata.typeValidate, \"typeValidate\");\n if (typeValidateFn) {\n targets.push({ fn: typeValidateFn, kind: \"typeValidate\" });\n }\n\n return targets;\n}\n\n/**\n * Collect all Identifier names from a TypeScript/JavaScript code string using oxc-parser.\n * @param code - Code string to analyze.\n * @returns Set of identifier names found in the code.\n */\nfunction collectIdentifierNames(code: string): Set<string> {\n const { program } = parseSync(\"_.ts\", code);\n const names = new Set<string>();\n const walk = (node: unknown): void => {\n if (!node || typeof node !== \"object\") return;\n const record = node as Record<string, unknown>;\n if (record.type === \"Identifier\" && typeof record.name === \"string\") {\n names.add(record.name);\n }\n for (const [key, value] of Object.entries(record)) {\n // Skip non-computed MemberExpression property (e.g. `length` in `value.length`)\n // but keep computed properties (e.g. `foo` in `obj[foo]`) as they are real references\n if (key === \"property\" && record.type === \"MemberExpression\" && !record.computed) continue;\n // Skip non-computed Property keys (e.g. `format` in `{ format: \"x\" }` is not a reference)\n if (key === \"key\" && record.type === \"Property\" && !record.computed) continue;\n // Skip TypeScript type annotation fields (not runtime references)\n if (TS_TYPE_FIELDS.has(key)) continue;\n if (Array.isArray(value)) {\n for (const item of value) walk(item);\n } else if (value && typeof value === \"object\" && \"type\" in value) {\n walk(value);\n }\n }\n };\n walk(program);\n return names;\n}\n\n/**\n * Collect top-level bindings (imports and declarations) from a TypeScript source file.\n * @param sourceFilePath - Absolute path to the source file.\n * @returns Map of binding name to SourceBinding.\n */\nexport function collectSourceBindings(sourceFilePath: string): Map<string, SourceBinding> {\n const source = readFileSync(sourceFilePath, \"utf-8\");\n const { program } = parseSync(sourceFilePath, source);\n const bindings = new Map<string, SourceBinding>();\n\n for (const stmt of program.body) {\n if (stmt.type === \"ImportDeclaration\") {\n const importDecl = stmt;\n const text = source.slice(importDecl.start, importDecl.end);\n for (const spec of importDecl.specifiers) {\n bindings.set(spec.local.name, {\n name: spec.local.name,\n sourceText: text,\n kind: \"import\",\n });\n }\n } else if (stmt.type === \"VariableDeclaration\") {\n const varDecl = stmt;\n const text = source.slice(varDecl.start, varDecl.end);\n for (const decl of varDecl.declarations) {\n if (decl.id.type === \"Identifier\") {\n bindings.set(decl.id.name, { name: decl.id.name, sourceText: text, kind: \"declaration\" });\n }\n }\n } else if (stmt.type === \"FunctionDeclaration\") {\n const funcDecl = stmt;\n if (funcDecl.id) {\n const text = source.slice(funcDecl.start, funcDecl.end);\n bindings.set(funcDecl.id.name, {\n name: funcDecl.id.name,\n sourceText: text,\n kind: \"declaration\",\n });\n }\n } else if (stmt.type === \"ExportNamedDeclaration\") {\n const exportDecl = stmt;\n const innerDecl = exportDecl.declaration;\n if (!innerDecl) continue;\n\n if (innerDecl.type === \"VariableDeclaration\") {\n const varDecl = innerDecl;\n // Slice only the inner declaration (without export keyword) so it is valid standalone\n const text = source.slice(varDecl.start, varDecl.end);\n for (const decl of varDecl.declarations) {\n if (decl.id.type === \"Identifier\") {\n bindings.set(decl.id.name, {\n name: decl.id.name,\n sourceText: text,\n kind: \"declaration\",\n });\n }\n }\n } else if (innerDecl.type === \"FunctionDeclaration\") {\n const funcDecl = innerDecl;\n if (funcDecl.id) {\n const text = source.slice(funcDecl.start, funcDecl.end);\n bindings.set(funcDecl.id.name, {\n name: funcDecl.id.name,\n sourceText: text,\n kind: \"declaration\",\n });\n }\n }\n }\n }\n\n return bindings;\n}\n\n/**\n * Resolve all bindings needed by a function, recursively including\n * dependencies of top-level declarations.\n * @param freeVars - Set of free variable names extracted from the function.\n * @param sourceBindings - Available bindings from the source file.\n * @returns Object with needed import statements and declaration texts.\n */\nexport function resolveNeededBindings(\n freeVars: Set<string>,\n sourceBindings: Map<string, SourceBinding>,\n): { imports: string[]; declarations: string[]; unresolved: string[] } {\n const neededImports = new Set<string>();\n const neededDeclarations = new Set<string>();\n const unresolved: string[] = [];\n const resolved = new Set<string>();\n\n const resolveVars = (vars: Set<string>): void => {\n for (const varName of vars) {\n if (resolved.has(varName)) continue;\n resolved.add(varName);\n\n const binding = sourceBindings.get(varName);\n if (!binding) {\n unresolved.push(varName);\n continue;\n }\n\n if (binding.kind === \"import\") {\n neededImports.add(binding.sourceText);\n } else {\n // Parse the declaration with oxc-parser (handles TypeScript) and collect\n // all Identifier names, then resolve those that match other source bindings.\n const identifiers = collectIdentifierNames(binding.sourceText);\n const referencedVars = new Set<string>();\n for (const id of identifiers) {\n if (id !== varName && sourceBindings.has(id)) {\n referencedVars.add(id);\n }\n }\n resolveVars(referencedVars);\n neededDeclarations.add(binding.sourceText);\n }\n }\n };\n\n resolveVars(freeVars);\n\n return {\n imports: [...neededImports],\n declarations: [...neededDeclarations],\n unresolved,\n };\n}\n\nfunction buildPrecompiledExpr(bundleCode: string, argsObject: string): string {\n return (\n \"(() => {\\n\" +\n \" const module = { exports: {} };\\n\" +\n \" const exports = module.exports;\\n\" +\n `${bundleCode}\\n` +\n ` return module.exports.main(${argsObject});\\n` +\n \"})()\"\n );\n}\n\n/**\n * Build entry file content from already-resolved imports and declarations.\n * @param imports - Import statement texts.\n * @param declarations - Declaration statement texts.\n * @param fnSource - The function source code.\n * @param sourceFilePath - Path to the source file for resolving relative imports.\n * @param multiArg - Whether the function accepts multiple arguments (spread via `...args`).\n * @returns Entry file content string.\n */\nexport function buildMinimalEntryFromResolved(\n imports: string[],\n declarations: string[],\n fnSource: string,\n sourceFilePath: string,\n multiArg = false,\n): string {\n const sourceDir = resolve(sourceFilePath, \"..\").replace(/\\\\/g, \"/\");\n\n // Rewrite relative import paths to absolute paths so rolldown can resolve them\n const resolvedImports = imports.map((imp) =>\n imp.replace(\n /from\\s+[\"'](\\.[^\"']+)[\"']/g,\n (_match, relPath: string) => `from \"${resolve(sourceDir, relPath).replace(/\\\\/g, \"/\")}\"`,\n ),\n );\n\n const lines = [\n ...resolvedImports,\n ...declarations,\n multiArg\n ? `export function main(...args) { return (${fnSource})(...args); }`\n : `export function main(input) { return (${fnSource})(input); }`,\n ];\n return lines.join(\"\\n\");\n}\n\nasync function bundleScriptTarget(args: {\n fn: ScriptFunction;\n kind: ScriptExprKind;\n sourceFilePath: string;\n sourceBindings: Map<string, SourceBinding>;\n tableName: string;\n targetIndex: number;\n tsconfig: string | undefined;\n}): Promise<string> {\n const { fn, kind, sourceFilePath, sourceBindings, tableName, targetIndex, tsconfig } = args;\n const context = `${kind} in ${sourceFilePath}`;\n const fnSource = stringifyFunction(fn);\n if ((kind === \"typeValidate\" || kind === \"validate\") && fn.constructor.name === \"AsyncFunction\") {\n throw new Error(\n `${context} must be synchronous — the generated validator runs synchronously, ` +\n \"so issues reported after an await are silently lost. Remove the async keyword.\",\n );\n }\n const inlineExpr = assertParsableExpression(`(${fnSource})(${buildHookCallArgs(kind)})`, context);\n\n // Check if the function has free variables that need bundling\n const freeVars = findUndefinedReferences(`const __fn = ${fnSource};`);\n if (freeVars.size === 0) {\n // No external dependencies - use inline expression without bundling\n return inlineExpr;\n }\n\n const { imports, declarations, unresolved } = resolveNeededBindings(freeVars, sourceBindings);\n if (unresolved.length > 0) {\n throw new Error(\n `${context} captures unresolvable variables (${unresolved.join(\", \")}). ` +\n \"Hooks and validators must not reference variables that cannot be resolved from the source file.\\n\" +\n ` ${kind}: ${fnSource}`,\n );\n }\n\n const entryContent = buildMinimalEntryFromResolved(\n imports,\n declarations,\n fnSource,\n sourceFilePath,\n kind === \"typeValidate\",\n );\n const entry = createVirtualEntry(\n `tailordb-script:${tableName}:${targetIndex}`,\n entryContent,\n \"ts\",\n sourceFilePath,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const buildResult = await rolldown.build({\n plugins: [\n entry.plugin,\n createTsconfigPathsPlugin({ virtualEntrySourceFile: sourceFilePath }),\n platformBundleDefinePlugin,\n ],\n input: entry.input,\n write: false,\n output: {\n format: \"cjs\",\n sourcemap: false,\n minify: true,\n codeSplitting: false,\n },\n tsconfig,\n treeshake: {\n moduleSideEffects: false,\n annotations: true,\n unknownGlobalSideEffects: false,\n },\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = buildResult.output[0].code;\n return assertParsableExpression(\n buildPrecompiledExpr(bundledCode, buildHookCallArgs(kind)),\n context,\n );\n}\n\n/**\n * Precompile TailorDB hooks/validators into self-contained script expressions using rolldown.\n * Uses oxc-parser AST walking to extract free variables from functions, then builds\n * minimal entry points containing only the needed imports and declarations.\n * @param type - TailorDB table schema output.\n * @param sourceFilePath - Source file where the table is defined.\n * @param tsconfig - Resolved tsconfig path, or undefined if not found.\n */\nexport async function precompileTailorDBTypeScripts(\n type: TailorDBTypeSchemaOutput,\n sourceFilePath: string,\n tsconfig: string | undefined,\n): Promise<void> {\n const targets = collectScriptTargets(type);\n if (targets.length === 0) return;\n\n // Collect source bindings once for all targets in this file\n const sourceBindings = collectSourceBindings(sourceFilePath);\n\n const results = await Promise.allSettled(\n targets.map((target, index) =>\n bundleScriptTarget({\n fn: target.fn,\n kind: target.kind,\n sourceFilePath,\n sourceBindings,\n tableName: type.name,\n targetIndex: index,\n tsconfig,\n }),\n ),\n );\n const firstError = results.find((r): r is PromiseRejectedResult => r.status === \"rejected\");\n if (firstError) {\n throw firstError.reason;\n }\n for (const [index, result] of results.entries()) {\n if (result.status === \"fulfilled\") {\n const target = assertDefined(targets[index], `bundle target at index ${index} missing`);\n setPrecompiledScriptExpr(target.fn, target.kind, result.value);\n }\n }\n}\n","import { fetchAll, isNotFoundError } from \"#/cli/shared/client\";\nimport { isPluginGeneratedTable } from \"#/parser/service/tailordb/type-source\";\nimport type { TypeSourceInfo, TypeSourceInfoEntry } from \"#/parser/service/tailordb/types\";\n\ntype LocalTailorDBService = {\n readonly namespace: string;\n readonly types: Readonly<Record<string, unknown>>;\n readonly typeSourceInfo: Readonly<TypeSourceInfo>;\n};\n\ntype TailorDBTypeNameSourceKind = \"local\" | \"external\";\n\nexport type TailorDBTypeNameSource = {\n readonly namespace: string;\n readonly tableName: string;\n readonly kind: TailorDBTypeNameSourceKind;\n readonly detail?: string;\n};\n\ntype ListTailorDBTypesArgs = {\n workspaceId: string;\n namespaceName: string;\n pageToken?: string;\n pageSize?: number;\n};\n\ntype ListTailorDBTypesResult = {\n tailordbTypes: Array<{ name: string }>;\n nextPageToken?: string;\n};\n\ntype ListTailorDBTypesClient = {\n listTailorDBTypes(args: ListTailorDBTypesArgs): Promise<ListTailorDBTypesResult>;\n};\n\nexport interface CollectLocalTailorDBTypeNameSourcesArgs {\n /** Loaded local TailorDB services. */\n tailorDBServices: ReadonlyArray<LocalTailorDBService>;\n}\n\nexport interface FetchExternalTailorDBTypeNameSourcesArgs {\n /** Client used to read TailorDB metadata. */\n client: ListTailorDBTypesClient;\n /** Workspace that owns the configured namespaces. */\n workspaceId: string;\n /** External TailorDB namespaces declared in the application config. */\n externalTailorDBNamespaces: ReadonlyArray<string>;\n}\n\ninterface AssertUniqueTailorDBTypeNamesArgs {\n /** Table-name sources to validate. */\n sources: ReadonlyArray<TailorDBTypeNameSource>;\n}\n\nexport interface AssertUniqueTailorDBTypeNamesWithExternalArgs\n extends CollectLocalTailorDBTypeNameSourcesArgs, FetchExternalTailorDBTypeNameSourcesArgs {\n /** External TailorDB services planned in the same deploy run. */\n plannedExternalTailorDBServices?: ReadonlyArray<LocalTailorDBService>;\n}\n\n/**\n * Format a TailorDB table source for validation errors.\n * @param sourceInfo - Source information captured when loading the table\n * @returns Human-readable source detail\n */\nexport function formatTailorDBTypeSourceInfo(\n sourceInfo: TypeSourceInfoEntry | undefined,\n): string | undefined {\n if (!sourceInfo) {\n return undefined;\n }\n\n if (isPluginGeneratedTable(sourceInfo)) {\n const parts = [`plugin ${sourceInfo.pluginId}`];\n if (sourceInfo.generatedTableKind) {\n parts.push(`kind ${sourceInfo.generatedTableKind}`);\n }\n if (sourceInfo.originalFilePath) {\n parts.push(`source ${sourceInfo.originalFilePath}`);\n }\n if (sourceInfo.originalExportName) {\n parts.push(`export ${sourceInfo.originalExportName}`);\n }\n return parts.join(\", \");\n }\n\n return `${sourceInfo.filePath} export ${sourceInfo.exportName}`;\n}\n\n/**\n * Collect TailorDB table-name sources from loaded local services.\n * @param args - Collection inputs\n * @returns Table-name sources for local services\n */\nfunction collectLocalTailorDBTypeNameSources(\n args: CollectLocalTailorDBTypeNameSourcesArgs,\n): TailorDBTypeNameSource[] {\n const sources: TailorDBTypeNameSource[] = [];\n\n for (const service of args.tailorDBServices) {\n for (const tableName of Object.keys(service.types)) {\n sources.push({\n namespace: service.namespace,\n tableName,\n kind: \"local\",\n detail: formatTailorDBTypeSourceInfo(service.typeSourceInfo[tableName]),\n });\n }\n }\n\n return sources;\n}\n\n/**\n * Fetch TailorDB table-name sources for external namespaces.\n * @param args - Fetch inputs\n * @returns Table-name sources for external services\n */\nexport async function fetchExternalTailorDBTypeNameSources(\n args: FetchExternalTailorDBTypeNameSourcesArgs,\n): Promise<TailorDBTypeNameSource[]> {\n const sourcesByNamespace = await Promise.all(\n args.externalTailorDBNamespaces.map(async (namespace) => {\n const sources: TailorDBTypeNameSource[] = [];\n const tailordbTypes = await fetchAll(async (pageToken, maxPageSize) => {\n try {\n const { tailordbTypes, nextPageToken } = await args.client.listTailorDBTypes({\n workspaceId: args.workspaceId,\n namespaceName: namespace,\n pageToken,\n pageSize: maxPageSize,\n });\n return [tailordbTypes, nextPageToken ?? \"\"];\n } catch (error) {\n if (isNotFoundError(error)) {\n return [[], \"\"];\n }\n throw error;\n }\n });\n\n for (const type of tailordbTypes) {\n sources.push({\n namespace,\n tableName: type.name,\n kind: \"external\",\n });\n }\n\n return sources;\n }),\n );\n\n return sourcesByNamespace.flat();\n}\n\n/**\n * Assert that TailorDB table names are unique across all supplied sources.\n * @param args - Validation inputs\n */\nfunction assertUniqueTailorDBTypeNames(args: AssertUniqueTailorDBTypeNamesArgs): void {\n const sourcesByTableName = new Map<string, TailorDBTypeNameSource[]>();\n\n for (const source of args.sources) {\n const existing = sourcesByTableName.get(source.tableName);\n if (existing) {\n existing.push(source);\n } else {\n sourcesByTableName.set(source.tableName, [source]);\n }\n }\n\n const errors: string[] = [];\n for (const [tableName, sources] of sourcesByTableName) {\n if (sources.length <= 1) {\n continue;\n }\n\n const sourceList = sources.map(formatTailorDBTypeNameSource).join(\", \");\n errors.push(`Table \"${tableName}\" is defined more than once: ${sourceList}`);\n }\n\n if (errors.length > 0) {\n throw new Error(\n \"Duplicate TailorDB table names detected.\\n\" +\n `${errors.map((error) => ` - ${error}`).join(\"\\n\")}\\n` +\n \"TailorDB table names must be unique across all TailorDB namespaces in an application.\",\n );\n }\n}\n\n/**\n * Assert local TailorDB table names are unique.\n * @param args - Validation inputs\n */\nexport function assertUniqueLocalTailorDBTypeNames(\n args: CollectLocalTailorDBTypeNameSourcesArgs,\n): void {\n assertUniqueTailorDBTypeNames({\n sources: collectLocalTailorDBTypeNameSources(args),\n });\n}\n\n/**\n * Assert TailorDB table names are unique across local and external namespaces.\n * @param args - Validation inputs\n */\nexport async function assertUniqueTailorDBTypeNamesWithExternal(\n args: AssertUniqueTailorDBTypeNamesWithExternalArgs,\n): Promise<void> {\n const localSources = collectLocalTailorDBTypeNameSources(args);\n const plannedExternalServices = args.plannedExternalTailorDBServices ?? [];\n const plannedExternalNamespaces = new Set(\n plannedExternalServices.map((service) => service.namespace),\n );\n const plannedExternalSources = collectLocalTailorDBTypeNameSources({\n tailorDBServices: plannedExternalServices,\n }).map((source) => ({\n ...source,\n kind: \"external\" as const,\n }));\n const remoteExternalNamespaces = args.externalTailorDBNamespaces.filter(\n (namespace) => !plannedExternalNamespaces.has(namespace),\n );\n const externalSources =\n remoteExternalNamespaces.length > 0\n ? await fetchExternalTailorDBTypeNameSources({\n client: args.client,\n workspaceId: args.workspaceId,\n externalTailorDBNamespaces: remoteExternalNamespaces,\n })\n : [];\n\n assertUniqueTailorDBTypeNames({\n sources: [...localSources, ...plannedExternalSources, ...externalSources],\n });\n}\n\nfunction formatTailorDBTypeNameSource(source: TailorDBTypeNameSource): string {\n const namespaceLabel =\n source.kind === \"external\"\n ? `external namespace \"${source.namespace}\"`\n : `namespace \"${source.namespace}\"`;\n\n return source.detail ? `${namespaceLabel} (${source.detail})` : namespaceLabel;\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport {\n pickTailorDBTypeSchemaKeys,\n stripTailorDBTypeBuilderHelpers,\n} from \"#/parser/service/tailordb/builder-helpers\";\nimport { parseTypes, TailorDBTypeSchema } from \"#/parser/service/tailordb/index\";\nimport {\n findMissingPermissionConfig,\n findOmittedPermitRules,\n} from \"#/parser/service/tailordb/permission\";\nimport { getRawPluginTableName } from \"#/plugin/guards\";\nimport { assertDefined } from \"#/utils/assert\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport { precompileTailorDBTypeScripts } from \"./hooks-validate-bundler\";\nimport { formatTailorDBTypeSourceInfo } from \"./type-name-validation\";\nimport type {\n TypeSourceInfo,\n TypeSourceInfoEntry,\n TailorDBType,\n} from \"#/parser/service/tailordb/types\";\nimport type { PluginManager } from \"#/plugin/manager\";\nimport type { PluginAttachment } from \"#/plugin/types\";\nimport type {\n TailorDBServiceConfig,\n TailorDBTypeRaw as TailorDBTypeSchemaOutput,\n} from \"#/types/tailordb.generated\";\n\nexport type TailorDBService = {\n readonly namespace: string;\n readonly config: TailorDBServiceConfig;\n readonly types: Readonly<Record<string, TailorDBType>>;\n readonly typeSourceInfo: Readonly<TypeSourceInfo>;\n readonly pluginAttachments: ReadonlyMap<string, readonly PluginAttachment[]>;\n loadTypes: () => Promise<Record<string, TailorDBType> | undefined>;\n processNamespacePlugins: () => Promise<void>;\n};\n\n/**\n * Parameters for creating a TailorDBService\n */\nexport interface CreateTailorDBServiceParams {\n /** The namespace for this TailorDB service */\n namespace: string;\n /** The TailorDB service configuration */\n config: TailorDBServiceConfig;\n /** Plugin manager for processing plugins */\n pluginManager?: PluginManager;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\n/**\n * Creates a new TailorDBService instance.\n * @param params - Parameters for creating the service\n * @returns A new TailorDBService instance\n */\nexport function createTailorDBService(params: CreateTailorDBServiceParams): TailorDBService {\n const { namespace, config, pluginManager, baseDir } = params;\n type TailorDBTypesByName = Record<string, TailorDBTypeSchemaOutput>;\n const createRawTypesByName = (): TailorDBTypesByName =>\n Object.create(null) as TailorDBTypesByName;\n const rawTypes = Object.create(null) as Record<string, TailorDBTypesByName>;\n let types: Record<string, TailorDBType> = {};\n const typeSourceInfo = Object.create(null) as TypeSourceInfo;\n const pluginAttachments: Map<string, PluginAttachment[]> = new Map();\n let loadPromise: Promise<Record<string, TailorDBType> | undefined> | undefined;\n\n const registerRawType = (\n rawTypesKey: string,\n tableName: string,\n type: TailorDBTypeSchemaOutput,\n sourceInfo: TypeSourceInfoEntry,\n ): void => {\n const existingSourceInfo = Object.hasOwn(typeSourceInfo, tableName)\n ? typeSourceInfo[tableName]\n : undefined;\n if (existingSourceInfo) {\n const firstSource = formatTailorDBTypeSourceInfo(existingSourceInfo) ?? \"unknown source\";\n const secondSource = formatTailorDBTypeSourceInfo(sourceInfo) ?? \"unknown source\";\n throw new Error(\n `Duplicate TailorDB table name \"${tableName}\" detected in TailorDB service \"${namespace}\". ` +\n `First: ${firstSource}. Second: ${secondSource}. ` +\n \"TailorDB table names must be unique across all TailorDB files in a service.\",\n );\n }\n\n assertDefined(rawTypes[rawTypesKey], `raw table entry missing for key: ${rawTypesKey}`)[\n tableName\n ] = type;\n typeSourceInfo[tableName] = sourceInfo;\n };\n\n // Plugin-emitted tables are runtime values the schema has never seen, unlike\n // user tables which are parsed in loadTypeFile; validate them here so a\n // malformed table fails with the offending plugin named instead of crashing\n // (or silently passing) during permission normalization.\n const parsePluginTable = (table: unknown, origin: string): TailorDBTypeSchemaOutput => {\n const result = TailorDBTypeSchema.safeParse(pickTailorDBTypeSchemaKeys(table));\n if (!result.success) {\n const issues = result.error.issues\n .map((issue) => ` - ${issue.path.map(String).join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"\\n\");\n throw new Error(\n `TailorDB table ${origin} in TailorDB service \"${namespace}\" failed schema validation:\\n${issues}`,\n { cause: result.error },\n );\n }\n return result.data;\n };\n\n const describeGeneratedTable = (name: unknown, kind: string, pluginId: string): string => {\n const namePart = typeof name === \"string\" && name.length > 0 ? `\"${name}\" ` : \"\";\n return `${namePart}generated as \"${kind}\" by plugin \"${pluginId}\"`;\n };\n\n const doParseTypes = (): void => {\n const allTypes = createRawTypesByName();\n for (const fileTypes of Object.values(rawTypes)) {\n for (const [tableName, type] of Object.entries(fileTypes)) {\n allTypes[tableName] = type;\n }\n }\n\n types = parseTypes(allTypes, namespace, typeSourceInfo);\n };\n\n // Warn about object-format permission rules that omit `permit`. Those default\n // to \"deny\" (unlike the array shorthand, which defaults to \"allow\"), an easy\n // way to accidentally lock out access the rule was meant to grant.\n const warnOmittedPermit = (): void => {\n for (const fileTypes of Object.values(rawTypes)) {\n for (const [tableName, type] of Object.entries(fileTypes)) {\n const locations = findOmittedPermitRules(type.metadata.permissions);\n if (locations.length > 0) {\n logger.warn(\n `TailorDB table \"${tableName}\" has permission rule(s) ${locations.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 }\n }\n };\n\n // Require .permission()/.gqlPermission() to be set explicitly. TailorDB\n // fails closed for record operations without a .permission(), producing an\n // opaque \"internal error\" instead of a clear denial when only\n // .gqlPermission() is set. Catching the omission here, rather than at\n // deploy/insert time, surfaces it while the table is still local.\n const validateRequiredPermissions = (): void => {\n const errors: string[] = [];\n for (const fileTypes of Object.values(rawTypes)) {\n for (const [tableName, type] of Object.entries(fileTypes)) {\n const effectiveGqlOperations =\n type.metadata.settings?.gqlOperations ?? config.gqlOperations;\n const { missingPermission, missingGqlPermission } = findMissingPermissionConfig(\n type.metadata.permissions,\n effectiveGqlOperations,\n );\n if (!missingPermission && !missingGqlPermission) {\n continue;\n }\n const source = formatTailorDBTypeSourceInfo(typeSourceInfo[tableName]);\n const location = source ? ` (${source})` : \"\";\n if (missingPermission) {\n errors.push(\n `TailorDB table \"${tableName}\"${location} has no .permission() configured. TailorDB denies all record operations for tables without permission; call .permission(...) to grant access explicitly.`,\n );\n }\n if (missingGqlPermission) {\n errors.push(\n `TailorDB table \"${tableName}\"${location} has no .gqlPermission() configured, but GraphQL operations are enabled for it. Call .gqlPermission(...) to grant GraphQL access explicitly, or disable GraphQL exposure with .features({ gqlOperations: { create: false, update: false, delete: false, read: false } }).`,\n );\n }\n }\n }\n if (errors.length > 0) {\n throw new Error(\n `TailorDB permission configuration errors in service \"${namespace}\":\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`,\n );\n }\n };\n\n /**\n * Process plugins for a table and add generated tables to rawTypes\n * @param rawTable - The raw TailorDB table being processed\n * @param attachments - Plugin attachments for this table\n * @param sourceFilePath - The file path where the table was loaded from\n */\n const processPluginsForTable = async (\n rawTable: TailorDBTypeSchemaOutput,\n attachments: PluginAttachment[],\n sourceFilePath: string,\n ): Promise<void> => {\n if (!pluginManager) return;\n\n const { extendedTable, generatedTables, events } =\n await pluginManager.processAttachmentsForTable({\n rawTable,\n attachments,\n namespace,\n });\n\n // Validate every plugin output before registering any of it, so a failure\n // does not leave partially registered state behind.\n const extendingPluginIds = [\n ...new Set(events.filter((ev) => ev.kind === \"extended\").map((ev) => ev.pluginId)),\n ];\n const parsedExtendedTable =\n extendedTable === undefined\n ? undefined\n : parsePluginTable(\n extendedTable,\n `\"${rawTable.name}\" extended by ${extendingPluginIds.length === 1 ? \"plugin\" : \"plugins\"} ${extendingPluginIds.map((id) => `\"${id}\"`).join(\", \")}`,\n );\n const parsedGeneratedTables = generatedTables.map((generatedTable) => ({\n ...generatedTable,\n table: parsePluginTable(\n generatedTable.table,\n describeGeneratedTable(\n generatedTable.tableName,\n generatedTable.kind,\n generatedTable.pluginId,\n ),\n ),\n }));\n\n if (parsedExtendedTable) {\n assertDefined(\n rawTypes[sourceFilePath],\n `raw table entry missing for file: ${sourceFilePath}`,\n )[rawTable.name] = parsedExtendedTable;\n }\n for (const generatedTable of parsedGeneratedTables) {\n // Plugin-generated tables don't have a source file.\n // Generators that need to import these tables should generate their own type files.\n const sourceInfo: TypeSourceInfoEntry = {\n exportName: generatedTable.tableName,\n pluginId: generatedTable.pluginId,\n pluginImportPath: generatedTable.pluginImportPath,\n originalFilePath: sourceFilePath,\n originalExportName: typeSourceInfo[rawTable.name]?.exportName || rawTable.name,\n generatedTableKind: generatedTable.kind,\n pluginConfig: generatedTable.pluginConfig,\n namespace,\n };\n registerRawType(sourceFilePath, generatedTable.tableName, generatedTable.table, sourceInfo);\n }\n for (const ev of events) {\n if (ev.kind === \"extended\") {\n logger.log(\n ` Extended: ${styles.success(ev.tableName)} with ${styles.highlight(ev.fieldCount.toString())} fields by plugin ${styles.info(ev.pluginId)}`,\n );\n } else {\n logger.log(\n ` Generated: ${styles.success(ev.tableName)} by plugin ${styles.info(ev.pluginId)}`,\n );\n }\n }\n };\n\n const loadTypeFile = async (\n typeFile: string,\n tsconfig: string | undefined,\n ): Promise<TailorDBTypesByName> => {\n rawTypes[typeFile] = createRawTypesByName();\n const loadedTypes = createRawTypesByName();\n try {\n const module = await importUserModule(typeFile);\n\n for (const exportName of Object.keys(module)) {\n const exportedValue = module[exportName];\n\n const result = TailorDBTypeSchema.safeParse(stripTailorDBTypeBuilderHelpers(exportedValue));\n if (!result.success) {\n if (isSdkBranded(exportedValue, \"tailordb-type\")) {\n throw result.error;\n }\n continue;\n }\n\n const relativePath = path.relative(process.cwd(), typeFile);\n logger.log(\n `Type: ${styles.successBright(`\"${result.data.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n await precompileTailorDBTypeScripts(result.data, typeFile, tsconfig);\n loadedTypes[result.data.name] = result.data;\n registerRawType(typeFile, result.data.name, result.data, {\n filePath: typeFile,\n exportName,\n });\n\n // Process plugins if any\n const rawType = exportedValue as TailorDBTypeSchemaOutput & {\n plugins?: PluginAttachment[];\n };\n if (rawType.plugins && Array.isArray(rawType.plugins) && rawType.plugins.length > 0) {\n pluginAttachments.set(rawType.name, [...rawType.plugins]);\n logger.log(\n ` Plugin attachments: ${styles.info(rawType.plugins.map((p) => p.pluginId).join(\", \"))}`,\n );\n\n await processPluginsForTable(rawType, rawType.plugins, typeFile);\n }\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), typeFile);\n logger.error(`Failed to load table from ${styles.bold(relativePath)}`);\n logger.error(String(error));\n throw error;\n }\n return loadedTypes;\n };\n\n return {\n namespace,\n config,\n get types() {\n return types;\n },\n get typeSourceInfo() {\n return typeSourceInfo;\n },\n get pluginAttachments() {\n return pluginAttachments as ReadonlyMap<string, readonly PluginAttachment[]>;\n },\n loadTypes: async () => {\n if (!loadPromise) {\n loadPromise = (async () => {\n if (config.files.length === 0) {\n return undefined;\n }\n\n const typeFiles = [...new Set(loadFilesWithIgnores(config, baseDir))];\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n logger.newline();\n logger.log(\n `Found ${styles.highlight(typeFiles.length.toString())} table files for TailorDB service ${styles.highlight(`\"${namespace}\"`)}`,\n );\n\n if (pluginManager) {\n for (const typeFile of typeFiles) {\n await loadTypeFile(typeFile, tsconfig);\n }\n } else {\n await Promise.all(typeFiles.map((typeFile) => loadTypeFile(typeFile, tsconfig)));\n }\n doParseTypes();\n warnOmittedPermit();\n validateRequiredPermissions();\n return types;\n })();\n }\n return loadPromise;\n },\n processNamespacePlugins: async () => {\n if (!pluginManager) return;\n\n const results = await pluginManager.processNamespacePlugins(namespace);\n const pluginGeneratedKey = \"__plugin_generated__\";\n\n const successfulResults = results.map(({ pluginId, config, result }) => {\n if (!result.success) {\n logger.error(result.error);\n throw new Error(result.error);\n }\n return { pluginId, config, output: result.output };\n });\n\n // Validate every generated table before mutating rawTypes/typeSourceInfo,\n // so a failure does not leave partially registered state behind.\n const parsedGeneratedTables = successfulResults.flatMap(({ pluginId, config, output }) =>\n Object.entries(output.tables ?? {}).map(([kind, generatedTable]) => ({\n pluginId,\n config,\n kind,\n table: parsePluginTable(\n generatedTable,\n describeGeneratedTable(getRawPluginTableName(generatedTable), kind, pluginId),\n ),\n })),\n );\n\n const hasPreviousGeneratedTables = Object.hasOwn(rawTypes, pluginGeneratedKey);\n const previousGeneratedTables = rawTypes[pluginGeneratedKey];\n const previousGeneratedTableKeys = previousGeneratedTables\n ? Object.keys(previousGeneratedTables)\n : [];\n const hadPreviousGeneratedTables = previousGeneratedTableKeys.length > 0;\n if (hasPreviousGeneratedTables) {\n for (const tableName of previousGeneratedTableKeys) {\n delete typeSourceInfo[tableName];\n }\n }\n rawTypes[pluginGeneratedKey] = createRawTypesByName();\n\n for (const { pluginId, config, kind, table } of parsedGeneratedTables) {\n const sourceInfo: TypeSourceInfoEntry = {\n exportName: table.name,\n pluginId,\n pluginImportPath: pluginManager.getPluginImportPath(pluginId) ?? \"\",\n originalFilePath: \"\",\n originalExportName: \"\",\n generatedTableKind: kind,\n pluginConfig: config,\n namespace,\n };\n registerRawType(pluginGeneratedKey, table.name, table, sourceInfo);\n\n logger.log(\n ` Generated: ${styles.success(table.name)} by namespace plugin ${styles.info(pluginId)}`,\n );\n }\n\n // Re-parse tables to include namespace plugin tables\n if (parsedGeneratedTables.length > 0 || hadPreviousGeneratedTables) {\n doParseTypes();\n validateRequiredPermissions();\n }\n },\n };\n}\n","import { type TailorDBService } from \"#/cli/services/tailordb/service\";\nimport { type AuthConfigSchema } from \"#/parser/service/auth/index\";\nimport { assertDefined } from \"#/utils/assert\";\nimport type { AuthConnectionConfig } from \"#/types/auth-connection.generated\";\nimport type { z } from \"zod\";\n\n/**\n * Auth config after `AuthConfigSchema.parse` (e.g. token lifetimes as Duration).\n */\ntype ParsedAuthConfig = z.output<typeof AuthConfigSchema>;\n\ntype UserProfile = NonNullable<ParsedAuthConfig[\"userProfile\"]> & {\n namespace: string;\n};\n\nexport type AuthService = {\n readonly config: ParsedAuthConfig;\n readonly tailorDBServices: ReadonlyArray<TailorDBService>;\n readonly externalTailorDBNamespaces: ReadonlyArray<string>;\n readonly connections: Readonly<Record<string, AuthConnectionConfig>>;\n readonly userProfile: UserProfile | undefined;\n resolveNamespaces: () => Promise<void>;\n};\n\n/**\n * Creates a new AuthService instance.\n * @param config - The auth configuration\n * @param tailorDBServices - The TailorDB services\n * @param externalTailorDBNamespaces - External TailorDB namespaces\n * @returns A new AuthService instance\n */\nexport function createAuthService(\n config: ParsedAuthConfig,\n tailorDBServices: ReadonlyArray<TailorDBService>,\n externalTailorDBNamespaces: ReadonlyArray<string>,\n): AuthService {\n const connections: Record<string, AuthConnectionConfig> = config.connections\n ? { ...config.connections }\n : {};\n\n let userProfile: UserProfile | undefined;\n\n return {\n config,\n tailorDBServices,\n externalTailorDBNamespaces,\n connections,\n get userProfile() {\n return userProfile;\n },\n resolveNamespaces: async () => {\n // No userProfile defined\n if (!config.userProfile) {\n return;\n }\n\n // 1. Explicit namespace\n if (config.userProfile.namespace) {\n userProfile = {\n ...config.userProfile,\n namespace: config.userProfile.namespace,\n };\n return;\n }\n\n const totalNamespaceCount = tailorDBServices.length + externalTailorDBNamespaces.length;\n let userProfileNamespace: string | undefined;\n\n // 2. Single TailorDB\n if (totalNamespaceCount === 1) {\n userProfileNamespace =\n tailorDBServices[0]?.namespace ??\n assertDefined(externalTailorDBNamespaces[0], \"external TailorDB namespace missing\");\n } else {\n // 3. Multiple TailorDBs\n await Promise.all(tailorDBServices.map((tailordb) => tailordb.loadTypes()));\n\n const userProfileTypeName =\n typeof config.userProfile.type === \"object\" && \"name\" in config.userProfile.type\n ? config.userProfile.type.name\n : undefined;\n\n if (userProfileTypeName) {\n for (const service of tailorDBServices) {\n const types = service.types;\n if (Object.prototype.hasOwnProperty.call(types, userProfileTypeName)) {\n userProfileNamespace = service.namespace;\n break;\n }\n }\n }\n\n if (!userProfileNamespace) {\n throw new Error(\n `userProfile type \"${config.userProfile.type.name}\" not found in any TailorDB namespace`,\n );\n }\n }\n\n userProfile = {\n ...config.userProfile,\n namespace: userProfileNamespace,\n };\n },\n };\n}\n","import * as os from \"node:os\";\nimport pLimit from \"p-limit\";\nimport { parsePositiveInt } from \"./parse-positive-int\";\n\n/**\n * Resolve the maximum number of bundle operations to run in parallel.\n *\n * Resolution order:\n * 1. `TAILOR_BUNDLE_CONCURRENCY` env var (positive integer)\n * 2. `os.cpus().length`, clamped to at least 1\n *\n * Each `rolldown.build` invocation drives its own module graph and Rust thread\n * pool, so unbounded parallelism can exhaust native memory on constrained\n * runners (e.g. ubuntu-latest GitHub Actions runners with hundreds of\n * resolvers). Capping at CPU count keeps the worst case predictable.\n * @returns Concurrency cap (always >= 1)\n */\nexport function resolveBundleConcurrency(): number {\n return parsePositiveInt(process.env.TAILOR_BUNDLE_CONCURRENCY) ?? Math.max(1, os.cpus().length);\n}\n\n/**\n * Run an async worker over each item with the bundle-concurrency cap applied.\n * Results are returned in the same order as the input items.\n *\n * On the first rejection no further queued work starts, but already-running\n * workers are awaited before that first rejection is rethrown, so a failing\n * bundle cannot leave sibling builds writing output after the caller\n * has moved on.\n * @param items - Items to process\n * @param worker - Async worker function\n * @returns Worker results in input order\n */\nexport async function withBundleConcurrency<T, R>(\n items: T[],\n worker: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = [];\n results.length = items.length;\n const limit = pLimit(resolveBundleConcurrency());\n let rejection: { reason: unknown } | undefined;\n\n await Promise.all(\n // flatMap skips sparse slots and, unlike map, emits no slot for them either.\n items.flatMap((item, index) => [\n limit(async () => {\n if (rejection) return;\n try {\n results[index] = await worker(item);\n } catch (reason) {\n rejection ??= { reason };\n }\n }),\n ]),\n );\n\n if (rejection) {\n throw rejection.reason;\n }\n return results;\n}\n","import { findUndefinedReferences } from \"#/cli/shared/free-variables\";\nimport { getForbiddenGlobalMessage, isForbiddenGlobal } from \"#/utils/node-builtins\";\nimport { CLIError } from \"./errors\";\n\n/**\n * Throw a CLIError when bundled code still references a Node-only global\n * (`process`, `Buffer`, etc.) that the Tailor Platform runtime never defines.\n * Run this against already-bundled output, not source text — bundling\n * resolves every reachable import first, so any free variable left over is\n * either a genuine runtime global or unreachable dead code the bundler failed\n * to resolve (which `bundleLog.assertAllResolved()` already catches).\n * @param code - Bundled JavaScript to scan.\n * @param context - Human-readable description of what produced `code`, used in the error message.\n */\nexport function assertNoForbiddenRuntimeGlobals(code: string, context: string): void {\n const freeVars = findUndefinedReferences(code);\n const forbidden = [...freeVars].filter(isForbiddenGlobal).toSorted();\n if (forbidden.length === 0) return;\n\n const noun = forbidden.length === 1 ? \"a global\" : \"globals\";\n throw CLIError({\n code: \"FORBIDDEN_RUNTIME_GLOBAL\",\n message: `${context} references ${noun} unavailable in the Tailor Platform runtime: ${forbidden.join(\", \")}.`,\n details: forbidden.map(getForbiddenGlobalMessage).join(\"\\n\"),\n });\n}\n","/**\n * JS expressions that shape the inputs passed to user-authored code.\n *\n * Two delivery paths:\n * - Apply config: shipped with apply and evaluated by the platform before\n * invoking user code.\n * - Bundle inline: interpolated into the generated entry module and\n * evaluated inside the bundled script at function entry.\n *\n * The principal field mapping (server → SDK) shared across services is built by\n * `makePrincipalExpr` from `@/parser/service/tailordb`; `tailorPrincipalMap`\n * (the `caller` mapping) is one of its outputs. `INVOKER_EXPR` and\n * `ACTOR_TRANSFORM_EXPR` below come from the same factory so the three stay in\n * sync.\n */\nimport { makePrincipalExpr, tailorPrincipalMap } from \"#/parser/service/tailordb/index\";\nimport type { Trigger } from \"#/types/executor.generated\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\n// ---------------------------------------------------------------------------\n// Bundle inline\n// ---------------------------------------------------------------------------\n\n/**\n * `invoker` value expression, inlined into bundler entry wrappers.\n *\n * Calls `tailor.context.getInvoker()` at function entry and maps the server\n * shape to `TailorPrincipal | null`. The payload is already in SDK type shape,\n * so no `USER_TYPE_*` normalization is needed; anonymous callers (`null`) pass\n * through as `null`.\n */\nexport const INVOKER_EXPR = makePrincipalExpr({\n source: \"tailor.context.getInvoker()\",\n normalize: false,\n fields: {\n type: { raw: \"$raw.type\" },\n id: \"$raw.id\",\n workspaceId: \"$raw.workspaceId\",\n attributes: \"$raw.attributeMap\",\n attributeList: \"$raw.attributes\",\n },\n});\n\n// ---------------------------------------------------------------------------\n// Executor\n// ---------------------------------------------------------------------------\n\n/**\n * Actor field transformation expression.\n *\n * Transforms the server's actor object to match `TailorPrincipal | null`.\n */\nconst ACTOR_TRANSFORM_EXPR = `actor: ${makePrincipalExpr({\n source: \"args.actor\",\n normalize: true,\n requireId: true,\n fields: {\n type: { raw: \"$raw?.userType\", fallback: \"$raw?.type\" },\n id: \"$raw?.userId ?? $raw?.id\",\n workspaceId: \"$raw.workspaceId\",\n attributes: \"$raw.attributeMap ?? {}\",\n attributeList: \"$raw.attributes ?? []\",\n },\n})}`;\n\n/**\n * Build the JavaScript expression that transforms server-format executor event\n * args into SDK-format args at runtime.\n *\n * The Tailor Platform server delivers event args with server-side field names.\n * The SDK exposes different field names to user code. This function produces a\n * JavaScript expression string that performs the mapping when evaluated\n * server-side.\n * @param triggerKind - The trigger kind discriminant from the parsed executor\n * @param env - Application env record to embed in the expression\n * @returns A JavaScript expression string, e.g. `({ ...args, ... })`\n */\nexport function buildExecutorArgsExpr(\n triggerKind: Trigger[\"kind\"],\n env: Record<string, string | number | boolean>,\n): string {\n const envExpr = `env: ${JSON.stringify(env)}`;\n\n switch (triggerKind) {\n case \"schedule\":\n return `({ ...args, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, ${envExpr} })`;\n\n case \"resolverExecuted\":\n return `({ ...args, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, success: !!args.succeeded, result: args.succeeded?.result.resolver, error: args.failed?.error, ${envExpr} })`;\n\n case \"incomingWebhook\":\n return `({ ...args, appNamespace: args.namespaceName, rawBody: args.raw_body, ${envExpr} })`;\n\n // Workflow events carry no namespace, and a single trigger can mix events\n // that report an outcome with events that do not, so `success` is derived\n // only when the delivered event actually has a result.\n case \"workflowExecution\":\n case \"workflowJobExecution\":\n return `({ ...args, event: args.eventType?.split(\".\").pop(), rawEvent: args.eventType, ${ACTOR_TRANSFORM_EXPR}, ...(args.succeeded ? { success: true } : args.failed ? { success: false, error: args.failed.error ?? \"\" } : {}), ${envExpr} })`;\n\n default:\n // All event triggers: inject event (short name) and rawEvent (full event type) from server-side eventType\n return `({ ...args, event: args.eventType?.split(\".\").pop(), rawEvent: args.eventType, appNamespace: args.namespaceName, ${ACTOR_TRANSFORM_EXPR}, ${envExpr} })`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Resolver\n// ---------------------------------------------------------------------------\n\n/**\n * Build the operationHook expression for resolver pipelines.\n *\n * Transforms server context to SDK resolver context:\n * context.args → input\n * context.pipeline → spread into result\n * user (global var) → caller (`TailorPrincipal | null`)\n * env → injected as JSON\n * @param env - Application env record to embed in the expression\n * @returns A JavaScript expression string for the operationHook\n */\nexport function buildResolverOperationHookExpr(\n env: Record<string, string | number | boolean>,\n): string {\n return `({ ...context.pipeline, input: context.args, caller: ${tailorPrincipalMap}, env: ${JSON.stringify(env)} });`;\n}\n\ntype ResolverPermissionPolicies = Extract<NonNullable<Resolver[\"permission\"]>, readonly unknown[]>;\ntype ResolverPermissionPolicy = ResolverPermissionPolicies[number];\ntype ResolverPermissionOperand = string | boolean | { user: string };\ntype ResolverPermissionCondition = readonly [\n ResolverPermissionOperand,\n \"=\" | \"!=\",\n ResolverPermissionOperand,\n];\n\nfunction isSingleResolverCondition(\n conditions: ResolverPermissionPolicy[\"conditions\"],\n): conditions is ResolverPermissionCondition {\n return conditions.length === 3 && typeof conditions[1] === \"string\";\n}\n\nfunction resolverPermissionOperandExpr(operand: ResolverPermissionOperand): string {\n if (typeof operand === \"object\") {\n if (operand.user === \"_loggedIn\") {\n return `(context.caller !== null)`;\n }\n if (operand.user === \"id\") {\n return `context.caller?.id`;\n }\n return `context.caller?.attributes?.[${JSON.stringify(operand.user)}]`;\n }\n return JSON.stringify(operand);\n}\n\n// `_loggedIn` always evaluates to a defined boolean, but `id` and arbitrary\n// attribute lookups go through `context.caller?.` and can be `undefined` --\n// the caller is `null` for anonymous requests, and an attribute key may not\n// be set.\nfunction isArbitraryAttributeOperand(operand: ResolverPermissionOperand): boolean {\n return typeof operand === \"object\" && operand.user !== \"_loggedIn\";\n}\n\nfunction resolverPermissionConditionExpr(condition: ResolverPermissionCondition): string {\n const [left, operator, right] = condition;\n const leftExpr = resolverPermissionOperandExpr(left);\n const rightExpr = resolverPermissionOperandExpr(right);\n\n if (operator === \"!=\") {\n // A missing attribute must not satisfy `!=` -- otherwise an\n // attribute-less caller would unintentionally match a policy meant to\n // exclude only a specific value (`{ user: \"role\" } != \"BANNED\"` should\n // not let a caller with no `role` attribute at all through).\n const userOperandExpr = isArbitraryAttributeOperand(left)\n ? leftExpr\n : isArbitraryAttributeOperand(right)\n ? rightExpr\n : undefined;\n if (userOperandExpr) {\n return `(${userOperandExpr} !== undefined && ${leftExpr} !== ${rightExpr})`;\n }\n }\n\n const jsOperator = operator === \"=\" ? \"===\" : \"!==\";\n return `(${leftExpr} ${jsOperator} ${rightExpr})`;\n}\n\nfunction resolverPermissionPolicyExpr(policy: ResolverPermissionPolicy): string {\n const conditions = isSingleResolverCondition(policy.conditions)\n ? [policy.conditions]\n : policy.conditions;\n if (conditions.length === 0) {\n throw new Error(\n \"Resolver permission policy must have at least one condition, got an empty array.\",\n );\n }\n return conditions.map(resolverPermissionConditionExpr).join(\" && \");\n}\n\n/**\n * Build a JS object literal capturing whether `policy` matched and its\n * (possibly empty) description, for runtime denial-reason attribution.\n * @param policy - The policy to compile\n * @returns A JS object literal expression: `{ matched, description }`\n */\nfunction policyEntryExpr(policy: ResolverPermissionPolicy): string {\n return `{ matched: ${resolverPermissionPolicyExpr(policy)}, description: ${JSON.stringify(policy.description ?? \"\")} }`;\n}\n\n/**\n * Build the permission guard statement injected at resolver entry.\n *\n * Rejects the call with `TailorErrors` — the only error class the platform\n * turns back into a message the caller can read — when the caller doesn't match\n * `permission`, evaluated against `context.caller` — the original caller,\n * unaffected by `authInvoker`. `permission` is deny-by-default: a caller is\n * granted only by a matching `permit: true` policy, and a matching\n * `permit: false` policy always overrides that grant. The thrown message only\n * includes the description(s) of the policy/policies that actually caused the\n * denial.\n *\n * The schema requires at least one `permit: true` policy (an array of only\n * `permit: false` policies is rejected at build time), so `allowPolicies` is\n * never empty here for schema-valid input; this function still handles that\n * case defensively since it also runs against test-authored raw shapes.\n * @param permission - The resolver's `permission` config\n * @returns A JS statement, or `undefined` when `permission` is omitted or `\"allowAnonymous\"`\n */\nexport function buildResolverPermissionGuardExpr(\n permission: Resolver[\"permission\"],\n): string | undefined {\n if (!permission || permission === \"allowAnonymous\") {\n return undefined;\n }\n if (permission.length === 0) {\n throw new Error(\"Resolver permission must have at least one policy, got an empty array.\");\n }\n const denyPolicies = permission.filter((policy) => policy.permit === false);\n const allowPolicies = permission.filter((policy) => policy.permit !== false);\n\n const denyEntriesExpr = `[${denyPolicies.map(policyEntryExpr).join(\", \")}]`;\n const allowEntriesExpr = `[${allowPolicies.map(policyEntryExpr).join(\", \")}]`;\n\n return `{\n const $denyPolicies = ${denyEntriesExpr};\n const $allowPolicies = ${allowEntriesExpr};\n const $matchedDeny = $denyPolicies.filter((p) => p.matched);\n const $anyAllowMatched = $allowPolicies.some((p) => p.matched);\n if ($matchedDeny.length > 0 || ($allowPolicies.length > 0 && !$anyAllowMatched)) {\n const $reasons = ($matchedDeny.length > 0 ? $matchedDeny : $allowPolicies)\n .map((p) => p.description)\n .filter(Boolean);\n const $message = $reasons.length > 0 ? \"access denied: \" + $reasons.join(\"; \") : \"access denied\";\n throw new TailorErrors([{ message: $message, path: [] }]);\n }\n }`;\n}\n\n/**\n * A resolver's permission config together with the default declared by its\n * namespace. The resolver's own `permission` replaces the namespace default\n * instead of merging with it, so a resolver opts out of a namespace-wide\n * requirement with `permission: \"allowAnonymous\"`.\n */\nexport type ResolverPermissionResolution = {\n permission: Resolver[\"permission\"];\n defaultPermission?: Resolver[\"permission\"];\n};\n\n/**\n * Build the permission guard and input-validation statements shared by every\n * resolver entry wrapper (production bundling and `function run`).\n *\n * Kept as a single generator so a resolver-wrapping behavior (like the\n * permission guard) can't be added to one entry-point template and forgotten\n * in the other — the namespace-default precedence below is resolved here for\n * the same reason. References `context.caller`, `context.input`, `invoker`,\n * and `_internalResolver` — the caller's wrapper must bind a `context` object\n * with `user`/`input` properties and an `invoker` binding (from\n * `INVOKER_EXPR`) before inlining this expression.\n * @param params - The resolver's and its namespace's permission config\n * @returns A JS statement block to inline before calling `_internalResolver.body(...)`\n */\nexport function buildResolverPermissionAndInputCheckExpr(\n params: ResolverPermissionResolution,\n): string {\n const { permission, defaultPermission } = params;\n const permissionGuardExpr = buildResolverPermissionGuardExpr(permission ?? defaultPermission);\n return `\n ${permissionGuardExpr ?? \"\"}\n if (_internalResolver.input) {\n const result = t.object(_internalResolver.input).parse({\n value: context.input,\n data: context.input,\n invoker,\n });\n\n if (result.issues) {\n throw new TailorErrors(result.issues.map(issue => ({\n message: issue.message,\n path: issue.path ?? [],\n })));\n }\n }\n `;\n}\n","import * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { loadFilesWithIgnores, type FileLoadConfig } from \"#/cli/services/file-loader\";\nimport { createStartTransformPlugin } from \"#/cli/services/workflow/start-transformer\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { assertNoForbiddenRuntimeGlobals } from \"#/cli/shared/forbidden-runtime-globals\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { INVOKER_EXPR } from \"#/cli/shared/runtime-exprs\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport { loadExecutor } from \"./loader\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\ninterface ExecutorInfo {\n name: string;\n sourceFile: string;\n}\n\n/**\n * Options for bundling executors\n */\nexport interface BundleExecutorsOptions {\n /** Executor file loading configuration */\n config: FileLoadConfig;\n /** Start context for workflow/job transformations */\n startContext?: StartContext;\n /** Additional files to bundle (e.g., plugin-generated executors) */\n additionalFiles?: string[];\n /** Optional bundle cache for skipping unchanged builds */\n cache?: BundleCache;\n /** Whether to enable inline sourcemaps */\n inlineSourcemap?: boolean;\n /** Controls which console calls are kept in bundled code */\n bundleLogLevel?: LogLevel;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n /** Optional tsconfig lookup cache shared across bundles in this CLI run */\n tsconfigCache?: TsconfigLookupCache;\n}\n\n/**\n * Bundle executors from the specified configuration\n *\n * This function:\n * 1. Creates an in-memory entry module that extracts operation.body\n * 2. Bundles in a single step with tree-shaking\n * @param options - Bundle executor options\n * @returns Map of executor name to bundled code\n */\nexport async function bundleExecutors(\n options: BundleExecutorsOptions,\n): Promise<Map<string, string>> {\n const bundledCode = new Map<string, string>();\n const {\n config,\n startContext,\n additionalFiles = [],\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n baseDir,\n tsconfigCache,\n } = options;\n const configFiles = loadFilesWithIgnores(config, baseDir);\n const files = [...configFiles, ...additionalFiles];\n if (files.length === 0) {\n logger.warn(`No executor files found for patterns: ${config.files.join(\", \")}`);\n return bundledCode;\n }\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(files.length.toString())} files for ${styles.info('\"executor\"')}`,\n );\n\n // Load all executors and filter to function/jobFunction only\n const executors: ExecutorInfo[] = [];\n for (const file of files) {\n const executor = await loadExecutor(file);\n if (!executor) {\n logger.debug(` Skipping: ${file} (could not be loaded)`);\n continue;\n }\n\n // Only bundle function and jobFunction executors\n if (![\"function\", \"jobFunction\"].includes(executor.operation.kind)) {\n logger.debug(` Skipping: ${executor.name} (not a function executor)`);\n continue;\n }\n\n executors.push({\n name: executor.name,\n sourceFile: file,\n });\n }\n\n if (executors.length === 0) {\n logger.debug(\" No function executors to bundle\");\n return bundledCode;\n }\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // Process each executor, capped by TAILOR_BUNDLE_CONCURRENCY to bound native\n // memory use (each rolldown.build allocates its own module graph).\n const results = await withBundleConcurrency(executors, (executor) =>\n bundleSingleExecutor(\n executor,\n tsconfig,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n ),\n );\n\n for (const [name, code] of results) {\n bundledCode.set(name, code);\n }\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info('\"executor\"')}`);\n\n return bundledCode;\n}\n\nasync function bundleSingleExecutor(\n executor: ExecutorInfo,\n tsconfig: string | undefined,\n startContext?: StartContext,\n cache?: BundleCache,\n inlineSourcemap?: boolean,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<[string, string]> {\n const serializedStartContext = serializeStartContext(startContext);\n\n const contextHash = computeBundlerContextHash({\n sourceFile: executor.sourceFile,\n extraContext: serializedStartContext,\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n });\n\n const code = await withCache({\n cache,\n kind: \"executor\",\n name: executor.name,\n sourceFile: executor.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(executor.sourceFile);\n\n const entryContent = ml /* js */ `\n import _internalExecutor from \"${absoluteSourcePath}\";\n\n const __executor_function = async (args) => {\n const invoker = ${INVOKER_EXPR};\n return _internalExecutor.operation.body({ ...args, invoker });\n };\n\n export { __executor_function as main };\n `;\n const entry = createVirtualEntry(\n `executor:${executor.name}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n const startPlugin = createStartTransformPlugin(startContext);\n const plugins: rolldown.Plugin[] = [entry.plugin];\n if (startPlugin) {\n plugins.push(startPlugin);\n }\n plugins.push(\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n assertNoForbiddenRuntimeGlobals(bundledCode, `Executor \"${executor.name}\"`);\n return bundledCode;\n },\n });\n\n return [executor.name, code];\n}\n","import type { HttpAdapterConfigInput } from \"#/types/http-adapter.generated\";\n\n/**\n * Maps the lowercase `input` handler keys to the HTTP methods they serve.\n * The key set is tied to `inputHandlersSchema` in `./schema` via the\n * zinfer-generated config type, so the two cannot drift apart.\n */\nexport const HTTP_METHODS = {\n get: \"GET\",\n post: \"POST\",\n put: \"PUT\",\n patch: \"PATCH\",\n delete: \"DELETE\",\n} as const satisfies Record<keyof Required<HttpAdapterConfigInput[\"input\"]>, string>;\n\nexport type HttpMethodKey = keyof typeof HTTP_METHODS;\n\nexport const HTTP_METHOD_KEYS = Object.keys(HTTP_METHODS) as readonly HttpMethodKey[];\n","import { z } from \"zod\";\nimport { functionSchema } from \"../common\";\n\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;\n\nconst inputHandlersSchema = z\n .strictObject({\n get: functionSchema.optional().describe(\"Handler for GET requests\"),\n post: functionSchema.optional().describe(\"Handler for POST requests\"),\n put: functionSchema.optional().describe(\"Handler for PUT requests\"),\n patch: functionSchema.optional().describe(\"Handler for PATCH requests\"),\n delete: functionSchema.optional().describe(\"Handler for DELETE requests\"),\n })\n\n .refine(\n // optional fields become undefined after zod parses them\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n (val) => Object.values(val).some((v) => v !== undefined),\n \"input must declare at least one HTTP method handler\",\n )\n .describe(\"Per-method functions that transform HTTP requests to GraphQL requests\");\n\nexport const HttpAdapterConfigSchema = z.strictObject({\n name: z\n .string()\n .regex(\n NAME_PATTERN,\n \"name must be 3-63 chars, lowercase alphanumeric with hyphens, not starting or ending with a hyphen\",\n )\n .describe(\"Unique adapter name within the domain\"),\n pathPattern: z\n .string()\n .min(1)\n .describe(\"Path pattern with segment wildcards (trailing or single-segment)\"),\n enabled: z.boolean().default(true).describe(\"Whether the adapter is active\"),\n priority: z\n .number()\n .int()\n .min(0)\n .default(0)\n .describe(\"Matching priority; the lowest value wins when multiple adapters match\"),\n input: inputHandlersSchema,\n output: functionSchema\n .optional()\n .describe(\"Function that transforms GraphQL response to HTTP response\"),\n});\n","import { createRequire } from \"node:module\";\nimport { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport { HTTP_METHODS, type HttpMethodKey } from \"#/parser/service/http-adapter/index\";\nimport { getNodeBuiltinMessage, isNodeBuiltinImport } from \"#/utils/node-builtins\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\nconst ADAPTER_BUNDLE_WARN_BYTES = 64 * 1024;\nconst ADAPTER_BUNDLE_ERROR_BYTES = 256 * 1024;\nconst nodeRequire = createRequire(import.meta.url);\nconst GRAPHQL_WEB_MODULE = nodeRequire.resolve(\"@0no-co/graphql.web\");\n\nexport interface HttpAdapterBundleInput {\n name: string;\n sourceFile: string;\n methods: HttpMethodKey[];\n hasOutput: boolean;\n}\n\nexport interface HttpAdapterBundleResult {\n /** Adapter name → bundled input JS string. */\n bundledInputs: Map<string, string>;\n /** Adapter name → bundled output JS string. Only populated when the adapter has an output. */\n bundledOutputs: Map<string, string>;\n}\n\n/**\n * Bundle each adapter's `input` (and `output`, if present) into a standalone\n * IIFE defining a global `transform(input)` entry point. `input` gets a\n * generated dispatcher that routes by `req.method`; `output` is used as is.\n * @param adapters - Detected adapters to bundle\n * @param baseDir - Directory the owning config's tsconfig is resolved against\n * @param cache - Optional bundle cache for skipping unchanged builds\n * @param bundleLogLevel - Controls which console calls are kept in bundled code\n * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run\n * @returns Bundled scripts keyed by adapter name\n */\nexport async function bundleHttpAdapters(\n adapters: HttpAdapterBundleInput[],\n baseDir: string,\n cache?: BundleCache,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<HttpAdapterBundleResult> {\n if (adapters.length === 0) {\n return { bundledInputs: new Map(), bundledOutputs: new Map() };\n }\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(adapters.length.toString())} files for ${styles.info('\"http-adapter\"')}`,\n );\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // rolldown.build() is memory-intensive; cap parallelism like the other SDK bundlers.\n const tasks = adapters.flatMap((adapter) => {\n const kinds: Array<\"input\" | \"output\"> = adapter.hasOutput ? [\"input\", \"output\"] : [\"input\"];\n return kinds.map((kind) => ({ adapter, kind }));\n });\n const results = await withBundleConcurrency(tasks, ({ adapter, kind }) =>\n bundleAdapterScript(adapter, kind, tsconfig, cache, bundleLogLevel, tsconfigCache),\n );\n\n const bundledInputs = new Map<string, string>();\n const bundledOutputs = new Map<string, string>();\n for (const [name, kind, code] of results) {\n if (kind === \"input\") {\n bundledInputs.set(name, code);\n } else {\n bundledOutputs.set(name, code);\n }\n }\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info('\"http-adapter\"')}`);\n\n return { bundledInputs, bundledOutputs };\n}\n\nasync function bundleAdapterScript(\n adapter: HttpAdapterBundleInput,\n kind: \"input\" | \"output\",\n tsconfig: string | undefined,\n cache: BundleCache | undefined,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<[string, \"input\" | \"output\", string]> {\n const contextHash = computeBundlerContextHash({\n sourceFile: adapter.sourceFile,\n extraContext: kind === \"input\" ? adapter.methods.join(\",\") : \"\",\n tsconfig,\n inlineSourcemap: false,\n bundleLogLevel,\n prefix: `${kind}:document-query-normalize-v1`,\n });\n\n const code = await withCache({\n cache,\n kind: kind === \"input\" ? \"http-adapter-input\" : \"http-adapter-output\",\n name: adapter.name,\n sourceFile: adapter.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(adapter.sourceFile);\n const entryContent =\n kind === \"input\"\n ? buildInputEntry(absoluteSourcePath, adapter.methods, GRAPHQL_WEB_MODULE)\n : buildOutputEntry(absoluteSourcePath);\n const entry = createVirtualEntry(\n `http-adapter:${adapter.name}:${kind}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n const rejectNodeImports: rolldown.Plugin = {\n name: \"http-adapter-reject-node-imports\",\n resolveId(source) {\n if (isNodeBuiltinImport(source)) {\n throw new Error(`HTTP adapter \"${adapter.name}\": ${getNodeBuiltinMessage(source)}`);\n }\n return null;\n },\n };\n\n // Stub out `@tailor-platform/sdk` imports: only the brand matters at\n // build time, and the IIFE must not depend on external globals.\n const stubSdkImports: rolldown.Plugin = {\n name: \"http-adapter-stub-sdk\",\n resolveId(source) {\n if (source === \"@tailor-platform/sdk\" || source.startsWith(\"@tailor-platform/sdk/\")) {\n return { id: \"\\0http-adapter-sdk-stub\", moduleSideEffects: false };\n }\n return null;\n },\n load(id) {\n if (id === \"\\0http-adapter-sdk-stub\") {\n return \"export const createHttpAdapter = (cfg) => cfg;\\nexport default { createHttpAdapter };\\n\";\n }\n return null;\n },\n };\n\n const plugins: rolldown.Plugin[] = [\n entry.plugin,\n rejectNodeImports,\n stubSdkImports,\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n ...cachePlugins,\n ];\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"iife\",\n sourcemap: false,\n minify: true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n // es2017 on purpose: async/await must survive downleveling so\n // rejectAsyncInBundle can reject it (lower targets rewrite it into\n // generator+Promise code that evades the check and breaks on Sobek).\n transform: { target: \"es2017\" },\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n const bundled = result.output[0].code;\n\n const byteLength = Buffer.byteLength(bundled, \"utf8\");\n if (byteLength > ADAPTER_BUNDLE_ERROR_BYTES) {\n throw new Error(\n `HTTP adapter \"${adapter.name}\" ${kind} script is ${byteLength} bytes, exceeding the ${ADAPTER_BUNDLE_ERROR_BYTES} byte limit`,\n );\n }\n if (byteLength > ADAPTER_BUNDLE_WARN_BYTES) {\n logger.warn(\n `HTTP adapter \"${adapter.name}\" ${kind} script is ${byteLength} bytes, larger than the recommended ${ADAPTER_BUNDLE_WARN_BYTES} byte limit`,\n );\n }\n\n // Load-time checks only see the handler functions; imported helpers can\n // still introduce async/await, so verify the whole bundle is synchronous.\n rejectAsyncInBundle(bundled, adapter.name, kind);\n\n return bundled;\n },\n });\n\n return [adapter.name, kind, code];\n}\n\nfunction buildInputEntry(\n absoluteSourcePath: string,\n methods: HttpMethodKey[],\n graphqlPrinterModule: string,\n): string {\n const cases = methods\n .map((method) => {\n const result = `__adapter.input.${method}(req)`;\n const expression = `__normalizeHttpAdapterGraphQLRequest(${result})`;\n return ` case \"${HTTP_METHODS[method]}\": return ${expression};`;\n })\n .join(\"\\n\");\n const supported = methods.map((m) => HTTP_METHODS[m]).join(\", \");\n const documentNormalizer = `import { print as __printHttpAdapterDocument } from ${JSON.stringify(graphqlPrinterModule)};\nfunction __normalizeHttpAdapterGraphQLRequest(result) {\n if (!result || typeof result.query === \"string\") {\n return result;\n }\n return { ...result, query: __printHttpAdapterDocument(result.query) };\n}\n`;\n return `${documentNormalizer}import __adapter from ${JSON.stringify(absoluteSourcePath)};\nglobalThis.transform = function(req) {\n switch (req.method) {\n${cases}\n default: throw new Error(\"HTTP adapter received unsupported method: \" + req.method + \" (supported: ${supported})\");\n }\n};\n`;\n}\n\nfunction buildOutputEntry(absoluteSourcePath: string): string {\n return `import __adapter from ${JSON.stringify(absoluteSourcePath)};\nglobalThis.transform = __adapter.output;\n`;\n}\n\nfunction rejectAsyncInBundle(code: string, adapterName: string, kind: \"input\" | \"output\"): void {\n // Use a fake filename so oxc treats this as a module. The bundle is already\n // minified IIFE; oxc parses it without complaint.\n const { program } = parseSync(`${adapterName}.${kind}.bundle.js`, code);\n\n let asyncFound = false;\n const stack: unknown[] = [program];\n while (stack.length > 0) {\n const node = stack.pop();\n if (!node || typeof node !== \"object\") continue;\n const n = node as Record<string, unknown>;\n const type = typeof n.type === \"string\" ? n.type : \"\";\n if (type === \"AwaitExpression\") {\n asyncFound = true;\n break;\n }\n if (\n (type === \"FunctionDeclaration\" ||\n type === \"FunctionExpression\" ||\n type === \"ArrowFunctionExpression\") &&\n n.async === true\n ) {\n asyncFound = true;\n break;\n }\n if ((type === \"ForOfStatement\" || type === \"ForStatement\") && n.await === true) {\n asyncFound = true;\n break;\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) stack.push(c);\n } else if (child && typeof child === \"object\") {\n stack.push(child);\n }\n }\n }\n\n if (asyncFound) {\n throw new Error(\n `HTTP adapter \"${adapterName}\" ${kind} bundle contains async/await, which is unavailable in the gateway runtime. ` +\n `Check imported helper modules — even if your handler is synchronous, an async helper will fail at runtime.`,\n );\n }\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { type HttpAdapterServiceInput } from \"#/configure/config/types\";\nimport {\n HTTP_METHOD_KEYS,\n HttpAdapterConfigSchema,\n type HttpMethodKey,\n} from \"#/parser/service/http-adapter/index\";\nimport { type HttpAdapterConfig } from \"#/types/http-adapter.generated\";\nimport { isSdkBranded } from \"#/utils/brand\";\n\ntype HttpAdapterServiceConfig = HttpAdapterServiceInput;\n\ntype LoadedHttpAdapter = {\n adapter: HttpAdapterConfig;\n sourceFile: string;\n methods: HttpMethodKey[];\n hasOutput: boolean;\n};\n\nexport type HttpAdapterService = {\n readonly config: HttpAdapterServiceConfig;\n readonly adapters: ReadonlyArray<LoadedHttpAdapter>;\n readonly fileCount: number;\n loadAdapters: () => Promise<void>;\n printLoadedAdapters: () => void;\n};\n\nexport interface CreateHttpAdapterServiceParams {\n config: HttpAdapterServiceConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\nexport function createHttpAdapterService(\n params: CreateHttpAdapterServiceParams,\n): HttpAdapterService {\n const { config, baseDir } = params;\n let adapters: LoadedHttpAdapter[] = [];\n let fileCount = 0;\n let loaded = false;\n\n return {\n config,\n get adapters() {\n return adapters;\n },\n get fileCount() {\n return fileCount;\n },\n loadAdapters: async () => {\n if (loaded) return;\n const result = await loadAdapterFiles(config, baseDir);\n adapters = result.adapters;\n fileCount = result.fileCount;\n loaded = true;\n },\n printLoadedAdapters: () => {\n if (adapters.length === 0) return;\n logger.newline();\n logger.log(`Found ${styles.highlight(adapters.length.toString())} HTTP adapters`);\n for (const { adapter, sourceFile } of adapters) {\n const relativePath = path.relative(process.cwd(), sourceFile);\n logger.log(\n `HTTP adapter: ${styles.successBright(\n `\"${adapter.name}\"`,\n )} loaded from ${styles.path(relativePath)}`,\n );\n }\n },\n };\n}\n\nasync function loadAdapterFiles(\n config: HttpAdapterServiceConfig,\n baseDir: string,\n): Promise<{ adapters: LoadedHttpAdapter[]; fileCount: number }> {\n if (config.files.length === 0) {\n return { adapters: [], fileCount: 0 };\n }\n\n const files = loadFilesWithIgnores(config, baseDir);\n\n // Import every matched file and keep the ones whose default export is a\n // createHttpAdapter() result, mirroring the resolver/executor loaders.\n // Matched files without one (e.g. shared helpers) are skipped.\n const loadResults = await Promise.all(files.map(loadAdapterFromFile));\n\n const adapters: LoadedHttpAdapter[] = [];\n const seenNames = new Map<string, string>();\n for (const result of loadResults) {\n if (!result) continue;\n const existing = seenNames.get(result.adapter.name);\n if (existing) {\n throw new Error(\n `Duplicate HTTP adapter name \"${result.adapter.name}\" found:\\n` +\n ` - ${existing}\\n` +\n ` - ${result.sourceFile}\\n` +\n `Each HTTP adapter must have a unique name.`,\n );\n }\n seenNames.set(result.adapter.name, result.sourceFile);\n adapters.push(result);\n }\n\n return { adapters, fileCount: files.length };\n}\n\nasync function loadAdapterFromFile(filePath: string): Promise<LoadedHttpAdapter | null> {\n try {\n const module = await importUserModule(filePath);\n // Only a createHttpAdapter() result is a valid default export; a plain\n // object that happens to match the schema is rejected by the brand check.\n if (!isSdkBranded(module.default, \"http-adapter\")) {\n // Not an adapter file (e.g. a shared helper matched by the glob). Guard\n // against an adapter that is only exported under a named export, which\n // would otherwise silently disappear from the deployment.\n const named = Object.entries(module).find(\n ([exportName, value]) => exportName !== \"default\" && isSdkBranded(value, \"http-adapter\"),\n );\n if (named) {\n throw new Error(\n `HTTP adapter must be the default export, but it is exported as \\`${named[0]}\\`. ` +\n \"Re-export it: `export default createHttpAdapter({...})`.\",\n );\n }\n return null;\n }\n\n const parsed = HttpAdapterConfigSchema.safeParse(module.default);\n if (!parsed.success) {\n throw parsed.error;\n }\n\n const adapter = parsed.data;\n const methods = collectMethodKeys(adapter);\n rejectAsyncHandlers(adapter, methods, filePath);\n\n return {\n adapter,\n sourceFile: filePath,\n methods,\n hasOutput: adapter.output !== undefined,\n };\n } catch (error) {\n const relativePath = path.relative(process.cwd(), filePath);\n logger.error(\n `${styles.error(\"Failed to load HTTP adapter from\")} ${styles.errorBright(relativePath)}`,\n );\n logger.error(String(error));\n throw error;\n }\n}\n\nfunction collectMethodKeys(adapter: HttpAdapterConfig): HttpMethodKey[] {\n const input = adapter.input as Partial<Record<HttpMethodKey, unknown>>;\n return HTTP_METHOD_KEYS.filter((key) => typeof input[key] === \"function\");\n}\n\nfunction rejectAsyncHandlers(\n adapter: HttpAdapterConfig,\n methods: HttpMethodKey[],\n sourceFile: string,\n): void {\n const input = adapter.input as Partial<Record<HttpMethodKey, unknown>>;\n for (const method of methods) {\n if (isAsyncFunction(input[method])) {\n throw new Error(\n `HTTP adapter \"${adapter.name}\" in ${sourceFile} has an async \\`input.${method}\\` function. ` +\n `Handlers must be synchronous; async/await is not supported.`,\n );\n }\n }\n if (adapter.output !== undefined && isAsyncFunction(adapter.output)) {\n throw new Error(\n `HTTP adapter \"${adapter.name}\" in ${sourceFile} has an async \\`output\\` function. ` +\n `Handlers must be synchronous; async/await is not supported.`,\n );\n }\n}\n\nfunction isAsyncFunction(fn: unknown): boolean {\n return typeof fn === \"function\" && fn.constructor.name === \"AsyncFunction\";\n}\n","import { z } from \"zod\";\nimport { AuthInvokerSchema } from \"#/parser/service/auth/schema\";\nimport { TailorFieldSchema } from \"#/parser/service/field/schema\";\nimport { functionSchema } from \"../common\";\n\nexport const QueryTypeSchema = z\n .union([z.literal(\"query\"), z.literal(\"mutation\")])\n .describe(\"GraphQL operation type\");\n\nconst ResolverPermissionOperandSchema = z.union([\n z.strictObject({ user: z.string() }),\n z.string(),\n z.boolean(),\n]);\n\nconst ResolverPermissionOperatorSchema = z.union([z.literal(\"=\"), z.literal(\"!=\")]);\n\nconst isUserOperand = (operand: z.infer<typeof ResolverPermissionOperandSchema>) =>\n typeof operand === \"object\";\n\n// Fixed `user` keys have a known value type; arbitrary user attributes don't\n// (their declared type lives in the configure-layer generic, not here), so\n// only these two are checked against the operand they're compared to.\nconst KNOWN_USER_OPERAND_TYPES: Record<string, \"string\" | \"boolean\"> = {\n _loggedIn: \"boolean\",\n id: \"string\",\n};\n\nconst operandTypeMismatch = (\n userOperand: z.infer<typeof ResolverPermissionOperandSchema>,\n otherOperand: z.infer<typeof ResolverPermissionOperandSchema>,\n) => {\n if (typeof userOperand !== \"object\") {\n return undefined;\n }\n const expected = KNOWN_USER_OPERAND_TYPES[userOperand.user];\n if (\n expected === undefined ||\n typeof otherOperand === \"object\" ||\n typeof otherOperand === expected\n ) {\n return undefined;\n }\n return { key: userOperand.user, expected };\n};\n\nconst ResolverPermissionConditionSchema = z\n .tuple([\n ResolverPermissionOperandSchema,\n ResolverPermissionOperatorSchema,\n ResolverPermissionOperandSchema,\n ])\n .refine(\n ([left, , right]) => isUserOperand(left) !== isUserOperand(right),\n \"Resolver permission condition must reference a `user` operand on exactly one side \" +\n \"(comparing two `user` operands to each other can match on `undefined === undefined`)\",\n )\n .superRefine(([left, , right], ctx) => {\n for (const mismatch of [operandTypeMismatch(left, right), operandTypeMismatch(right, left)]) {\n if (mismatch) {\n ctx.addIssue({\n code: \"custom\",\n message: `\\`${mismatch.key}\\` must compare to a ${mismatch.expected}`,\n });\n }\n }\n })\n .readonly();\n\nconst ResolverPermissionPolicySchema = z.strictObject({\n conditions: z.union([\n ResolverPermissionConditionSchema,\n z\n .array(ResolverPermissionConditionSchema)\n .min(1, \"Resolver permission policy must have at least one condition\")\n .readonly(),\n ]),\n permit: z.boolean(),\n description: z\n .string()\n .optional()\n .describe(\"Reason recorded for this policy, used in the access-denied error message\"),\n});\n\nexport const ResolverPermissionSchema = z\n .union([\n z\n .array(ResolverPermissionPolicySchema)\n .min(1, \"Resolver permission must have at least one policy\")\n .refine(\n (policies) => policies.some((policy) => policy.permit === true),\n \"Resolver permission must include at least one `permit: true` policy — a policy array \" +\n \"with only `permit: false` policies still lets any caller through by simply not \" +\n \"authenticating, since none of the deny conditions apply to a caller with no user \" +\n \"attributes at all\",\n )\n .readonly(),\n z.literal(\"allowAnonymous\"),\n ])\n .describe(\n \"Access requirement for this resolver, evaluated against the original caller \" +\n '(unaffected by `invoker`) before `body` runs. \"allowAnonymous\" documents that ' +\n \"anonymous callers are allowed. Omitted (default): unchanged, anonymous callers can \" +\n \"reach the resolver\",\n );\n\nexport const ResolverSchema = z.strictObject({\n operation: QueryTypeSchema.describe(\"GraphQL operation type (query or mutation)\"),\n name: z.string().describe(\"Resolver name\"),\n description: z.string().optional().describe(\"Resolver description\"),\n input: z.record(z.string(), TailorFieldSchema).optional().describe(\"Input field definitions\"),\n body: functionSchema.describe(\"Resolver implementation function\"),\n output: TailorFieldSchema.describe(\"Output field definition\"),\n publishEvents: z.boolean().optional().describe(\"Enable publishing events from this resolver\"),\n invoker: AuthInvokerSchema.optional().describe(\"Machine user to execute this resolver as\"),\n permission: ResolverPermissionSchema.optional(),\n});\n","import { importUserModule } from \"#/cli/shared/user-modules\";\nimport { ResolverSchema } from \"#/parser/service/resolver/index\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\n/**\n * Load and validate a resolver definition from a file.\n * @param resolverFilePath - Path to the resolver file\n * @returns Parsed resolver or null if invalid\n */\nexport async function loadResolver(resolverFilePath: string): Promise<Resolver | null> {\n const resolverModule = await importUserModule(resolverFilePath);\n const resolver = resolverModule.default;\n\n const parseResult = ResolverSchema.safeParse(resolver);\n if (!parseResult.success) {\n return null;\n }\n\n return parseResult.data;\n}\n","import * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { type BundleCache, computeBundlerContextHash, withCache } from \"#/cli/cache/bundle-cache\";\nimport { type FileLoadConfig, loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { createStartTransformPlugin } from \"#/cli/services/workflow/start-transformer\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { assertNoForbiddenRuntimeGlobals } from \"#/cli/shared/forbidden-runtime-globals\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { buildResolverPermissionAndInputCheckExpr, INVOKER_EXPR } from \"#/cli/shared/runtime-exprs\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport { loadResolver } from \"./loader\";\nimport type { LogLevel } from \"#/configure/config/types\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\ninterface ResolverInfo {\n name: string;\n sourceFile: string;\n permission: Resolver[\"permission\"];\n}\n\nexport interface BundleResolversOptions {\n /** Resolver namespace name */\n namespace: string;\n /** Resolver file loading configuration */\n config: FileLoadConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n /** The namespace's `defaultPermission`, applied to resolvers declaring none */\n defaultPermission?: Resolver[\"permission\"];\n /** Start context for workflow/job transformations */\n startContext?: StartContext;\n /** Optional bundle cache for skipping unchanged builds */\n cache?: BundleCache;\n /** Whether to enable inline sourcemaps */\n inlineSourcemap?: boolean;\n /** Controls which console calls are kept in bundled code */\n bundleLogLevel?: LogLevel;\n /** Optional tsconfig lookup cache shared across bundles in this CLI run */\n tsconfigCache?: TsconfigLookupCache;\n}\n\n/**\n * Bundle resolvers for the specified namespace\n *\n * This function:\n * 1. Uses a transform plugin to add validation wrapper during bundling\n * 2. Creates an in-memory entry module\n * 3. Bundles in a single step with tree-shaking\n * @param options - Bundle options\n * @returns Map of resolver name to bundled code\n */\nexport async function bundleResolvers(\n options: BundleResolversOptions,\n): Promise<Map<string, string>> {\n const {\n namespace,\n config,\n baseDir,\n defaultPermission,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n tsconfigCache,\n } = options;\n const bundledCode = new Map<string, string>();\n const files = loadFilesWithIgnores(config, baseDir);\n if (files.length === 0) {\n logger.warn(`No resolver files found for patterns: ${config.files.join(\", \")}`);\n return bundledCode;\n }\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(files.length.toString())} files for ${styles.info(\n `\"${namespace}\"`,\n )}`,\n );\n\n // Load all resolvers to get their names\n const resolvers: ResolverInfo[] = [];\n for (const file of files) {\n const resolver = await loadResolver(file);\n if (!resolver) {\n logger.debug(` Skipping: ${file} (could not be loaded)`);\n continue;\n }\n resolvers.push({\n name: resolver.name,\n sourceFile: file,\n permission: resolver.permission,\n });\n }\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // Process each resolver, capped by TAILOR_BUNDLE_CONCURRENCY to bound native\n // memory use (each rolldown.build allocates its own module graph).\n const results = await withBundleConcurrency(resolvers, (resolver) =>\n bundleSingleResolver({\n namespace,\n resolver,\n tsconfig,\n defaultPermission,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n }),\n );\n\n for (const [name, code] of results) {\n bundledCode.set(name, code);\n }\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info(`\"${namespace}\"`)}`);\n\n return bundledCode;\n}\n\ntype BundleSingleResolverOptions = Omit<BundleResolversOptions, \"config\" | \"baseDir\"> & {\n resolver: ResolverInfo;\n tsconfig: string | undefined;\n};\n\nasync function bundleSingleResolver(\n options: BundleSingleResolverOptions,\n): Promise<[string, string]> {\n const {\n namespace,\n resolver,\n tsconfig,\n defaultPermission,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel = \"DEBUG\",\n tsconfigCache,\n } = options;\n const serializedStartContext = serializeStartContext(startContext);\n\n const contextHash = computeBundlerContextHash({\n sourceFile: resolver.sourceFile,\n // The namespace default is part of the generated guard but lives in the\n // config file, not in any resolver source, so a cached bundle would\n // otherwise survive a change to it. Encoded as a pair rather than joined,\n // so no separator has to be a character neither value can contain.\n extraContext: JSON.stringify([serializedStartContext, defaultPermission ?? null]),\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n });\n\n const code = await withCache({\n cache,\n kind: \"resolver\",\n namespace,\n name: resolver.name,\n sourceFile: resolver.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(resolver.sourceFile);\n const guardAndInputCheckExpr = buildResolverPermissionAndInputCheckExpr({\n permission: resolver.permission,\n defaultPermission,\n });\n\n const entryContent = ml /* js */ `\n import _internalResolver from \"${absoluteSourcePath}\";\n import { t } from \"@tailor-platform/sdk\";\n\n const $tailor_resolver_body = async (context) => {\n const invoker = ${INVOKER_EXPR};\n ${guardAndInputCheckExpr}\n return _internalResolver.body({ ...context, invoker });\n };\n\n export { $tailor_resolver_body as main };\n `;\n const entry = createVirtualEntry(\n `resolver:${resolver.name}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n const startPlugin = createStartTransformPlugin(startContext);\n const plugins: rolldown.Plugin[] = [entry.plugin];\n if (startPlugin) {\n plugins.push(startPlugin);\n }\n plugins.push(\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n );\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n assertNoForbiddenRuntimeGlobals(bundledCode, `Resolver \"${resolver.name}\"`);\n return bundledCode;\n },\n });\n\n return [resolver.name, code];\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { ResolverPermissionSchema } from \"#/parser/service/resolver/index\";\nimport type { ResolverServiceConfig, ResolverServiceInput } from \"#/configure/config/types\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\ntype ParseParams = {\n namespace: string;\n config: ResolverServiceConfig;\n};\n\n/**\n * Validate a resolver namespace's `defaultPermission` with the same schema as\n * a resolver's own `permission`, so an invalid policy fails the build instead\n * of compiling into a guard that lets everyone through.\n * @param params - The namespace name and its resolver service config\n * @returns The validated default, or `undefined` when the namespace declares none\n */\nexport function parseResolverDefaultPermission(\n params: ParseParams,\n): Resolver[\"permission\"] | undefined {\n const { namespace, config } = params;\n if (config.defaultPermission === undefined) {\n return undefined;\n }\n const result = ResolverPermissionSchema.safeParse(config.defaultPermission);\n if (!result.success) {\n throw new Error(\n `Invalid \\`defaultPermission\\` for resolver namespace \"${namespace}\": ` +\n result.error.issues.map((issue) => issue.message).join(\"; \"),\n );\n }\n return result.data;\n}\n\ntype ResolveForFileParams = {\n config: ResolverServiceInput | undefined;\n filePath: string;\n baseDir: string;\n};\n\n/**\n * Find the `defaultPermission` of the resolver namespace a file belongs to.\n *\n * `function run` receives a single file rather than a namespace, so the\n * namespace is recovered by matching the file against each namespace's own\n * patterns — otherwise a test run would skip a guard the deployed resolver has.\n *\n * Nothing stops two namespaces' patterns from claiming the same file, and\n * `deploy` then bundles that resolver once per namespace, each with its own\n * default. Picking one here would make the test run agree with only one of\n * the deployed copies, so an ambiguous file is rejected instead.\n * @param params - The config's resolver section, the resolver file, and the config's own directory\n * @returns The owning namespace's validated default, or `undefined` when no namespace claims the file\n */\nexport function resolveResolverDefaultPermissionForFile(\n params: ResolveForFileParams,\n): Resolver[\"permission\"] | undefined {\n const { config, filePath, baseDir } = params;\n if (!config) {\n return undefined;\n }\n\n // Globbed paths keep the platform's own separators; `path.resolve` here is\n // pathe's, which normalizes both sides to the same form before comparing.\n const targetFile = path.resolve(filePath);\n const owners: Array<{ namespace: string; config: ResolverServiceConfig }> = [];\n for (const [namespace, serviceConfig] of Object.entries(config)) {\n if (\"external\" in serviceConfig) {\n continue;\n }\n const files = loadFilesWithIgnores(serviceConfig, baseDir);\n if (files.some((file) => path.resolve(file) === targetFile)) {\n owners.push({ namespace, config: serviceConfig });\n }\n }\n\n if (owners.length > 1) {\n throw new Error(\n `Resolver ${path.relative(process.cwd(), targetFile)} matches more than one resolver ` +\n `namespace: ${owners.map((owner) => `\"${owner.namespace}\"`).join(\", \")}. ` +\n `Each namespace applies its own \\`defaultPermission\\`, so narrow the \\`files\\`/` +\n `\\`ignores\\` patterns until exactly one namespace claims this file.`,\n );\n }\n\n const [owner] = owners;\n return owner ? parseResolverDefaultPermission(owner) : undefined;\n}\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { ResolverSchema } from \"#/parser/service/resolver/index\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport { parseResolverDefaultPermission } from \"./default-permission\";\nimport type { ResolverServiceConfig } from \"#/configure/config/types\";\nimport type { Resolver } from \"#/types/resolver.generated\";\n\nexport type ResolverService = {\n readonly namespace: string;\n readonly config: ResolverServiceConfig;\n /** The namespace's validated `defaultPermission`, applied to resolvers declaring none. */\n readonly defaultPermission: Resolver[\"permission\"] | undefined;\n readonly resolvers: Record<string, Resolver>;\n loadResolvers: () => Promise<void>;\n};\n\n/**\n * Creates a new ResolverService instance.\n * @param namespace - The namespace for this resolver service\n * @param config - The resolver service configuration\n * @param baseDir - Directory the config's file patterns are resolved against\n * @returns A new ResolverService instance\n */\nexport function createResolverService(\n namespace: string,\n config: ResolverServiceConfig,\n baseDir: string,\n): ResolverService {\n const resolvers: Record<string, Resolver> = {};\n const defaultPermission = parseResolverDefaultPermission({ namespace, config });\n let loaded = false;\n\n const loadResolverForFile = async (resolverFile: string): Promise<Resolver | undefined> => {\n try {\n const resolverModule = await importUserModule(resolverFile);\n const result = ResolverSchema.safeParse(resolverModule.default);\n if (result.success) {\n const relativePath = path.relative(process.cwd(), resolverFile);\n logger.log(\n `Resolver: ${styles.successBright(`\"${result.data.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n resolvers[resolverFile] = result.data;\n return result.data;\n }\n if (isSdkBranded(resolverModule.default, \"resolver\")) {\n throw result.error;\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), resolverFile);\n logger.error(`Failed to load resolver from ${styles.bold(relativePath)}`);\n logger.error(String(error));\n throw error;\n }\n return undefined;\n };\n\n return {\n namespace,\n config,\n defaultPermission,\n get resolvers() {\n return resolvers;\n },\n loadResolvers: async () => {\n if (loaded) {\n return;\n }\n if (config.files.length === 0) {\n return;\n }\n\n const resolverFiles = loadFilesWithIgnores(config, baseDir);\n\n logger.log(\n `Found ${styles.highlight(resolverFiles.length.toString())} resolver files for service ${styles.highlight(`\"${namespace}\"`)}`,\n );\n\n await Promise.all(resolverFiles.map((resolverFile) => loadResolverForFile(resolverFile)));\n assertUniqueResolverNames(resolvers, namespace);\n warnUndeclaredPermissions({ namespace, defaultPermission, resolvers });\n loaded = true;\n },\n };\n}\n\ntype WarnUndeclaredPermissionsParams = {\n namespace: string;\n defaultPermission: Resolver[\"permission\"] | undefined;\n resolvers: Record<string, Resolver>;\n};\n\n/**\n * Warn about resolvers that declare no access requirement at all.\n *\n * A namespace-level `defaultPermission` covers every resolver in the\n * namespace, so the warning only fires when the namespace declares none and\n * at least one of its resolvers declares none either — those resolvers are\n * reachable by anonymous callers.\n * @param params - The namespace, its default permission, and its loaded resolvers\n */\nfunction warnUndeclaredPermissions(params: WarnUndeclaredPermissionsParams): void {\n const { namespace, defaultPermission, resolvers } = params;\n if (defaultPermission !== undefined) {\n return;\n }\n\n const loaded = Object.values(resolvers);\n const undeclared = loaded.filter((resolver) => resolver.permission === undefined);\n if (undeclared.length === 0) {\n return;\n }\n\n logger.warn(\n `Resolver namespace ${styles.highlight(`\"${namespace}\"`)}: ${undeclared.length} of ` +\n `${loaded.length} resolvers declare no \\`permission\\`, so anonymous callers can reach ` +\n `them. Set \\`defaultPermission\\` on the namespace, or declare \\`permission\\` on each ` +\n `resolver (\"allowAnonymous\" if public access is intended).`,\n );\n // Sorted because resolvers load concurrently, so their record order varies per run.\n const names = undeclared.map((resolver) => resolver.name).toSorted();\n logger.debug(` Resolvers without \\`permission\\`: ${names.join(\", \")}`);\n}\n\n/**\n * Assert that every loaded resolver in a namespace has a unique name.\n * Resolvers are stored by source file, so two files declaring the same\n * `name` would otherwise silently share a single bundle cache entry.\n * @param resolvers - Loaded resolvers keyed by source file\n * @param namespace - The namespace the resolvers belong to\n */\nfunction assertUniqueResolverNames(resolvers: Record<string, Resolver>, namespace: string): void {\n const seenNames = new Map<string, string>();\n for (const [file, resolver] of Object.entries(resolvers)) {\n const relativePath = path.relative(process.cwd(), file);\n const existing = seenNames.get(resolver.name);\n if (existing) {\n throw new Error(\n `Duplicate resolver name \"${resolver.name}\" found in namespace \"${namespace}\":\\n` +\n ` - ${existing}\\n` +\n ` - ${relativePath}\\n` +\n `Each resolver must have a unique name within a namespace.`,\n );\n }\n seenNames.set(resolver.name, relativePath);\n }\n}\n","import { parseSync } from \"oxc-parser\";\nimport { type ASTNode, type Replacement, applyReplacements, findStatementEnd } from \"./ast-utils\";\nimport { findAllJobs } from \"./job-detector\";\nimport { collectSdkBindings, isSdkFunctionCall } from \"./sdk-binding-collector\";\nimport type { Program } from \"@oxc-project/types\";\n\n/**\n * Find variable declarations by export names\n * Returns a map of export name to statement range\n * @param program - Parsed TypeScript program\n * @returns Map of export name to statement range\n */\nfunction findVariableDeclarationsByName(\n program: Program,\n): Map<string, { start: number; end: number }> {\n const declarations = new Map<string, { start: number; end: number }>();\n\n for (const statement of program.body) {\n const declaration =\n statement.type === \"ExportNamedDeclaration\" ? statement.declaration : statement;\n if (declaration?.type !== \"VariableDeclaration\") continue;\n\n const variableDeclaration = declaration;\n for (const declarator of variableDeclaration.declarations) {\n if (declarator.id.type === \"Identifier\") {\n declarations.set(declarator.id.name, {\n start: statement.start,\n end: statement.end,\n });\n }\n }\n }\n\n return declarations;\n}\n\n/**\n * Find createWorkflow default export declarations\n * Returns the range of the export statement to remove\n * @param program - Parsed TypeScript program\n * @returns Range of the default export statement or null\n */\nfunction findWorkflowDefaultExport(program: Program): { start: number; end: number } | null {\n const bindings = collectSdkBindings(program, \"createWorkflow\");\n\n for (const statement of program.body) {\n if (statement.type === \"ExportDefaultDeclaration\") {\n const exportDecl = statement;\n const declaration = exportDecl.declaration;\n\n // Check for direct createWorkflow call: export default createWorkflow({...})\n if (isSdkFunctionCall(declaration as unknown as ASTNode, bindings, \"createWorkflow\")) {\n return { start: exportDecl.start, end: exportDecl.end };\n }\n\n // Check for variable reference that was assigned from createWorkflow\n // This handles: const wf = createWorkflow({...}); export default wf;\n if (declaration.type === \"Identifier\") {\n return { start: exportDecl.start, end: exportDecl.end };\n }\n }\n }\n\n return null;\n}\n\n/**\n * Transform workflow source code\n * - Other jobs: remove entire variable declaration\n * @param source - The source code to transform\n * @param targetJobName - The name of the target job (from job config)\n * @param targetJobExportName - The export name of the target job (optional, for enhanced detection)\n * @param otherJobExportNames - Export names of other jobs to remove (optional, for enhanced detection)\n * @returns Transformed workflow source code\n */\nexport function transformWorkflowSource(\n source: string,\n targetJobName: string,\n targetJobExportName?: string,\n otherJobExportNames?: string[],\n): string {\n // Use .ts extension to properly parse TypeScript code\n const { program } = parseSync(\"input.ts\", source);\n\n // Find all jobs using AST detection\n const detectedJobs = findAllJobs(program, source);\n\n // Defense-in-depth: the bundler already gates this function behind an\n // isJobSourceFile check, so dependency files should not reach here.\n // Guard anyway so that external callers don't accidentally strip exports\n // from files that don't contain the target job.\n const targetJobExistsInFile = detectedJobs.some((j) => j.name === targetJobName);\n if (!targetJobExistsInFile) {\n return source;\n }\n\n // Find all variable declarations for export name-based removal\n const allDeclarations = findVariableDeclarationsByName(program);\n\n const replacements: Replacement[] = [];\n const removedStarts = new Set<number>();\n\n // Step 1: First, collect all ranges that will be removed (other job declarations)\n // This runs before the trigger pass so calls inside sibling jobs are removed first.\n for (const job of detectedJobs) {\n if (job.name === targetJobName) {\n continue;\n }\n\n if (job.statementRange && !removedStarts.has(job.statementRange.start)) {\n const endPos = findStatementEnd(source, job.statementRange.end);\n removedStarts.add(job.statementRange.start);\n replacements.push({\n start: job.statementRange.start,\n end: endPos,\n text: \"\",\n });\n } else if (!job.statementRange) {\n // Fallback: replace body with empty function if we can't find the statement\n removedStarts.add(job.bodyValueRange.start);\n replacements.push({\n start: job.bodyValueRange.start,\n end: job.bodyValueRange.end,\n text: \"() => {}\",\n });\n }\n }\n\n // Step 2: Remove other jobs by export name (catches jobs missed by AST detection)\n if (otherJobExportNames) {\n for (const exportName of otherJobExportNames) {\n if (exportName === targetJobExportName) continue;\n\n const declRange = allDeclarations.get(exportName);\n if (declRange && !removedStarts.has(declRange.start)) {\n const endPos = findStatementEnd(source, declRange.end);\n removedStarts.add(declRange.start);\n replacements.push({\n start: declRange.start,\n end: endPos,\n text: \"\",\n });\n }\n }\n }\n\n // Step 3: Remove createWorkflow default export (not needed in job bundles)\n const workflowExport = findWorkflowDefaultExport(program);\n if (workflowExport && !removedStarts.has(workflowExport.start)) {\n const endPos = findStatementEnd(source, workflowExport.end);\n removedStarts.add(workflowExport.start);\n replacements.push({\n start: workflowExport.start,\n end: endPos,\n text: \"\",\n });\n }\n\n return applyReplacements(source, replacements);\n}\n","import * as fs from \"node:fs\";\nimport { parseSync } from \"oxc-parser\";\nimport * as path from \"pathe\";\nimport * as rolldown from \"rolldown\";\nimport { computeBundlerContextHash, withCache, type BundleCache } from \"#/cli/cache/bundle-cache\";\nimport { withBundleConcurrency } from \"#/cli/shared/bundle-concurrency\";\nimport { createBundleLog } from \"#/cli/shared/bundle-log\";\nimport { createLogLevelTreeshakeOptions } from \"#/cli/shared/bundle-log-level\";\nimport { assertNoForbiddenRuntimeGlobals } from \"#/cli/shared/forbidden-runtime-globals\";\nimport { composeFunctionTreeshakeOptions } from \"#/cli/shared/function-treeshake\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { platformBundleDefinePlugin } from \"#/cli/shared/platform-bundle-plugin\";\nimport { resolveTSConfigWithFallback } from \"#/cli/shared/resolve-tsconfig\";\nimport { INVOKER_EXPR } from \"#/cli/shared/runtime-exprs\";\nimport { serializeStartContext, type StartContext } from \"#/cli/shared/start-context\";\nimport {\n createTsconfigPathsPlugin,\n type TsconfigLookupCache,\n} from \"#/cli/shared/tsconfig-paths-plugin\";\nimport { createVirtualEntry } from \"#/cli/shared/virtual-entry\";\nimport ml from \"#/utils/multiline\";\nimport { getModuleExportName, type ASTNode } from \"./ast-utils\";\nimport { findAllJobs } from \"./job-detector\";\nimport { transformWorkflowSource } from \"./source-transformer\";\nimport { detectResolvedStartCalls, hasStartCall, transformStartCalls } from \"./start-transformer\";\nimport type { LogLevel } from \"#/configure/config/types\";\n\nfunction safeRealpath(p: string): string {\n const resolved = path.resolve(p);\n try {\n return fs.realpathSync(resolved);\n } catch (e) {\n logger.debug(`realpathSync failed for ${resolved}: ${e instanceof Error ? e.message : e}`);\n return resolved;\n }\n}\n\ninterface JobInfo {\n name: string;\n exportName: string;\n sourceFile: string;\n}\n\n/**\n * Thrown when a job's dependency graph cannot be statically determined, so the\n * job or a call to it would otherwise be silently dropped from the bundle.\n */\nclass WorkflowJobDetectionError extends Error {}\n\nfunction isExecJobFunctionCallee(node: unknown): boolean {\n if (!node || typeof node !== \"object\") return false;\n const callee = node as ASTNode;\n if (callee.type !== \"MemberExpression\") return false;\n const property = callee.property as ASTNode | undefined;\n if (property?.type !== \"Identifier\" || property.name !== \"execJobFunction\") return false;\n const object = callee.object as ASTNode | undefined;\n if (object?.type !== \"MemberExpression\") return false;\n const workflowProperty = object.property as ASTNode | undefined;\n if (workflowProperty?.type !== \"Identifier\" || workflowProperty.name !== \"workflow\") {\n return false;\n }\n const root = object.object as ASTNode | undefined;\n return root?.type === \"Identifier\" && root.name === \"tailor\";\n}\n\nfunction extractStaticStringValue(node: unknown): string | undefined {\n if (!node || typeof node !== \"object\") return undefined;\n const value = node as ASTNode;\n if (value.type === \"Literal\" && typeof value.value === \"string\") {\n return value.value;\n }\n if (value.type === \"TemplateLiteral\") {\n const quasis = value.quasis as Array<{ value?: { cooked?: string } }> | undefined;\n const expressions = value.expressions as unknown[] | undefined;\n if (quasis?.length === 1 && (expressions?.length ?? 0) === 0) {\n return quasis[0]?.value?.cooked;\n }\n }\n return undefined;\n}\n\nconst RUNTIME_WORKFLOW_MODULE_SPECIFIERS = new Set([\n \"@tailor-platform/sdk/runtime\",\n \"@tailor-platform/sdk/runtime/workflow\",\n]);\n\nfunction collectRuntimeWorkflowImportBindings(program: ASTNode): Set<string> {\n const bindings = new Set<string>();\n for (const statement of (program.body as ASTNode[] | undefined) ?? []) {\n if (statement.type !== \"ImportDeclaration\" || statement.importKind === \"type\") continue;\n const source = statement.source as ASTNode | undefined;\n if (\n typeof source?.value !== \"string\" ||\n !RUNTIME_WORKFLOW_MODULE_SPECIFIERS.has(source.value)\n ) {\n continue;\n }\n for (const specifier of (statement.specifiers as ASTNode[] | undefined) ?? []) {\n if (specifier.type !== \"ImportSpecifier\" || specifier.importKind === \"type\") continue;\n const imported = getModuleExportName(specifier.imported);\n const local = getModuleExportName(specifier.local);\n if (imported === \"workflow\" && local) bindings.add(local);\n }\n }\n return bindings;\n}\n\nfunction isDirectExecJobFunctionCallee(\n node: unknown,\n runtimeWorkflowBindings: ReadonlySet<string>,\n): boolean {\n if (isExecJobFunctionCallee(node)) return true;\n if (!node || typeof node !== \"object\") return false;\n const callee = node as ASTNode;\n if (callee.type !== \"MemberExpression\") return false;\n const property = callee.property as ASTNode | undefined;\n if (property?.type !== \"Identifier\" || property.name !== \"execJobFunction\") return false;\n const object = callee.object as ASTNode | undefined;\n return object?.type === \"Identifier\" && runtimeWorkflowBindings.has(object.name as string);\n}\n\ninterface DirectExecJobFunctionCall {\n targetName: string | undefined;\n}\n\n/**\n * Find calls to `execJobFunction` written directly in workflow source, on\n * either the ambient `tailor.workflow` global or a `workflow` value imported\n * from `@tailor-platform/sdk/runtime`(`/workflow`) (aliases included). Such a\n * call is never recognized as a dependency, so its target would silently be\n * dropped from the bundle unless something else happens to reference it.\n * @param program - Parsed workflow file AST\n * @returns Every direct execJobFunction call found, with its static target\n * name when the first argument is a string literal\n */\nfunction findDirectExecJobFunctionCalls(program: ASTNode): DirectExecJobFunctionCall[] {\n const runtimeWorkflowBindings = collectRuntimeWorkflowImportBindings(program);\n const calls: DirectExecJobFunctionCall[] = [];\n\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n if (\n node.type === \"CallExpression\" &&\n isDirectExecJobFunctionCallee(node.callee, runtimeWorkflowBindings)\n ) {\n const args = node.arguments as unknown[] | undefined;\n calls.push({ targetName: extractStaticStringValue(args?.[0]) });\n }\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(program);\n return calls;\n}\n\nfunction buildDirectExecJobFunctionErrorMessage(\n sourceFile: string,\n call: DirectExecJobFunctionCall,\n): string {\n if (call.targetName !== undefined) {\n return (\n `Workflow file ${sourceFile} calls execJobFunction(\"${call.targetName}\", ...) directly. A ` +\n `direct call is never recognized as a dependency, so \"${call.targetName}\" would silently be ` +\n `dropped from the bundle unless something else happens to reference it. Call the ` +\n `\"${call.targetName}\" job's .start(...) method from inside a job body instead.`\n );\n }\n return (\n `Workflow file ${sourceFile} calls execJobFunction(...) directly with a job name that isn't a ` +\n `string literal, so the target can't be resolved at build time. Call the target job's own ` +\n `.start(...) method from inside a job body instead of calling execJobFunction directly.`\n );\n}\n\n/**\n * Find the job names a bundled job's code calls `execJobFunction` on, by\n * looking for `tailor.workflow.execJobFunction(<name>, ...)` calls with a\n * static string name.\n * @param code - Bundled job code\n * @returns Target job names referenced with a statically known name\n */\nexport function collectExecJobFunctionTargets(code: string): string[] {\n const { program, errors } = parseSync(\"input.js\", code);\n if (errors.length > 0) {\n throw new WorkflowJobDetectionError(\n `Failed to parse bundled job code while checking for missed dependencies: ` +\n `${errors.map((e) => e.message).join(\"; \")}`,\n );\n }\n const targets: string[] = [];\n\n function walk(node: ASTNode | null | undefined): void {\n if (!node || typeof node !== \"object\") return;\n if (node.type === \"CallExpression\" && isExecJobFunctionCallee(node.callee)) {\n const args = node.arguments as unknown[] | undefined;\n const target = extractStaticStringValue(args?.[0]);\n if (target !== undefined) targets.push(target);\n }\n for (const key of Object.keys(node)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach((c: unknown) => walk(c as ASTNode | null));\n } else if (child && typeof child === \"object\") {\n walk(child as ASTNode);\n }\n }\n }\n\n walk(program as unknown as ASTNode);\n return targets;\n}\n\n/**\n * Check every bundled job's code for execJobFunction targets that were not\n * bundled, throwing a WorkflowJobDetectionError naming the caller job when\n * one is found (or when the caller's own bundled code fails to parse).\n * @param bundledCode - Bundled job code by job name\n * @param usedJobNames - Job names that were actually bundled\n */\nexport function validateBundledDependencies(\n bundledCode: Map<string, string>,\n usedJobNames: readonly string[],\n): void {\n const usedJobNameSet = new Set(usedJobNames);\n for (const [callerJobName, code] of bundledCode) {\n let targets: string[];\n try {\n targets = collectExecJobFunctionTargets(code);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new WorkflowJobDetectionError(\n `Failed to check the bundled output of workflow job \"${callerJobName}\" for missed ` +\n `dependencies: ${message}`,\n );\n }\n\n for (const targetJobName of targets) {\n if (!usedJobNameSet.has(targetJobName)) {\n throw new WorkflowJobDetectionError(\n `Workflow job \"${callerJobName}\" calls execJobFunction(\"${targetJobName}\", ...) — usually the ` +\n `result of a rewritten \"${targetJobName}\" job .start() call — but \"${targetJobName}\" was not ` +\n `detected as a dependency and is not included in the bundle. Call the \"${targetJobName}\" job's ` +\n `.start() method from inside the body of workflow job \"${callerJobName}\" (a nested function ` +\n `inside body works too), or make sure the file containing the call is covered by the workflow ` +\n `service's \"files\" pattern.`,\n );\n }\n }\n }\n}\n\nexport interface BundleWorkflowJobsResult {\n /** Maps mainJobName -> list of all job names it depends on (including itself) */\n mainJobDeps: Record<string, string[]>;\n /** Job names that were actually bundled */\n usedJobNames: string[];\n /** Maps job name to bundled code string */\n bundledCode: Map<string, string>;\n}\n\n/**\n * Bundle workflow jobs\n *\n * This function:\n * 1. Detects which jobs are actually used (mainJobs + their dependencies)\n * 2. Uses a transform plugin to transform start calls during bundling\n * 3. Creates an in-memory entry module and bundles with tree-shaking\n *\n * Returns metadata about which jobs each workflow uses.\n * @param allJobs - All available job infos\n * @param mainJobNames - Names of main jobs\n * @param env - Environment variables to inject\n * @param startContext - Start context for transformations\n * @param baseDir - Directory the owning config's tsconfig is resolved against\n * @param cache - Optional bundle cache for skipping unchanged builds\n * @param inlineSourcemap - Whether to enable inline sourcemaps\n * @param bundleLogLevel - Controls which console calls are kept in bundled code\n * @param tsconfigCache - Optional tsconfig lookup cache shared across bundles in this CLI run\n * @returns Workflow job bundling result\n */\nexport async function bundleWorkflowJobs(\n allJobs: JobInfo[],\n mainJobNames: string[],\n env: Record<string, string | number | boolean> = {},\n startContext: StartContext,\n baseDir: string,\n cache?: BundleCache,\n inlineSourcemap?: boolean,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<BundleWorkflowJobsResult> {\n if (allJobs.length === 0) {\n logger.warn(\"No workflow jobs to bundle\");\n return { mainJobDeps: {}, usedJobNames: [], bundledCode: new Map() };\n }\n\n // Filter to only used jobs and get per-mainJob dependencies\n const { usedJobs, mainJobDeps } = await filterUsedJobs(allJobs, mainJobNames, startContext);\n\n logger.newline();\n logger.log(\n `Bundling ${styles.highlight(usedJobs.length.toString())} files for ${styles.info('\"workflow-job\"')}`,\n );\n\n const tsconfig = await resolveTSConfigWithFallback(baseDir);\n\n // Process each job, capped by TAILOR_BUNDLE_CONCURRENCY to bound native\n // memory use (each rolldown.build allocates its own module graph).\n const results = await withBundleConcurrency(usedJobs, (job) =>\n bundleSingleJob(\n job,\n usedJobs,\n tsconfig,\n env,\n startContext,\n cache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n ),\n );\n\n const bundledCode = new Map<string, string>();\n for (const [name, code] of results) {\n bundledCode.set(name, code);\n }\n\n // Backstop for dependency-graph gaps the source-level checks in\n // filterUsedJobs cannot see (e.g. a factored-out .start() call inside a\n // helper file outside `workflow.files`): the rewrite still resolves and\n // produces a valid execJobFunction call, but the target was never bundled.\n // Runs before the success log below so a failure here doesn't print a\n // misleading \"Bundled\" message right before throwing.\n validateBundledDependencies(\n bundledCode,\n usedJobs.map((job) => job.name),\n );\n\n logger.log(`${styles.success(\"Bundled\")} ${styles.info('\"workflow-job\"')}`);\n\n return {\n mainJobDeps,\n usedJobNames: usedJobs.map((job) => job.name),\n bundledCode,\n };\n}\n\ninterface FilterUsedJobsResult {\n usedJobs: JobInfo[];\n mainJobDeps: Record<string, string[]>;\n}\n\n/**\n * Filter jobs to only include those that are actually used.\n * A job is \"used\" if:\n * - It's a mainJob of a workflow\n * - It's called via .start() from another used job (transitively)\n *\n * Also returns a map of mainJob -> all jobs it depends on (for metadata).\n * @param allJobs - All available job infos\n * @param mainJobNames - Names of main jobs\n * @param startContext - Module binding metadata for resolving start targets\n * @returns Used jobs and main job dependency map\n */\nasync function filterUsedJobs(\n allJobs: JobInfo[],\n mainJobNames: string[],\n startContext: StartContext,\n): Promise<FilterUsedJobsResult> {\n if (allJobs.length === 0 || mainJobNames.length === 0) {\n return { usedJobs: [], mainJobDeps: {} };\n }\n\n // Build maps for lookups\n const jobsBySourceFile = new Map<string, JobInfo[]>();\n for (const job of allJobs) {\n const existing = jobsBySourceFile.get(job.sourceFile) || [];\n existing.push(job);\n jobsBySourceFile.set(job.sourceFile, existing);\n }\n\n // Files with no job of their own (e.g. a shared helper module factoring out\n // .start() calls) still need scanning for stray start calls below; otherwise\n // a call factored into such a file is never checked at all.\n const filesToScan = new Map(jobsBySourceFile);\n const knownRealpaths = new Set([...jobsBySourceFile.keys()].map(safeRealpath));\n for (const binding of startContext.modules.values()) {\n if (!knownRealpaths.has(safeRealpath(binding.sourceFile))) {\n filesToScan.set(binding.sourceFile, []);\n }\n }\n\n // Detect start calls and build dependency graph\n // Maps job name -> set of job names it starts\n const dependencies = new Map<string, Set<string>>();\n\n // Process all source files in parallel\n const fileResults = await Promise.all(\n Array.from(filesToScan.entries()).map(async ([sourceFile, jobs]) => {\n try {\n const source = await fs.promises.readFile(sourceFile, \"utf-8\");\n const { program, errors } = parseSync(sourceFile, source);\n if (errors.length > 0) {\n throw new WorkflowJobDetectionError(\n `Failed to parse ${sourceFile}: ${errors.map((e) => e.message).join(\"; \")}`,\n );\n }\n\n const [firstDirectExecCall] = findDirectExecJobFunctionCalls(program as unknown as ASTNode);\n if (firstDirectExecCall) {\n throw new WorkflowJobDetectionError(\n buildDirectExecJobFunctionErrorMessage(sourceFile, firstDirectExecCall),\n );\n }\n\n // Find all jobs in this file to get body ranges\n const detectedJobs = findAllJobs(program, source);\n const startCalls = detectResolvedStartCalls(program, source, startContext, sourceFile);\n\n // For each job in this file, find which start calls are inside its body\n const jobDependencies: Array<{ jobName: string; deps: Set<string> }> = [];\n\n for (const job of jobs) {\n const detectedJob = detectedJobs.find((d) => d.name === job.name);\n if (!detectedJob) {\n throw new WorkflowJobDetectionError(\n `Workflow job \"${job.name}\" (export \"${job.exportName}\" in ${sourceFile}) could not be ` +\n `statically detected: createWorkflowJob's \"name\" must be a string literal and \"body\" ` +\n `must be a function expression. Dynamic or computed values (e.g. body: someWrapper(fn)) ` +\n `cannot be bundled and would be silently dropped.`,\n );\n }\n\n const jobDeps = new Set<string>();\n\n for (const call of startCalls) {\n // Check if this start call is inside the job's body\n if (\n call.kind === \"job\" &&\n call.callRange.start >= detectedJob.bodyValueRange.start &&\n call.callRange.end <= detectedJob.bodyValueRange.end\n ) {\n jobDeps.add(call.targetName);\n }\n }\n\n if (jobDeps.size > 0) {\n jobDependencies.push({ jobName: job.name, deps: jobDeps });\n }\n }\n\n for (const call of startCalls) {\n if (call.kind !== \"job\") continue;\n const isInsideAJobBody = detectedJobs.some(\n (detectedJob) =>\n call.callRange.start >= detectedJob.bodyValueRange.start &&\n call.callRange.end <= detectedJob.bodyValueRange.end,\n );\n if (!isInsideAJobBody) {\n throw new WorkflowJobDetectionError(\n `Call to job \"${call.targetName}\".start() in ${sourceFile} is not inside any workflow ` +\n `job's body: it was factored into a function defined outside the calling job's body. ` +\n `Dependency detection only sees .start() calls lexically inside a job body, so this call ` +\n `would silently drop \"${call.targetName}\" from the bundle. Move the call to a function ` +\n `defined inside the calling job's body.`,\n );\n }\n }\n\n return jobDependencies;\n } catch (error) {\n if (error instanceof WorkflowJobDetectionError) throw error;\n // Some other unexpected error (e.g. a file read failure): treat the\n // file as having no dependencies rather than failing the whole build.\n return [];\n }\n }),\n );\n\n // Merge results into dependencies map\n for (const jobDependencies of fileResults) {\n for (const { jobName, deps } of jobDependencies) {\n dependencies.set(jobName, deps);\n }\n }\n\n // Collect all used jobs and per-mainJob dependencies\n const usedJobNames = new Set<string>();\n const mainJobDeps: Record<string, string[]> = {};\n\n function collectDeps(jobName: string, collected: Set<string>) {\n if (collected.has(jobName)) return;\n collected.add(jobName);\n\n // Recursively collect dependencies\n const deps = dependencies.get(jobName);\n if (deps) {\n for (const dep of deps) {\n collectDeps(dep, collected);\n }\n }\n }\n\n // For each mainJob, collect all its dependencies\n for (const mainJobName of mainJobNames) {\n const depsForMainJob = new Set<string>();\n collectDeps(mainJobName, depsForMainJob);\n mainJobDeps[mainJobName] = Array.from(depsForMainJob);\n\n // Add to global used jobs\n for (const dep of depsForMainJob) {\n usedJobNames.add(dep);\n }\n }\n\n // Filter to only used jobs\n const usedJobs = allJobs.filter((job) => usedJobNames.has(job.name));\n return { usedJobs, mainJobDeps };\n}\n\nasync function bundleSingleJob(\n job: JobInfo,\n allJobs: JobInfo[],\n tsconfig: string | undefined,\n env: Record<string, string | number | boolean>,\n startContext: StartContext,\n cache?: BundleCache,\n inlineSourcemap?: boolean,\n bundleLogLevel: LogLevel = \"DEBUG\",\n tsconfigCache?: TsconfigLookupCache,\n): Promise<[string, string]> {\n const serializedStartContext = serializeStartContext(startContext);\n\n // Include sorted env variables as a prefix so that env changes invalidate the cache\n const sortedEnvPrefix = JSON.stringify(\n Object.fromEntries(Object.entries(env).toSorted(([a], [b]) => a.localeCompare(b))),\n );\n const contextHash = computeBundlerContextHash({\n sourceFile: job.sourceFile,\n extraContext: serializedStartContext,\n tsconfig,\n inlineSourcemap,\n bundleLogLevel,\n prefix: sortedEnvPrefix,\n });\n\n const code = await withCache({\n cache,\n kind: \"workflow-job\",\n name: job.name,\n sourceFile: job.sourceFile,\n contextHash,\n async build(cachePlugins, trackDependency) {\n const absoluteSourcePath = path.resolve(job.sourceFile);\n\n const entryContent = ml /* js */ `\n import { ${job.exportName} } from \"${absoluteSourcePath}\";\n\n export async function main(input) {\n const env = ${JSON.stringify(env)};\n const invoker = ${INVOKER_EXPR};\n return await ${job.exportName}.body(input, { env, invoker });\n }\n `;\n const entry = createVirtualEntry(\n `workflow-job:${job.name}`,\n entryContent,\n \"js\",\n absoluteSourcePath,\n );\n\n // Pre-compute once to avoid redundant realpathSync calls per module\n const resolvedSourceFile = safeRealpath(job.sourceFile);\n\n // Step 2: Bundle with a transform plugin that transforms start calls\n // Collect export names for enhanced AST removal (catches jobs missed by AST detection)\n const otherJobExportNames = allJobs\n .filter(\n (candidate) =>\n candidate.name !== job.name &&\n safeRealpath(candidate.sourceFile) === resolvedSourceFile,\n )\n .map((j) => j.exportName);\n\n // Create transform plugin to transform start calls and remove other job declarations\n const transformPlugin: rolldown.Plugin = {\n name: \"workflow-transform\",\n transform: {\n filter: {\n id: {\n include: [/\\.(ts|mts|cts|js|mjs|cjs)$/],\n },\n },\n handler(code, id) {\n // Only transform source files that contain workflow jobs or start calls\n if (\n !code.includes(\"createWorkflowJob\") &&\n !code.includes(\"createWorkflow\") &&\n !hasStartCall(code)\n ) {\n return null;\n }\n\n // Only remove other jobs and the default workflow export from the job's\n // own source file. Dependency files imported by the source file must keep\n // their exports intact for rolldown to resolve cross-file\n // imports (e.g. `import workflow from \"./other-workflow\"`).\n let transformed = code;\n const isJobSourceFile = safeRealpath(id) === resolvedSourceFile;\n if (isJobSourceFile) {\n transformed = transformWorkflowSource(\n code,\n job.name,\n job.exportName,\n otherJobExportNames,\n );\n }\n\n // Apply workflow.start / job.start transformation.\n if (hasStartCall(transformed)) {\n transformed = transformStartCalls(transformed, startContext, id);\n }\n\n if (transformed === code) return null;\n return { code: transformed };\n },\n },\n };\n\n const plugins: rolldown.Plugin[] = [\n entry.plugin,\n transformPlugin,\n createTsconfigPathsPlugin({ onTsconfigRead: trackDependency, cache: tsconfigCache }),\n platformBundleDefinePlugin,\n ...cachePlugins,\n ];\n\n const bundleLog = createBundleLog({ tsconfig });\n const result = await rolldown.build({\n input: entry.input,\n write: false,\n output: {\n format: \"esm\",\n sourcemap: inlineSourcemap ? \"inline\" : true,\n minify: inlineSourcemap\n ? {\n mangle: {\n keepNames: true,\n },\n }\n : true,\n codeSplitting: false,\n },\n tsconfig,\n plugins,\n treeshake: composeFunctionTreeshakeOptions([\n createLogLevelTreeshakeOptions(bundleLogLevel),\n ]),\n ...bundleLog.options,\n } as rolldown.BuildOptions);\n bundleLog.assertAllResolved();\n\n const bundledCode = result.output[0].code;\n assertNoForbiddenRuntimeGlobals(bundledCode, `Workflow job \"${job.name}\"`);\n return bundledCode;\n },\n });\n\n return [job.name, code];\n}\n","import { z } from \"zod\";\nimport { functionSchema } from \"../common\";\n\nexport const WorkflowJobSchema = z.strictObject({\n name: z.string().describe(\"Job name (must be unique across the project)\"),\n start: functionSchema.describe(\"Start function that initiates the job\"),\n body: functionSchema.describe(\"Job implementation function\"),\n publishEvents: z\n .boolean()\n .optional()\n .describe(\"Enable publishing job execution events for this job\"),\n});\n\nconst durationUnits = [\"ms\", \"s\", \"m\"] as const;\n\nconst unitToSeconds: Record<(typeof durationUnits)[number], number> = {\n ms: 1 / 1000,\n s: 1,\n m: 60,\n};\n\nfunction durationToSeconds(duration: string): number {\n const match = duration.match(/^(\\d+)(ms|s|m)$/);\n if (!match) return 0;\n const value = match[1];\n const unit = match[2];\n if (value === undefined || unit === undefined) return 0;\n return parseInt(value, 10) * unitToSeconds[unit as (typeof durationUnits)[number]];\n}\n\nconst baseDurationSchema = z.templateLiteral([z.number().int().positive(), z.enum(durationUnits)]);\n\nconst durationSchema = (maxSeconds: number) =>\n baseDurationSchema.refine((val) => durationToSeconds(val) <= maxSeconds, {\n message: `Duration must be at most ${maxSeconds} seconds`,\n });\n\nexport const RetryPolicySchema = z\n .strictObject({\n maxRetries: z.number().int().min(1).max(10).describe(\"Maximum number of retries (1-10)\"),\n initialBackoff: durationSchema(3600).describe(\n \"Initial backoff duration (e.g., '1s', '500ms', '1m', max 1h)\",\n ),\n maxBackoff: durationSchema(86400).describe(\n \"Maximum backoff duration (e.g., '30s', '5m', max 24h)\",\n ),\n backoffMultiplier: z.number().min(1).describe(\"Backoff multiplier (>= 1)\"),\n })\n\n .refine((data) => durationToSeconds(data.initialBackoff) <= durationToSeconds(data.maxBackoff), {\n message: \"initialBackoff must be less than or equal to maxBackoff\",\n path: [\"initialBackoff\"],\n })\n .refine((data) => durationToSeconds(data.initialBackoff) > 0, {\n message: \"initialBackoff must be greater than 0\",\n path: [\"initialBackoff\"],\n });\n\nexport const ConcurrencyPolicySchema = z.strictObject({\n maxConcurrentExecutions: z\n .number()\n .int()\n .min(1)\n .max(1000)\n .describe(\"Maximum number of concurrent executions (1-1000)\"),\n});\n\nexport const ExecutionPolicyNameSchema = z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/,\n \"Invalid execution policy name: must match [a-z0-9-] (3-63 chars; must start and end with [a-z0-9])\",\n )\n .describe(\"Workspace-unique execution policy name embedded in the resource TRN\");\n\nexport const ExecutionPolicyKeySchema = z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9_:.-]{0,62}[a-z0-9*]$/,\n \"Invalid execution policy key: must match [a-z0-9_:.-] (2-64 chars; must start with [a-z0-9] and end with [a-z0-9] or a trailing '*')\",\n )\n .describe(\"Execution policy key passed to execJobFunction's executionPolicyKey option\");\n\nexport const WorkflowJobFunctionExecutionPolicySchema = z.strictObject({\n name: ExecutionPolicyNameSchema,\n key: ExecutionPolicyKeySchema,\n concurrencyPolicy: ConcurrencyPolicySchema.optional().describe(\n \"Optional per-key concurrency cap for job function dispatches matching this policy\",\n ),\n});\n\nexport const WorkflowSchema = z.strictObject({\n name: z.string().describe(\"Workflow name\"),\n mainJob: WorkflowJobSchema.describe(\"Main job that starts the workflow\"),\n retryPolicy: RetryPolicySchema.optional().describe(\"Retry policy for the workflow\"),\n concurrencyPolicy: ConcurrencyPolicySchema.optional().describe(\n \"Concurrency policy for the workflow\",\n ),\n publishEvents: z\n .boolean()\n .optional()\n .describe(\"Enable publishing workflow execution events for this workflow\"),\n});\n","import * as path from \"pathe\";\nimport { loadFilesWithIgnores } from \"#/cli/services/file-loader\";\nimport { logger, styles } from \"#/cli/shared/logger\";\nimport { importUserModule } from \"#/cli/shared/user-modules\";\nimport { WorkflowJobSchema, WorkflowSchema } from \"#/parser/service/workflow/index\";\nimport { isSdkBranded } from \"#/utils/brand\";\nimport type { WorkflowServiceConfig } from \"#/configure/config/types\";\nimport type { Workflow } from \"#/types/workflow.generated\";\n\nexport interface CollectedJob {\n name: string;\n exportName: string;\n sourceFile: string;\n /** Explicit `publishEvents` from `createWorkflowJob`, when the job set one. */\n publishEvents?: boolean;\n}\n\nfunction stripRuntimeStart(workflow: unknown): unknown {\n if (\n !isSdkBranded(workflow, \"workflow\") ||\n workflow === null ||\n typeof workflow !== \"object\" ||\n !(\"start\" in workflow)\n ) {\n return workflow;\n }\n const { start: _start, ...rest } = workflow as Record<string, unknown>;\n return rest;\n}\n\ninterface WorkflowLoadResult {\n workflows: Record<string, Workflow>;\n workflowSources: Array<{ workflow: Workflow; sourceFile: string }>;\n jobs: CollectedJob[];\n fileCount: number;\n}\n\nexport type WorkflowService = {\n readonly config: WorkflowServiceConfig;\n readonly workflows: Record<string, Workflow>;\n readonly workflowSources: ReadonlyArray<{ workflow: Workflow; sourceFile: string }>;\n readonly jobs: CollectedJob[];\n readonly fileCount: number;\n loadWorkflows: () => Promise<void>;\n printLoadedWorkflows: () => void;\n};\n\n/**\n * Parameters for creating a WorkflowService\n */\nexport interface CreateWorkflowServiceParams {\n /** The workflow service configuration */\n config: WorkflowServiceConfig;\n /** Directory the config's file patterns are resolved against */\n baseDir: string;\n}\n\n/**\n * Creates a new WorkflowService instance.\n * @param params - Parameters for creating the service\n * @returns A new WorkflowService instance\n */\nexport function createWorkflowService(params: CreateWorkflowServiceParams): WorkflowService {\n const { config, baseDir } = params;\n let workflows: Record<string, Workflow> = {};\n let workflowSources: Array<{ workflow: Workflow; sourceFile: string }> = [];\n let jobs: CollectedJob[] = [];\n let fileCount = 0;\n let loaded = false;\n\n return {\n config,\n get workflows() {\n return workflows;\n },\n get workflowSources() {\n return workflowSources;\n },\n get jobs() {\n return jobs;\n },\n get fileCount() {\n return fileCount;\n },\n loadWorkflows: async () => {\n if (loaded) {\n return;\n }\n const result = await loadAndCollectJobs(config, baseDir);\n workflows = result.workflows;\n workflowSources = result.workflowSources;\n jobs = result.jobs;\n fileCount = result.fileCount;\n loaded = true;\n },\n printLoadedWorkflows: () => {\n if (fileCount === 0) {\n return;\n }\n logger.newline();\n logger.log(`Found ${styles.highlight(fileCount.toString())} workflow files`);\n for (const { workflow, sourceFile } of workflowSources) {\n const relativePath = path.relative(process.cwd(), sourceFile);\n logger.log(\n `Workflow: ${styles.successBright(`\"${workflow.name}\"`)} loaded from ${styles.path(relativePath)}`,\n );\n }\n },\n };\n}\n\n/**\n * Load workflow files and collect all jobs in a single pass.\n * Dependencies are detected at bundle time via AST analysis.\n * @param config - Workflow service configuration\n * @param baseDir - Directory the config's file patterns are resolved against\n * @returns Loaded workflows and collected jobs\n */\nasync function loadAndCollectJobs(\n config: WorkflowServiceConfig,\n baseDir: string,\n): Promise<WorkflowLoadResult> {\n const workflows: Record<string, Workflow> = {};\n const workflowSources: Array<{ workflow: Workflow; sourceFile: string }> = [];\n const collectedJobs: CollectedJob[] = [];\n\n if (config.files.length === 0) {\n return {\n workflows,\n workflowSources,\n jobs: collectedJobs,\n fileCount: 0,\n };\n }\n\n const workflowFiles = loadFilesWithIgnores(config, baseDir);\n const fileCount = workflowFiles.length;\n\n // Maps for collecting data\n const allJobsMap = new Map<string, CollectedJob>();\n\n // Load all files in parallel and collect jobs and workflows\n const loadResults = await Promise.all(\n workflowFiles.map(async (workflowFile) => {\n const { jobs, workflow } = await loadFileContent(workflowFile);\n return { workflowFile, jobs, workflow };\n }),\n );\n\n for (const { workflowFile, jobs, workflow } of loadResults) {\n if (workflow) {\n workflowSources.push({ workflow, sourceFile: workflowFile });\n workflows[workflowFile] = workflow;\n }\n\n for (const job of jobs) {\n const existing = allJobsMap.get(job.name);\n if (existing) {\n throw new Error(\n `Duplicate job name \"${job.name}\" found:\\n` +\n ` - ${existing.sourceFile} (export: ${existing.exportName})\\n` +\n ` - ${job.sourceFile} (export: ${job.exportName})\\n` +\n `Each job must have a unique name.`,\n );\n }\n allJobsMap.set(job.name, job);\n collectedJobs.push(job);\n }\n }\n\n return {\n workflows,\n workflowSources,\n jobs: collectedJobs,\n fileCount,\n };\n}\n\n/**\n * Load a single file and extract jobs and workflow\n * @param filePath - Path to the workflow file\n * @returns Extracted jobs and workflow\n */\nasync function loadFileContent(filePath: string): Promise<{\n jobs: CollectedJob[];\n workflow: Workflow | null;\n}> {\n const jobs: CollectedJob[] = [];\n let workflow: Workflow | null = null;\n\n try {\n const module = await importUserModule(filePath);\n\n for (const [exportName, exportValue] of Object.entries(module)) {\n // Check if it's a workflow (default export)\n if (exportName === \"default\") {\n const workflowResult = WorkflowSchema.safeParse(stripRuntimeStart(exportValue));\n if (workflowResult.success) {\n workflow = workflowResult.data;\n } else if (isSdkBranded(exportValue, [\"workflow\", \"workflow-job\"])) {\n throw workflowResult.error;\n }\n continue;\n }\n\n const jobResult = WorkflowJobSchema.safeParse(exportValue);\n if (jobResult.success) {\n jobs.push({\n name: jobResult.data.name,\n exportName,\n sourceFile: filePath,\n ...(jobResult.data.publishEvents !== undefined\n ? { publishEvents: jobResult.data.publishEvents }\n : {}),\n });\n } else if (isSdkBranded(exportValue, [\"workflow\", \"workflow-job\"])) {\n throw jobResult.error;\n }\n }\n } catch (error) {\n const relativePath = path.relative(process.cwd(), filePath);\n logger.error(\n `${styles.error(\"Failed to load workflow from\")} ${styles.errorBright(relativePath)}`,\n );\n logger.error(String(error));\n throw error;\n }\n\n return { jobs, workflow };\n}\n","import type { AppConfig } from \"#/configure/config/types\";\n\ntype AuthNamespaceApplication = {\n authService?: { config: { name: string } };\n config?: Pick<AppConfig, \"auth\">;\n};\n\n/**\n * Resolve the auth namespace configured for an application.\n * @param application - Loaded application with local or external Auth config\n * @returns Auth namespace, or undefined when no Auth config is present\n */\nexport function getApplicationAuthNamespace(\n application: AuthNamespaceApplication,\n): string | undefined {\n return application.authService?.config.name ?? application.config?.auth?.name;\n}\n\n/**\n * Resolve the auth namespace configured for an application, throwing when none is configured.\n * @param application - Loaded application with local or external Auth config\n * @returns Auth namespace\n */\nexport function requireApplicationAuthNamespace(application: AuthNamespaceApplication): string {\n const authNamespace = getApplicationAuthNamespace(application);\n if (!authNamespace) {\n throw new Error(\"No Auth service configured\");\n }\n return authNamespace;\n}\n","let distPath: string | null = null;\n\nexport const getDistDir = (): string => {\n const configured = process.env.TAILOR_BUILD_OUTPUT_DIR;\n if (configured && configured !== distPath) {\n distPath = configured;\n } else if (distPath === null) {\n distPath = configured || \".tailor\";\n }\n return distPath;\n};\n","import { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Resolve whether inline sourcemaps should be enabled.\n *\n * Resolution order:\n * 1. Config value (`inlineSourcemap` in defineConfig) — if explicitly set\n * 2. Environment variable `TAILOR_INLINE_SOURCEMAP` — if explicitly set\n * 3. Default: `true`\n * @param configValue - The `inlineSourcemap` value from AppConfig\n * @returns Whether inline sourcemaps should be enabled\n */\nexport function resolveInlineSourcemap(configValue?: boolean): boolean {\n if (configValue !== undefined) return configValue;\n const envValue = parseBoolean(process.env.TAILOR_INLINE_SOURCEMAP);\n if (envValue !== undefined) return envValue;\n return true;\n}\n","export function resolverBundleKey(namespace: string, resolverName: string): string {\n return `${namespace}:${resolverName}`;\n}\n","import { z } from \"zod\";\n\nconst NAME_PATTERN = /^[a-z0-9][a-z0-9-]{1,28}[a-z0-9]$/;\nconst AUTH_NAMESPACE_PATTERN = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;\n\n// strip unknown keys\nexport const AIGatewaySchema = z.strictObject({\n name: z\n .string()\n .regex(NAME_PATTERN, \"Must be 3-30 lowercase alphanumeric characters or hyphens\")\n .describe(\"AI Gateway name\"),\n authNamespace: z\n .string()\n .regex(AUTH_NAMESPACE_PATTERN, \"Must be 3-63 lowercase alphanumeric characters or hyphens\")\n .optional()\n .describe(\n \"Auth namespace used to resolve request tokens against the workspace's auth. Defaults to the application's own auth service when omitted; omitting it without an Auth service configured is rejected.\",\n ),\n cors: z\n .array(z.string())\n .optional()\n .describe(\n \"Allowed CORS origins for browser-based clients. Each entry is `*`, `http(s)://*`, `http(s)://*.example.com`, or `http(s)://app.example.com`, optionally with `:port`. Empty list disables cross-origin access.\",\n ),\n});\n","import { z } from \"zod\";\n\n/**\n * Normalize IdPGqlOperationsConfig (alias or object) to IdPGqlOperations object.\n * \"query\" alias expands to read-only mode: every mutation is disabled while\n * queries (`read`, `requestMfaSettingsUrl`) stay enabled.\n * @param config - The config to normalize\n * @returns The normalized IdPGqlOperations object\n */\nfunction normalizeIdPGqlOperations(\n config:\n | \"query\"\n | {\n create?: boolean;\n update?: boolean;\n delete?: boolean;\n read?: boolean;\n sendPasswordResetEmail?: boolean;\n requestMfaSettingsUrl?: boolean;\n unenrollMfa?: boolean;\n },\n) {\n if (config === \"query\") {\n return {\n create: false,\n update: false,\n delete: false,\n read: true,\n sendPasswordResetEmail: false,\n requestMfaSettingsUrl: true,\n unenrollMfa: false,\n };\n }\n return config;\n}\n\n/**\n * Zod schema for IdPGqlOperations configuration with normalization transform.\n * Accepts \"query\" alias or detailed object, normalizes to IdPGqlOperations object.\n */\nexport const IdPGqlOperationsSchema = z\n .union([\n z.literal(\"query\"),\n z.strictObject({\n create: z.boolean().optional().describe(\"Enable _createUser mutation (default: true)\"),\n update: z.boolean().optional().describe(\"Enable _updateUser mutation (default: true)\"),\n delete: z.boolean().optional().describe(\"Enable _deleteUser mutation (default: true)\"),\n read: z.boolean().optional().describe(\"Enable _users and _user queries (default: true)\"),\n sendPasswordResetEmail: z\n .boolean()\n .optional()\n .describe(\"Enable _sendPasswordResetEmail mutation (default: true)\"),\n requestMfaSettingsUrl: z\n .boolean()\n .optional()\n .describe(\"Enable _requestMfaSettingsUrl query (default: true)\"),\n unenrollMfa: z.boolean().optional().describe(\"Enable _unenrollMfa mutation (default: true)\"),\n }),\n ])\n .describe(\n \"Configuration for GraphQL operations on IdP users.\\nAll operations are enabled by default (undefined or true = enabled, false = disabled).\",\n )\n .transform((val) => normalizeIdPGqlOperations(val));\n\nexport const IdPLangSchema = z.enum([\"en\", \"ja\"]).describe(\"IdP UI language\");\n\n// Origins are either a literal http(s) origin (scheme + host + optional port,\n// no path/query/fragment) or a static-website `<name>:url` placeholder that\n// the CLI resolves to a real origin at apply time. The placeholder branch\n// uses the same slug rule as the platform's static-website name validator so\n// typos like `https://app.example.com:url` are rejected instead of being\n// silently interpreted as a website name at apply time.\nconst allowedReturnOriginPattern =\n /^(https?:\\/\\/[a-zA-Z0-9.-]+(:[0-9]+)?|[a-z0-9][a-z0-9-]{1,61}[a-z0-9]:url)$/;\n\nexport const IdPUserAuthPolicySchema = z\n .strictObject({\n useNonEmailIdentifier: z\n .boolean()\n .optional()\n .describe(\"Use non-email identifier for usernames\"),\n allowSelfPasswordReset: z\n .boolean()\n .optional()\n .describe(\"Allow users to reset their own passwords\"),\n passwordRequireUppercase: z\n .boolean()\n .optional()\n .describe(\"Require uppercase letters in passwords\"),\n passwordRequireLowercase: z\n .boolean()\n .optional()\n .describe(\"Require lowercase letters in passwords\"),\n passwordRequireNonAlphanumeric: z\n .boolean()\n .optional()\n .describe(\"Require non-alphanumeric characters in passwords\"),\n passwordRequireNumeric: z\n .boolean()\n .optional()\n .describe(\"Require numeric characters in passwords\"),\n passwordMinLength: z\n .number()\n .int()\n .refine((val) => val >= 6 && val <= 30, {\n message: \"passwordMinLength must be between 6 and 30\",\n })\n .optional()\n .describe(\"Minimum password length (6-30)\"),\n passwordMaxLength: z\n .number()\n .int()\n .refine((val) => val >= 6 && val <= 4096, {\n message: \"passwordMaxLength must be between 6 and 4096\",\n })\n .optional()\n .describe(\"Maximum password length (6-4096)\"),\n allowedEmailDomains: z\n .array(z.string())\n .optional()\n .describe(\"Restrict registration to these email domains\"),\n allowGoogleOauth: z.boolean().optional().describe(\"Enable Google OAuth login\"),\n allowMicrosoftOauth: z.boolean().optional().describe(\"Enable Microsoft OAuth login\"),\n disablePasswordAuth: z.boolean().optional().describe(\"Disable password-based authentication\"),\n enableMfa: z\n .boolean()\n .optional()\n .describe(\"Make TOTP MFA available for users in this namespace\"),\n requireMfa: z\n .boolean()\n .optional()\n .describe(\n \"Require TOTP MFA enrollment and challenge for password-authenticated users (requires enableMfa)\",\n ),\n allowedReturnOrigins: z\n .array(\n z\n .string()\n .regex(\n allowedReturnOriginPattern,\n 'must be an http(s) origin like \"https://app.example.com\" (scheme + host + optional port, no path/query/fragment) or a static-website placeholder like \"<name>:url\"',\n ),\n )\n .optional()\n .describe(\n \"Application origins (scheme + host + optional port) allowed as MFA self-service return targets\",\n ),\n mfaIssuer: z\n .string()\n .max(64, \"mfaIssuer must be 64 characters or less\")\n .optional()\n .describe(\"Label shown next to the user account in authenticator apps\"),\n })\n\n .refine(\n (data) =>\n data.passwordMinLength === undefined ||\n data.passwordMaxLength === undefined ||\n data.passwordMinLength <= data.passwordMaxLength,\n {\n message: \"passwordMinLength must be less than or equal to passwordMaxLength\",\n path: [\"passwordMinLength\"],\n },\n )\n .refine(\n (data) =>\n !data.allowedEmailDomains ||\n data.allowedEmailDomains.length === 0 ||\n !data.useNonEmailIdentifier,\n {\n message: \"allowedEmailDomains cannot be set when useNonEmailIdentifier is true\",\n path: [\"allowedEmailDomains\"],\n },\n )\n .refine(\n (data) =>\n data.allowGoogleOauth === undefined ||\n data.allowGoogleOauth === false ||\n !data.useNonEmailIdentifier,\n {\n message: \"allowGoogleOauth cannot be set when useNonEmailIdentifier is true\",\n path: [\"allowGoogleOauth\"],\n },\n )\n .refine(\n (data) =>\n !data.allowGoogleOauth || (data.allowedEmailDomains && data.allowedEmailDomains.length > 0),\n {\n message: \"allowGoogleOauth requires allowedEmailDomains to be set\",\n path: [\"allowGoogleOauth\"],\n },\n )\n .refine((data) => !data.allowMicrosoftOauth || !data.useNonEmailIdentifier, {\n message: \"allowMicrosoftOauth cannot be set when useNonEmailIdentifier is true\",\n path: [\"allowMicrosoftOauth\"],\n })\n .refine(\n (data) =>\n !data.allowMicrosoftOauth ||\n (data.allowedEmailDomains && data.allowedEmailDomains.length > 0),\n {\n message: \"allowMicrosoftOauth requires allowedEmailDomains to be set\",\n path: [\"allowMicrosoftOauth\"],\n },\n )\n .refine((data) => !data.allowMicrosoftOauth || data.disablePasswordAuth === true, {\n message: \"allowMicrosoftOauth requires disablePasswordAuth to be enabled\",\n path: [\"allowMicrosoftOauth\"],\n })\n .refine(\n (data) =>\n !data.disablePasswordAuth ||\n data.allowGoogleOauth === true ||\n data.allowMicrosoftOauth === true,\n {\n message: \"disablePasswordAuth requires allowGoogleOauth or allowMicrosoftOauth to be enabled\",\n path: [\"disablePasswordAuth\"],\n },\n )\n .refine((data) => !data.disablePasswordAuth || !data.allowSelfPasswordReset, {\n message: \"disablePasswordAuth cannot be used with allowSelfPasswordReset\",\n path: [\"disablePasswordAuth\"],\n })\n .refine((data) => !data.requireMfa || data.enableMfa === true, {\n message: \"requireMfa requires enableMfa to be enabled\",\n path: [\"requireMfa\"],\n })\n .refine(\n (data) =>\n !data.enableMfa || (data.allowedReturnOrigins && data.allowedReturnOrigins.length > 0),\n {\n message:\n \"enableMfa requires allowedReturnOrigins to list at least one origin so MFA self-service has a valid return target\",\n path: [\"enableMfa\"],\n },\n );\n\nconst emailFieldSchema = z\n .string()\n .max(200, \"must be 200 characters or less\")\n .regex(/^[^\\r\\n]*$/, \"must not contain newline characters\");\n\nexport const IdPEmailConfigSchema = z\n .strictObject({\n fromName: emailFieldSchema.optional().describe(\"Default sender display name for emails\"),\n passwordResetSubject: emailFieldSchema\n .optional()\n .describe(\"Default subject for password reset emails\"),\n })\n\n .describe(\"Namespace-level email configuration defaults\");\n\nconst IdPPermissionOperandSchema = z.union([\n z.string(),\n z.boolean(),\n z.array(z.string()).readonly(),\n z.array(z.boolean()).readonly(),\n z.strictObject({ user: z.string() }),\n z.strictObject({ idpUser: z.enum([\"id\", \"name\", \"disabled\"]) }),\n z.strictObject({ oldIdpUser: z.enum([\"id\", \"name\", \"disabled\"]) }),\n z.strictObject({ newIdpUser: z.enum([\"id\", \"name\", \"disabled\"]) }),\n]);\n\nconst IdPPermissionOperatorSchema = z.enum([\"=\", \"!=\", \"in\", \"not in\"]);\n\nconst IdPPermissionConditionSchema = z\n .tuple([IdPPermissionOperandSchema, IdPPermissionOperatorSchema, IdPPermissionOperandSchema])\n .readonly();\n\nconst IdPActionPermissionSchema = z.union([\n // Object format: { conditions, description?, permit? }\n z.strictObject({\n conditions: z.union([\n IdPPermissionConditionSchema,\n z.array(IdPPermissionConditionSchema).readonly(),\n ]),\n description: z.string().optional(),\n permit: z.boolean().optional(),\n }),\n // Single condition tuple: [operand, operator, operand]\n z\n .tuple([IdPPermissionOperandSchema, IdPPermissionOperatorSchema, IdPPermissionOperandSchema])\n .readonly(),\n // Single condition tuple with permit: [operand, operator, operand, permit]\n z\n .tuple([\n IdPPermissionOperandSchema,\n IdPPermissionOperatorSchema,\n IdPPermissionOperandSchema,\n z.boolean(),\n ])\n .readonly(),\n // Multiple conditions with optional trailing permit\n z\n .array(z.union([IdPPermissionConditionSchema, z.boolean()]))\n .refine(\n (arr) => {\n const boolIndex = arr.findIndex((item) => typeof item === \"boolean\");\n return boolIndex === -1 || boolIndex === arr.length - 1;\n },\n { message: \"Boolean permit flag must only appear at the end\" },\n )\n .readonly(),\n]);\n\nexport const IdPPermissionSchema = z\n .strictObject({\n create: z.array(IdPActionPermissionSchema).readonly(),\n read: z.array(IdPActionPermissionSchema).readonly(),\n update: z.array(IdPActionPermissionSchema).readonly(),\n delete: z.array(IdPActionPermissionSchema).readonly(),\n sendPasswordResetEmail: z.array(IdPActionPermissionSchema).readonly().optional(),\n unenrollMfa: z.array(IdPActionPermissionSchema).readonly().optional(),\n })\n\n .describe(\"Per-operation permission policies for IdP users\");\n\nexport const IdPSchema = z\n .strictObject({\n name: z.string().describe(\"IdP service name\"),\n authorization: z\n .union([z.literal(\"insecure\"), z.literal(\"loggedIn\"), z.strictObject({ cel: z.string() })])\n .optional()\n .describe(\"Authorization mode for IdP API access\"),\n clients: z.array(z.string()).describe(\"OAuth2 client names that can use this IdP\"),\n lang: IdPLangSchema.optional().describe(\"UI language for IdP pages\"),\n userAuthPolicy: IdPUserAuthPolicySchema.transform((input) =>\n // transform input may be undefined before schema parse\n // oxlint-disable-next-line typescript/no-unnecessary-condition\n IdPUserAuthPolicySchema.parse(input ?? {}),\n )\n .optional()\n .describe(\"User authentication policy configuration\"),\n publishEvents: z.boolean().optional().describe(\"Enable publishing user lifecycle events\"),\n gqlOperations: IdPGqlOperationsSchema.optional().describe(\n \"Configure which GraphQL operations are enabled\",\n ),\n emailConfig: IdPEmailConfigSchema.optional().describe(\n \"Namespace-level email configuration defaults\",\n ),\n permission: IdPPermissionSchema.optional().describe(\n \"Per-operation permission policies for IdP users\",\n ),\n })\n\n .refine(\n (data) =>\n !data.userAuthPolicy?.enableMfa ||\n data.gqlOperations?.unenrollMfa === false ||\n (data.permission !== undefined && data.permission.unenrollMfa !== undefined),\n {\n message:\n \"permission.unenrollMfa must be set explicitly when userAuthPolicy.enableMfa is true (set [{ conditions: [...], permit: true }] to allow, or [] to deny all). permission itself must also be defined. The requirement is only relaxed when gqlOperations.unenrollMfa is false.\",\n path: [\"permission\", \"unenrollMfa\"],\n },\n )\n .refine(\n (data) =>\n !data.permission ||\n data.userAuthPolicy?.disablePasswordAuth === true ||\n data.gqlOperations?.sendPasswordResetEmail === false ||\n data.permission.sendPasswordResetEmail !== undefined,\n {\n message:\n \"permission.sendPasswordResetEmail must be set explicitly when password authentication is enabled (set [{ conditions: [...], permit: true }] to allow, or [] to deny; only optional when userAuthPolicy.disablePasswordAuth is true or gqlOperations.sendPasswordResetEmail is false)\",\n path: [\"permission\", \"sendPasswordResetEmail\"],\n },\n );\n","import { z } from \"zod\";\n\nconst namePattern = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;\nconst nameSchema = z.string().regex(namePattern);\n\nconst secretsVaultSchema = z.record(nameSchema, z.string().nullish());\nexport const SecretsSchema = z.strictObject({\n vaults: z.record(nameSchema, secretsVaultSchema),\n options: z.strictObject({\n ignoreNullishValues: z.boolean(),\n }),\n});\n","import { z } from \"zod\";\n\n// strip unknown keys\nexport const StaticWebsiteSchema = z.strictObject({\n name: z.string().describe(\"Static website name\"),\n description: z.string().optional().describe(\"Static website description\"),\n allowedIpAddresses: z\n .array(z.string())\n .optional()\n .describe(\"IP addresses allowed to access the website\"),\n customDomains: z.array(z.string()).optional().describe(\"Custom domains for the static website\"),\n});\n","import {\n WAIT_POINT_KEY_GRAMMAR as KEY_GRAMMAR,\n WAIT_POINT_KEY_MAX_LENGTH as MAX_KEY_LENGTH,\n WAIT_POINT_KEY_REGEX as KEY_REGEX,\n isWaitPointParamSegment,\n} from \"#/utils/wait-point-key-grammar\";\nimport type { RegisteredWaitPoint } from \"#/utils/wait-point-registry\";\n\nconst LITERAL_SEGMENT_REGEX = /^[a-z0-9]+$/;\nconst PARAM_NAME_REGEX = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Check one declared wait point key against the key rules.\n *\n * The declaration matters: only `createWaitPoints`' `define` receives the key\n * before the type arguments, so only there can TypeScript read the `$params`\n * off the key literal.\n * @param waitPoint - A key as declared, with the declaration it came from\n * @returns The rule the key breaks, or undefined when the key is usable\n */\nexport function checkWaitPointKey(waitPoint: RegisteredWaitPoint): string | undefined {\n const { key, declaredBy } = waitPoint;\n const segments = key.split(\"-\");\n // Excluding bare \"$\" matters here: otherwise a key carrying one would be\n // answered with advice about typing its $params.\n const paramSegments = segments.filter(isWaitPointParamSegment);\n\n if (paramSegments.length > 0 && declaredBy !== \"define\") {\n return declaredBy === \"property\"\n ? `Invalid wait point key \"${key}\": $params cannot come from a property name. Pass the key to define instead, e.g. define.for(\"${key}\")<Payload, Result>().`\n : `Invalid wait point key \"${key}\": createWaitPoint takes its type arguments first, which stops TypeScript inferring the key as a literal, so it cannot type the $params. Declare it through createWaitPoints instead: createWaitPoints((define) => ({ myWaitPoint: define.for(\"${key}\")<Payload, Result>() })).`;\n }\n\n const seen = new Set<string>();\n let literals = 0;\n\n for (const segment of segments) {\n if (segment.startsWith(\"$\")) {\n const name = segment.slice(1);\n if (!PARAM_NAME_REGEX.test(name)) {\n return `Invalid wait point key \"${key}\": \"${segment}\" is not a usable parameter name. Use letters, digits and underscores, starting with a letter or underscore.`;\n }\n if (seen.has(name)) {\n return `Invalid wait point key \"${key}\": parameter \"$${name}\" appears more than once.`;\n }\n seen.add(name);\n continue;\n }\n // An empty segment comes from a run of hyphens, which the key grammar allows\n // inside a key. Leave the placement rules to the whole-key checks below.\n if (segment === \"\") continue;\n if (!LITERAL_SEGMENT_REGEX.test(segment)) {\n return `Invalid wait point key \"${key}\": segment \"${segment}\" may only contain [a-z0-9]. Wait point keys accept ${KEY_GRAMMAR}, with $params standing in for runtime values.`;\n }\n literals += 1;\n }\n\n // Only a key that actually carries $params can be identity-less in this\n // sense; without them, an empty run of segments is a plain grammar failure.\n if (literals === 0 && paramSegments.length > 0) {\n // A key that also sits outside the grammar needs to hear that first:\n // adding the literal this message asks for would leave \"-$id\" broken.\n return key.startsWith(\"-\") || key.endsWith(\"-\")\n ? `Invalid wait point key \"${key}\": must match ${KEY_GRAMMAR}.`\n : `Invalid wait point key \"${key}\": it needs at least one literal segment alongside its $params, otherwise the key carries no identity of its own and can collide with an unrelated wait point.`;\n }\n\n if (paramSegments.length === 0) {\n return KEY_REGEX.test(key)\n ? undefined\n : `Invalid wait point key \"${key}\": must match ${KEY_GRAMMAR}.`;\n }\n\n // Every param value is itself `[a-z0-9]`-bounded, so the shortest instance of\n // the pattern is valid exactly when every instance is.\n const shortest = segments.map((segment) => (segment.startsWith(\"$\") ? \"0\" : segment)).join(\"-\");\n if (shortest.length > MAX_KEY_LENGTH) {\n return `Wait point key \"${key}\" cannot fit in ${MAX_KEY_LENGTH} characters: even single-character parameter values produce ${shortest.length}.`;\n }\n return KEY_REGEX.test(shortest)\n ? undefined\n : `Invalid wait point key \"${key}\": must match ${KEY_GRAMMAR}.`;\n}\n\n/**\n * Check every declared wait point key, reporting each broken rule once.\n * @param waitPoints - The keys declared across the project, as registered\n * @returns One message per distinct declaration that breaks a rule\n */\nexport function collectWaitPointKeyFailures(waitPoints: readonly RegisteredWaitPoint[]): string[] {\n const failures: string[] = [];\n // The declaration is half of what makes a key valid, so the same key\n // declared two ways is two things to check, not one.\n const seen = new Set<string>();\n for (const waitPoint of waitPoints) {\n const identity = `${waitPoint.declaredBy} ${waitPoint.key}`;\n if (seen.has(identity)) continue;\n seen.add(identity);\n const failure = checkWaitPointKey(waitPoint);\n if (failure) failures.push(failure);\n }\n return failures;\n}\n","import * as path from \"pathe\";\nimport { generatePluginExecutorFiles } from \"#/cli/commands/generate/plugin-executor-generator\";\nimport { generatePluginTableFiles } from \"#/cli/commands/generate/plugin-table-generator\";\nimport { bundleAuthHooks } from \"#/cli/services/auth/bundler\";\nimport { createAuthService, type AuthService } from \"#/cli/services/auth/service\";\nimport { bundleExecutors } from \"#/cli/services/executor/bundler\";\nimport { createExecutorService, type ExecutorService } from \"#/cli/services/executor/service\";\nimport {\n bundleHttpAdapters,\n type HttpAdapterBundleResult,\n} from \"#/cli/services/http-adapter/bundler\";\nimport {\n createHttpAdapterService,\n type HttpAdapterService,\n} from \"#/cli/services/http-adapter/service\";\nimport { bundleResolvers } from \"#/cli/services/resolver/bundler\";\nimport { createResolverService, type ResolverService } from \"#/cli/services/resolver/service\";\nimport { createTailorDBService, type TailorDBService } from \"#/cli/services/tailordb/service\";\nimport { assertUniqueLocalTailorDBTypeNames } from \"#/cli/services/tailordb/type-name-validation\";\nimport { bundleWorkflowJobs, type BundleWorkflowJobsResult } from \"#/cli/services/workflow/bundler\";\nimport { createWorkflowService, type WorkflowService } from \"#/cli/services/workflow/service\";\nimport { getApplicationAuthNamespace } from \"#/cli/shared/auth-namespace\";\nimport { resolveBundleLogLevel } from \"#/cli/shared/bundle-log-level\";\nimport { type LoadedConfig } from \"#/cli/shared/config-loader\";\nimport { getDistDir } from \"#/cli/shared/dist-dir\";\nimport { resolveInlineSourcemap } from \"#/cli/shared/inline-sourcemap\";\nimport { logger } from \"#/cli/shared/logger\";\nimport { resolverBundleKey } from \"#/cli/shared/resolver-bundle-key\";\nimport { buildStartContext } from \"#/cli/shared/start-context\";\nimport { createTsconfigLookupCache } from \"#/cli/shared/tsconfig-paths-plugin\";\nimport {\n type AppConfig,\n type ExecutorServiceInput,\n type HttpAdapterServiceInput,\n type ResolverServiceInput,\n type WorkflowServiceConfig,\n} from \"#/configure/config/types\";\nimport { type AuthConfig } from \"#/configure/services/auth/types\";\nimport { type IdPConfig, type IdPOwnConfig } from \"#/configure/services/idp/types\";\nimport { AIGatewaySchema } from \"#/parser/service/aigateway/index\";\nimport { AuthConfigSchema } from \"#/parser/service/auth/index\";\nimport { IdPSchema } from \"#/parser/service/idp/index\";\nimport { SecretsSchema } from \"#/parser/service/secrets/index\";\nimport { StaticWebsiteSchema } from \"#/parser/service/staticwebsite/index\";\nimport { TailorDBServiceConfigSchema } from \"#/parser/service/tailordb/index\";\nimport { collectWaitPointKeyFailures } from \"#/parser/service/workflow/wait-point-key\";\nimport { getScopedWaitPoints } from \"#/utils/wait-point-registry\";\nimport type { BundleCache } from \"#/cli/cache/bundle-cache\";\nimport type { BundledScripts } from \"#/cli/commands/deploy/function-registry-types\";\nimport type { TailorDBServiceInput } from \"#/configure/services/tailordb/types\";\nimport type { PluginManager } from \"#/plugin/manager\";\nimport type { AIGateway, AIGatewayInput } from \"#/types/aigateway.generated\";\nimport type { IdP } from \"#/types/idp.generated\";\nimport type { StaticWebsite, StaticWebsiteInput } from \"#/types/staticwebsite.generated\";\n\ntype SecretVault = {\n readonly vaultName: string;\n readonly secrets: ReadonlyArray<{ name: string; value: string | null | undefined }>;\n};\n\nexport type Application = {\n readonly name: string;\n readonly id: string | undefined;\n readonly config: AppConfig;\n readonly subgraphs: ReadonlyArray<{ Type: string; Name: string }>;\n readonly tailorDBServices: ReadonlyArray<TailorDBService>;\n readonly externalTailorDBNamespaces: ReadonlyArray<string>;\n readonly resolverServices: ReadonlyArray<ResolverService>;\n readonly idpServices: ReadonlyArray<IdP>;\n readonly authService: Readonly<AuthService> | undefined;\n readonly executorService: Readonly<ExecutorService> | undefined;\n readonly workflowService: Readonly<WorkflowService> | undefined;\n readonly httpAdapterService: Readonly<HttpAdapterService> | undefined;\n readonly staticWebsiteServices: ReadonlyArray<StaticWebsite>;\n readonly aiGatewayServices: ReadonlyArray<AIGateway>;\n readonly secrets: ReadonlyArray<SecretVault>;\n readonly ignoreNullishValues: boolean;\n readonly env: Readonly<Record<string, string | number | boolean>>;\n readonly applications: ReadonlyArray<Application>;\n};\n\n/**\n * Result of loading the application\n */\nexport interface LoadApplicationResult {\n /** Fully initialized application */\n application: Application;\n /** Workflow bundling result (if workflows were bundled) */\n workflowBuildResult?: BundleWorkflowJobsResult;\n /** HTTP adapter bundling result (if adapters were bundled) */\n httpAdapterBuildResult?: HttpAdapterBundleResult;\n /** In-memory bundled scripts organized by kind */\n bundledScripts: BundledScripts;\n}\n\ntype DefineTailorDBResult = {\n tailorDBServices: TailorDBService[];\n externalTailorDBNamespaces: string[];\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction defineTailorDB(\n config: TailorDBServiceInput | undefined,\n baseDir: string,\n pluginManager?: PluginManager,\n): DefineTailorDBResult {\n const tailorDBServices: TailorDBService[] = [];\n const externalTailorDBNamespaces: string[] = [];\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { tailorDBServices, externalTailorDBNamespaces, subgraphs };\n }\n\n for (const [namespace, serviceConfig] of Object.entries(config)) {\n if (\"external\" in serviceConfig) {\n externalTailorDBNamespaces.push(namespace);\n } else {\n // Parse config through schema to normalize gqlOperations\n const parsedConfig = TailorDBServiceConfigSchema.parse(serviceConfig);\n const tailorDB = createTailorDBService({\n namespace,\n config: parsedConfig,\n pluginManager,\n baseDir,\n });\n tailorDBServices.push(tailorDB);\n }\n subgraphs.push({ Type: \"tailordb\", Name: namespace });\n }\n\n return { tailorDBServices, externalTailorDBNamespaces, subgraphs };\n}\n\ntype DefineResolverResult = {\n resolverServices: ResolverService[];\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction defineResolver(\n config: ResolverServiceInput | undefined,\n baseDir: string,\n): DefineResolverResult {\n const resolverServices: ResolverService[] = [];\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { resolverServices, subgraphs };\n }\n\n for (const [namespace, serviceConfig] of Object.entries(config)) {\n if (!(\"external\" in serviceConfig)) {\n const resolverService = createResolverService(namespace, serviceConfig, baseDir);\n resolverServices.push(resolverService);\n }\n subgraphs.push({ Type: \"pipeline\", Name: namespace });\n }\n\n return { resolverServices, subgraphs };\n}\n\ntype DefineIdpResult = {\n idpServices: IdP[];\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction stripIdpProviderHelper(idpConfig: IdPOwnConfig): IdPOwnConfig {\n const configWithProvider = idpConfig as IdPOwnConfig & { provider?: unknown };\n if (typeof configWithProvider.provider !== \"function\") return idpConfig;\n const { provider: _provider, ...config } = configWithProvider;\n return config;\n}\n\nfunction defineIdp(config: readonly IdPConfig[] | undefined): DefineIdpResult {\n const idpServices: IdP[] = [];\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { idpServices, subgraphs };\n }\n\n const idpNames = new Set<string>();\n config.forEach((idpConfig) => {\n const name = idpConfig.name;\n if (idpNames.has(name)) {\n throw new Error(`IdP with name \"${name}\" already defined.`);\n }\n idpNames.add(name);\n if (!(\"external\" in idpConfig)) {\n const idp = IdPSchema.parse(stripIdpProviderHelper(idpConfig));\n idpServices.push(idp);\n }\n subgraphs.push({ Type: \"idp\", Name: name });\n });\n\n return { idpServices, subgraphs };\n}\n\ntype DefineAuthResult = {\n authService: AuthService | undefined;\n subgraphs: Array<{ Type: string; Name: string }>;\n};\n\nfunction defineAuth(\n config: AuthConfig | undefined,\n tailorDBServices: ReadonlyArray<TailorDBService>,\n externalTailorDBNamespaces: ReadonlyArray<string>,\n): DefineAuthResult {\n const subgraphs: Array<{ Type: string; Name: string }> = [];\n\n if (!config) {\n return { authService: undefined, subgraphs };\n }\n\n let authService: AuthService | undefined;\n if (!(\"external\" in config)) {\n authService = createAuthService(\n AuthConfigSchema.parse(config),\n tailorDBServices,\n externalTailorDBNamespaces,\n );\n }\n subgraphs.push({ Type: \"auth\", Name: config.name });\n\n return { authService, subgraphs };\n}\n\nfunction defineExecutor(\n config: ExecutorServiceInput | undefined,\n baseDir: string,\n hasPluginExecutors: boolean,\n): ExecutorService | undefined {\n if (!config && !hasPluginExecutors) {\n return undefined;\n }\n return createExecutorService({ config: config ?? { files: [] }, baseDir });\n}\n\nfunction defineWorkflow(\n config: WorkflowServiceConfig | undefined,\n baseDir: string,\n): WorkflowService | undefined {\n if (!config) {\n return undefined;\n }\n return createWorkflowService({ config, baseDir });\n}\n\nfunction defineHttpAdapterService(\n config: HttpAdapterServiceInput | undefined,\n baseDir: string,\n): HttpAdapterService | undefined {\n if (!config) {\n return undefined;\n }\n return createHttpAdapterService({ config, baseDir });\n}\n\nfunction stripStaticWebsiteUrlHelper(config: StaticWebsiteInput): StaticWebsiteInput {\n const configWithUrl = config as StaticWebsiteInput & { url?: unknown };\n if (configWithUrl.url !== `${config.name}:url`) return config;\n const { url: _url, ...websiteConfig } = configWithUrl;\n return websiteConfig;\n}\n\nfunction defineStaticWebsites(\n websites: readonly StaticWebsiteInput[] | undefined,\n): StaticWebsite[] {\n const staticWebsiteServices: StaticWebsite[] = [];\n const websiteNames = new Set<string>();\n\n (websites ?? []).forEach((config) => {\n const website = StaticWebsiteSchema.parse(stripStaticWebsiteUrlHelper(config));\n if (websiteNames.has(website.name)) {\n throw new Error(`Static website with name \"${website.name}\" already defined.`);\n }\n websiteNames.add(website.name);\n staticWebsiteServices.push(website);\n });\n\n return staticWebsiteServices;\n}\n\nfunction defineAIGateways(\n gateways: readonly AIGatewayInput[] | undefined,\n applicationAuthNamespace: string | undefined,\n): AIGateway[] {\n const aiGatewayServices: AIGateway[] = [];\n const gatewayNames = new Set<string>();\n\n (gateways ?? []).forEach((config) => {\n const gateway = AIGatewaySchema.parse(config);\n if (gatewayNames.has(gateway.name)) {\n throw new Error(`AI Gateway with name \"${gateway.name}\" already defined.`);\n }\n gatewayNames.add(gateway.name);\n if (gateway.authNamespace === undefined) {\n if (!applicationAuthNamespace) {\n throw new Error(\n `AI Gateway \"${gateway.name}\" has no \"authNamespace\" and no Auth service is configured ` +\n `to default to. Define an Auth service, or set \"authNamespace\" explicitly.`,\n );\n }\n gateway.authNamespace = applicationAuthNamespace;\n }\n aiGatewayServices.push(gateway);\n });\n\n return aiGatewayServices;\n}\n\nfunction parseSecretManager(config: AppConfig[\"secrets\"]): {\n secrets: SecretVault[];\n ignoreNullishValues: boolean;\n} {\n if (!config) {\n return { secrets: [], ignoreNullishValues: false };\n }\n\n const parsed = SecretsSchema.parse(config);\n const { ignoreNullishValues } = parsed.options;\n\n const secrets = Object.entries(parsed.vaults).map(([vaultName, vaultSecrets]) => ({\n vaultName,\n secrets: Object.entries(vaultSecrets).map(([name, value]) => ({ name, value })),\n }));\n\n // Defensive check: error if nullish values exist without ignoreNullishValues\n if (!ignoreNullishValues) {\n for (const vault of secrets) {\n for (const secret of vault.secrets) {\n if (secret.value == null) {\n throw new Error(\n `Secret \"${vault.vaultName}/${secret.name}\" has no value. ` +\n `Use { ignoreNullishValues: true } option in defineSecretManager() to skip secrets without values.`,\n );\n }\n }\n }\n }\n\n return { secrets, ignoreNullishValues };\n}\n\ntype DefineServicesResult = {\n tailordbResult: DefineTailorDBResult;\n resolverResult: DefineResolverResult;\n idpResult: DefineIdpResult;\n authResult: DefineAuthResult;\n staticWebsiteServices: StaticWebsite[];\n aiGatewayServices: AIGateway[];\n secrets: SecretVault[];\n ignoreNullishValues: boolean;\n};\n\nfunction defineServices(\n config: AppConfig,\n baseDir: string,\n pluginManager?: PluginManager,\n): DefineServicesResult {\n const tailordbResult = defineTailorDB(config.db, baseDir, pluginManager);\n const resolverResult = defineResolver(config.resolver, baseDir);\n const idpResult = defineIdp(config.idp);\n const authResult = defineAuth(\n config.auth,\n tailordbResult.tailorDBServices,\n tailordbResult.externalTailorDBNamespaces,\n );\n const staticWebsiteServices = defineStaticWebsites(config.staticWebsites);\n const aiGatewayServices = defineAIGateways(\n config.aiGateways,\n getApplicationAuthNamespace({ authService: authResult.authService, config }),\n );\n const { secrets, ignoreNullishValues } = parseSecretManager(config.secrets);\n return {\n tailordbResult,\n resolverResult,\n idpResult,\n authResult,\n staticWebsiteServices,\n aiGatewayServices,\n secrets,\n ignoreNullishValues: ignoreNullishValues,\n };\n}\n\nfunction buildApplication(params: {\n config: AppConfig;\n tailordbResult: DefineTailorDBResult;\n resolverResult: DefineResolverResult;\n idpResult: DefineIdpResult;\n authResult: DefineAuthResult;\n executorService: ExecutorService | undefined;\n workflowService: WorkflowService | undefined;\n httpAdapterService: HttpAdapterService | undefined;\n staticWebsiteServices: StaticWebsite[];\n aiGatewayServices: AIGateway[];\n secrets: SecretVault[];\n ignoreNullishValues: boolean;\n env: Record<string, string | number | boolean>;\n}): Application {\n const application: Application = {\n name: params.config.name,\n id: params.config.id,\n config: params.config,\n subgraphs: [\n ...params.tailordbResult.subgraphs,\n ...params.resolverResult.subgraphs,\n ...params.idpResult.subgraphs,\n ...params.authResult.subgraphs,\n ],\n tailorDBServices: params.tailordbResult.tailorDBServices,\n externalTailorDBNamespaces: params.tailordbResult.externalTailorDBNamespaces,\n resolverServices: params.resolverResult.resolverServices,\n idpServices: params.idpResult.idpServices,\n authService: params.authResult.authService,\n executorService: params.executorService,\n workflowService: params.workflowService,\n httpAdapterService: params.httpAdapterService,\n staticWebsiteServices: params.staticWebsiteServices,\n aiGatewayServices: params.aiGatewayServices,\n secrets: params.secrets,\n ignoreNullishValues: params.ignoreNullishValues,\n env: params.env,\n get applications() {\n return [application];\n },\n };\n return application;\n}\n\n/**\n * Parameters for defining an application\n */\nexport interface DefineApplicationParams {\n /** Application configuration object (must be loaded via loadConfig) */\n config: LoadedConfig;\n /** Plugin manager for processing plugins */\n pluginManager?: PluginManager;\n /** Optional bundle cache for skipping unchanged builds */\n bundleCache?: BundleCache;\n}\n\n/**\n * Define a Tailor application from the given configuration.\n * This is a lightweight, synchronous function that creates the application\n * structure without loading tables or bundling files.\n * @param params - Parameters for defining the application\n * @returns Configured application instance\n */\nexport function defineApplication(params: DefineApplicationParams): Application {\n const { config, pluginManager } = params;\n const baseDir = path.dirname(config.path);\n const services = defineServices(config, baseDir, pluginManager);\n // Plugin executors are not known at define-time; generate/apply flows handle them after table loading.\n const executorService = defineExecutor(config.executor, baseDir, false);\n const workflowService = defineWorkflow(config.workflow, baseDir);\n const httpAdapterService = defineHttpAdapterService(config.httpAdapter, baseDir);\n\n return buildApplication({\n config,\n ...services,\n executorService,\n workflowService,\n httpAdapterService,\n env: config.env ?? {},\n });\n}\n\n/**\n * Generate plugin table and executor files if a plugin manager is provided.\n * Collects source table info from TailorDB services and delegates to PluginManager.\n * @param pluginManager - Plugin manager instance (skips if undefined)\n * @param tailorDBServices - TailorDB services to collect table source info from\n * @param configPath - Path to tailor.config.ts for resolving plugin imports\n * @returns Generated executor file paths\n */\nexport function generatePluginFilesIfNeeded(\n pluginManager: PluginManager | undefined,\n tailorDBServices: ReadonlyArray<TailorDBService>,\n configPath: string,\n): string[] {\n if (!pluginManager) return [];\n\n const sourceTableInfoMap = new Map<string, { filePath: string; exportName: string }>();\n for (const db of tailorDBServices) {\n const tableSourceInfo = db.typeSourceInfo;\n for (const [tableName, sourceInfo] of Object.entries(tableSourceInfo)) {\n if (sourceInfo.filePath) {\n sourceTableInfoMap.set(tableName, {\n filePath: sourceInfo.filePath,\n exportName: sourceInfo.exportName,\n });\n }\n }\n }\n\n return pluginManager.generatePluginFiles({\n outputDir: path.join(getDistDir(), \"plugin\"),\n sourceTableInfoMap,\n configPath,\n tableGenerator: generatePluginTableFiles,\n executorGenerator: generatePluginExecutorFiles,\n });\n}\n\nfunction assertWaitPointKeys(): void {\n const failures = collectWaitPointKeyFailures(getScopedWaitPoints());\n if (failures.length === 0) return;\n throw new Error(failures.join(\"\\n\"));\n}\n\n/**\n * Load and fully initialize a Tailor application.\n * This performs all I/O-heavy operations: loading tables, processing plugins,\n * generating plugin files, bundling, and loading definitions for validation.\n * @param params - Parameters for defining and loading the application\n * @returns Fully initialized application with workflow results\n */\nexport async function loadApplication(\n params: DefineApplicationParams,\n): Promise<LoadApplicationResult> {\n const { config, pluginManager, bundleCache } = params;\n const baseDir = path.dirname(config.path);\n\n // 1. Define services (synchronous)\n const {\n tailordbResult,\n resolverResult,\n idpResult,\n authResult,\n staticWebsiteServices,\n aiGatewayServices,\n secrets,\n ignoreNullishValues,\n } = defineServices(config, baseDir, pluginManager);\n\n // 2. Load TailorDB tables and process namespace plugins\n for (const tailordb of tailordbResult.tailorDBServices) {\n await tailordb.loadTypes();\n await tailordb.processNamespacePlugins();\n }\n assertUniqueLocalTailorDBTypeNames({\n tailorDBServices: tailordbResult.tailorDBServices,\n });\n\n // 3. Generate plugin files and determine executor file paths\n const pluginExecutorFiles = generatePluginFilesIfNeeded(\n pluginManager,\n tailordbResult.tailorDBServices,\n config.path,\n );\n\n // 4. Determine final executorService (const, no reassignment)\n const executorService = defineExecutor(config.executor, baseDir, pluginExecutorFiles.length > 0);\n\n // 5. Load and collect workflows\n const workflowService = defineWorkflow(config.workflow, baseDir);\n if (workflowService) {\n await workflowService.loadWorkflows();\n }\n\n // 6. Load and collect HTTP adapters\n const httpAdapterService = defineHttpAdapterService(config.httpAdapter, baseDir);\n if (httpAdapterService) {\n await httpAdapterService.loadAdapters();\n }\n\n // 7. Build start context for workflow/job start transformation\n const startContext = await buildStartContext(\n config.workflow,\n getApplicationAuthNamespace({ authService: authResult.authService, config }),\n baseDir,\n );\n\n // 8. Resolve bundle settings\n const inlineSourcemap = resolveInlineSourcemap(config.inlineSourcemap);\n const bundleLogLevel = resolveBundleLogLevel(config.logLevel);\n // Shared across every bundle below so a project with many resolvers/executors/etc.\n // reads and parses each ancestor tsconfig once instead of once per item.\n const tsconfigCache = createTsconfigLookupCache();\n\n // Collect in-memory bundled scripts\n const bundledScripts: BundledScripts = {\n resolvers: new Map(),\n executors: new Map(),\n workflowJobs: new Map(),\n authHooks: new Map(),\n };\n\n // 9. Bundle resolvers\n for (const pipeline of resolverResult.resolverServices) {\n const resolverBundles = await bundleResolvers({\n namespace: pipeline.namespace,\n config: pipeline.config,\n baseDir,\n defaultPermission: pipeline.defaultPermission,\n startContext,\n cache: bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n });\n for (const [name, code] of resolverBundles) {\n bundledScripts.resolvers.set(resolverBundleKey(pipeline.namespace, name), code);\n }\n }\n\n // 10. Bundle executors\n if (executorService) {\n bundledScripts.executors = await bundleExecutors({\n config: executorService.config,\n startContext,\n additionalFiles: [...pluginExecutorFiles],\n cache: bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n baseDir,\n tsconfigCache,\n });\n }\n\n // 11. Bundle workflows\n let workflowBuildResult: BundleWorkflowJobsResult | undefined;\n if (workflowService && workflowService.jobs.length > 0) {\n const mainJobNames = workflowService.workflowSources.map((ws) => ws.workflow.mainJob.name);\n workflowBuildResult = await bundleWorkflowJobs(\n workflowService.jobs,\n mainJobNames,\n config.env ?? {},\n startContext,\n baseDir,\n bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n tsconfigCache,\n );\n bundledScripts.workflowJobs = workflowBuildResult.bundledCode;\n }\n\n // 12. Bundle HTTP adapters\n let httpAdapterBuildResult: HttpAdapterBundleResult | undefined;\n if (httpAdapterService && httpAdapterService.adapters.length > 0) {\n httpAdapterBuildResult = await bundleHttpAdapters(\n httpAdapterService.adapters.map((a) => ({\n name: a.adapter.name,\n sourceFile: a.sourceFile,\n methods: a.methods,\n hasOutput: a.hasOutput,\n })),\n baseDir,\n bundleCache,\n bundleLogLevel,\n tsconfigCache,\n );\n }\n\n // 13. Bundle auth hooks\n if (authResult.authService?.config.hooks?.beforeLogin) {\n const authName = authResult.authService.config.name;\n bundledScripts.authHooks = await bundleAuthHooks({\n configPath: config.path,\n authName,\n handlerAccessPath: `auth.hooks.beforeLogin.handler`,\n env: config.env ?? {},\n startContext,\n cache: bundleCache,\n inlineSourcemap,\n bundleLogLevel,\n baseDir,\n tsconfigCache,\n });\n }\n\n // 14. Load resolver and executor definitions (for validation/logging)\n for (const pipeline of resolverResult.resolverServices) {\n await pipeline.loadResolvers();\n }\n if (executorService) {\n await executorService.loadExecutors();\n if (pluginExecutorFiles.length > 0) {\n await executorService.loadPluginExecutorFiles([...pluginExecutorFiles]);\n }\n }\n // 15. Check the wait point keys every loaded module declared\n assertWaitPointKeys();\n\n if (workflowService) {\n workflowService.printLoadedWorkflows();\n }\n if (httpAdapterService) {\n httpAdapterService.printLoadedAdapters();\n }\n logger.newline();\n\n // 16. Build immutable Application\n const application = buildApplication({\n config,\n tailordbResult,\n resolverResult,\n idpResult,\n authResult,\n executorService,\n workflowService,\n httpAdapterService,\n staticWebsiteServices,\n aiGatewayServices,\n secrets,\n ignoreNullishValues,\n env: config.env ?? {},\n });\n\n return { application, workflowBuildResult, httpAdapterBuildResult, bundledScripts };\n}\n"],"mappings":"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"}
|