@workos/oagen 0.30.2 → 0.31.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/README.md +4 -12
- package/dist/cli/index.d.mts +1 -1
- package/dist/cli/index.mjs +2885 -651
- package/dist/cli/index.mjs.map +1 -1
- package/dist/compat/index.d.mts +85 -36
- package/dist/compat/index.d.mts.map +1 -1
- package/dist/compat/index.mjs +33 -23
- package/dist/compat/index.mjs.map +1 -1
- package/dist/{diff-BO5FieX5.mjs → diff-CAsypxXV.mjs} +107 -89
- package/dist/{diff-BO5FieX5.mjs.map → diff-CAsypxXV.mjs.map} +1 -1
- package/dist/differ-B0DSuKUZ.d.mts +72 -0
- package/dist/differ-B0DSuKUZ.d.mts.map +1 -0
- package/dist/index.d.mts +129 -61
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2877 -546
- package/dist/index.mjs.map +1 -1
- package/dist/{overlay-DWAHPofk.mjs → overlay-Dj3WWlNP.mjs} +44 -38
- package/dist/overlay-Dj3WWlNP.mjs.map +1 -0
- package/dist/scripts/smoke/baseline.d.mts +1 -1
- package/dist/scripts/smoke/baseline.mjs +2740 -527
- package/dist/scripts/smoke/baseline.mjs.map +1 -1
- package/dist/scripts/smoke/sdk-test.d.mts +1 -1
- package/dist/scripts/smoke/sdk-test.mjs +4 -2
- package/dist/scripts/smoke/sdk-test.mjs.map +1 -1
- package/dist/smoke.d.mts +251 -36
- package/dist/smoke.d.mts.map +1 -1
- package/dist/smoke.mjs +2740 -527
- package/dist/smoke.mjs.map +1 -1
- package/dist/{tree-sitter-CDKm3n64.mjs → tree-sitter-C7Hk-NDu.mjs} +35 -7
- package/dist/tree-sitter-C7Hk-NDu.mjs.map +1 -0
- package/dist/{types-BcbGLNkh.d.mts → types-I7W7CNl1.d.mts} +219 -9
- package/dist/types-I7W7CNl1.d.mts.map +1 -0
- package/dist/verify/index.d.mts +7 -8
- package/dist/verify/index.d.mts.map +1 -1
- package/dist/verify/index.mjs +24 -14
- package/dist/verify/index.mjs.map +1 -1
- package/docs/architecture/emitter-contract.md +1 -0
- package/docs/architecture/ir-types.md +170 -17
- package/docs/cli.md +13 -13
- package/package.json +3 -3
- package/skills/check-emitter-parity/SKILL.md +15 -1
- package/dist/differ-nZSxhCfC.d.mts +0 -123
- package/dist/differ-nZSxhCfC.d.mts.map +0 -1
- package/dist/overlay-DWAHPofk.mjs.map +0 -1
- package/dist/tree-sitter-CDKm3n64.mjs.map +0 -1
- package/dist/types-BcbGLNkh.d.mts.map +0 -1
package/dist/smoke.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smoke.mjs","names":[],"sources":["../src/utils/naming.ts","../src/ir/sdk-behavior.ts","../src/errors.ts","../src/parser/refs.ts","../src/ir/types.ts","../src/parser/inline-models.ts","../src/parser/schemas.ts","../src/parser/pagination.ts","../src/parser/responses.ts","../src/parser/operations.ts","../src/parser/normalize-inline-models.ts","../src/parser/collect-inline-enums.ts","../src/parser/parameter-group-names.ts","../src/parser/normalize-model-refs.ts","../src/parser/parse.ts","../scripts/smoke/shared.ts"],"sourcesContent":["/**\n * Known compound tokens that the regex-based splitter over-splits.\n * Each entry is [lowercase-word-sequence, canonical-form].\n * Sorted longest-first so greedy matching works correctly.\n */\nconst COMPOUND_WORDS: [string[], string][] = [\n [['m', '2', 'm'], 'M2M'],\n [['o', 'auth'], 'OAuth'],\n];\n\n/**\n * Recombine adjacent words that form a known compound token.\n */\nfunction recombineCompounds(words: string[]): string[] {\n const result: string[] = [];\n let i = 0;\n while (i < words.length) {\n let matched = false;\n for (const [pattern, canonical] of COMPOUND_WORDS) {\n if (i + pattern.length <= words.length) {\n const matches = pattern.every((p, j) => words[i + j].toLowerCase() === p);\n if (matches) {\n result.push(canonical);\n i += pattern.length;\n matched = true;\n break;\n }\n }\n }\n if (!matched) {\n result.push(words[i]);\n i++;\n }\n }\n return result;\n}\n\n/**\n * Split a string into words, handling:\n * - camelCase / PascalCase boundaries\n * - snake_case / kebab-case separators\n * - Consecutive capitals (e.g., \"HTTPClient\" → [\"HTTP\", \"Client\"])\n * - Numbers as word boundaries (e.g., \"OAuth2Token\" → [\"OAuth\", \"2\", \"Token\"])\n * - Known compounds are recombined (e.g., \"M2M\" stays as one word)\n */\nexport function splitWords(s: string): string[] {\n if (!s) return [];\n\n const words = s\n .replace(/[^a-zA-Z0-9_\\-\\s.]/g, '_') // replace non-alphanumeric chars with separator\n .replace(/([a-z])([A-Z])/g, '$1\\0$2') // camelCase boundary\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1\\0$2') // consecutive caps boundary\n .replace(/([a-zA-Z])(\\d)/g, '$1\\0$2') // letter to number\n .replace(/(\\d)([a-zA-Z])/g, '$1\\0$2') // number to letter\n .split(/[\\0_\\-\\s.]+/)\n .filter((w) => w.length > 0);\n\n return recombineCompounds(words);\n}\n\nexport const ACRONYM_SET = new Set(['SSO', 'FGA', 'SAML', 'SCIM', 'JWT', 'HMAC', 'M2M']);\n\nexport function toPascalCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n return splitWords(s)\n .map((w) => {\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n // Special case: OAuth should stay as OAuth, not OAUTH\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toCamelCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n const words = splitWords(s);\n if (words.length === 0) return '';\n return words\n .map((w, i) => {\n if (i === 0) return w.toLowerCase();\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('_');\n}\n\nexport function toKebabCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('-');\n}\n\nexport function toUpperSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toUpperCase())\n .join('_');\n}\n\nconst BACKEND_SUFFIXES = ['Controller'];\n\nexport function stripBackendSuffixes(name: string): string {\n for (const suffix of BACKEND_SUFFIXES) {\n if (name.endsWith(suffix) && name.length > suffix.length) {\n return name.slice(0, -suffix.length);\n }\n }\n return name;\n}\n\nexport function stripBackendPrefixes(name: string): string {\n return name.replace(/Userland/g, '').replace(/Controller/g, '');\n}\n\n/**\n * Remove ListItem / ByExternalId / ByResourceId / ForResource markers from PascalCase names.\n * E.g. \"DirectoriesListItemState\" → \"DirectoriesState\"\n */\nexport function stripListItemMarkers(name: string): string {\n return name\n .replace(/ListItem/g, '')\n .replace(/ByExternalId/g, '')\n .replace(/ByResourceId/g, '')\n .replace(/ForResource/g, '');\n}\n\n/** Words that look plural but must NOT be singularized. */\nconst SINGULAR_SAFE_LIST = new Set([\n 'Status',\n 'Address',\n 'Access',\n 'Process',\n 'Progress',\n 'Success',\n 'Radius',\n 'Canvas',\n 'Alias',\n 'Basis',\n 'Bus',\n 'Species',\n 'Series',\n]);\n\n/**\n * Conservative singularize for the leading PascalCase word.\n * Only applied to the first word of a PascalCase name (the resource word).\n * - `ies` → `y` (e.g. Directories → Directory)\n * - trailing `s` for words >4 chars (e.g. Organizations → Organization)\n * Safe-listed words are never singularized.\n */\nexport function singularize(word: string): string {\n if (SINGULAR_SAFE_LIST.has(word)) return word;\n if (word.endsWith('ies') && word.length > 4) {\n return word.slice(0, -3) + 'y';\n }\n if (word.endsWith('ses') && word.length > 4) {\n // e.g. \"Processes\" — but \"Process\" is safe-listed, this handles non-safe ones\n return word.slice(0, -2);\n }\n if (word.endsWith('s') && !word.endsWith('ss') && word.length > 4) {\n return word.slice(0, -1);\n }\n return word;\n}\n\n/**\n * Compose all backend name cleaning transforms in order:\n * 1. Strip backend prefixes (Userland, Controller)\n * 2. Strip backend suffixes (Dto, DTO, Controller)\n * 3. Strip ListItem / ByExternalId markers\n * 4. Singularize leading resource word\n *\n * Must be idempotent: `cleanSchemaName(cleanSchemaName(x)) === cleanSchemaName(x)`\n */\n/** Strip `.js` extensions from import/export specifiers for dedup comparison. */\nexport function normalizeJsExtension(text: string): string {\n return text.replace(/\\.js(['\"])/g, '$1');\n}\n\nexport function cleanSchemaName(name: string): string {\n let result = stripBackendPrefixes(stripBackendSuffixes(name));\n result = stripListItemMarkers(result);\n\n // Singularize the leading PascalCase word\n const match = result.match(/^([A-Z][a-z]*)/);\n if (match) {\n const leadWord = match[1];\n const singular = singularize(leadWord);\n if (singular !== leadWord) {\n result = singular + result.slice(leadWord.length);\n }\n }\n\n return result;\n}\n","/**\n * SDK Behavior IR — language-agnostic runtime policies for generated SDKs.\n *\n * These types capture the \"what\" of SDK behavior (retry, telemetry, errors, etc.)\n * while emitters provide the \"how\" (language-specific mechanism).\n *\n * Emitters access these via `ctx.spec.sdk` — always populated, never undefined.\n */\n\n// ── Retry ──────────────────────────────────────────────────────────\n\n/** Retry policy — when and how to retry failed requests. */\nexport interface RetryPolicy {\n /** HTTP status codes that trigger a retry. */\n retryableStatusCodes: number[];\n /** Maximum number of retry attempts (0 = no retries). */\n maxRetries: number;\n /** Whether to retry on connection errors (DNS failure, TCP reset). */\n retryOnConnectionError: boolean;\n /** Whether to retry on timeout errors. */\n retryOnTimeout: boolean;\n /** Backoff strategy between retries. */\n backoff: BackoffStrategy;\n}\n\n/** Exponential backoff configuration.\n *\n * Formula: `delay = min(initialDelay * multiplier^attempt, maxDelay)`\n * With jitter: `delay += delay * jitterFactor * random(0, 1)`\n */\nexport interface BackoffStrategy {\n /** Initial delay in seconds before the first retry. */\n initialDelay: number;\n /** Multiplier applied to the delay on each subsequent retry. */\n multiplier: number;\n /** Maximum delay in seconds (cap). */\n maxDelay: number;\n /** Jitter factor (0..1). 0.5 means up to 50% random jitter added. */\n jitterFactor: number;\n}\n\n// ── Errors ─────────────────────────────────────────────────────────\n\n/** Error mapping — status codes to named exception kinds. */\nexport interface ErrorPolicy {\n /** Map from HTTP status code to a logical error kind name (e.g. 400 → 'BadRequest').\n * Emitters append language-specific suffixes (e.g. 'BadRequestException'). */\n statusCodeMap: Record<number, string>;\n /** Catch-all error kind for 5xx status codes not in the map. */\n serverErrorKind: string;\n /** Catch-all error kind for unrecognized status codes. */\n clientErrorKind: string;\n /** URL template for error documentation. Use {code} as placeholder for the API error code. */\n errorDocUrlTemplate?: string;\n}\n\n// ── Telemetry ──────────────────────────────────────────────────────\n\n/** Telemetry — what request metrics to track and send. */\nexport interface TelemetryPolicy {\n /** Whether telemetry is enabled by default. Users can opt out via constructor param. */\n enabledByDefault: boolean;\n /** Header name for client telemetry data (previous request's ID + latency). */\n headerName: string;\n /** Response header name for the request ID. */\n requestIdHeader: string;\n}\n\n// ── Pagination ─────────────────────────────────────────────────────\n\n/** Pagination behavior defaults. */\nexport interface PaginationPolicy {\n /** Delay in milliseconds between pages during auto-pagination. 0 = no delay. */\n autoPageDelayMs: number;\n}\n\n// ── Idempotency ────────────────────────────────────────────────────\n\n/** Idempotency auto-generation rules. */\nexport interface IdempotencyPolicy {\n /** Header name for the idempotency key. */\n headerName: string;\n /** Whether to auto-generate a UUID v4 idempotency key for POST requests when retries > 0. */\n autoGenerateForPost: boolean;\n}\n\n// ── Logging ────────────────────────────────────────────────────────\n\n/** Logging contract — what to log at which level. */\nexport interface LoggingPolicy {\n /** Whether structured logging hooks are generated. */\n enabled: boolean;\n /** Log events that the generated client emits. */\n events: LogEvent[];\n}\n\n/** A discrete loggable event in the request lifecycle. */\nexport type LogEvent =\n | 'request.start'\n | 'request.success'\n | 'request.retry'\n | 'request.rate_limited'\n | 'request.error'\n | 'request.connection_error';\n\n// ── User-Agent ─────────────────────────────────────────────────────\n\n/** User-Agent construction rules. */\nexport interface UserAgentPolicy {\n /** Template for the SDK identifier string.\n * Placeholders: {name} = spec name, {lang} = emitter language, {version} = SDK version.\n * Each emitter interpolates with its own language string and casing conventions.\n * Example: '{name} {lang}/{version}' → 'Acme PHP/4.32.0' */\n sdkIdentifierTemplate: string;\n /** Whether to append the runtime/language version (e.g. PHP 8.2, Python 3.12). */\n includeRuntimeVersion: boolean;\n /** Whether to allow app info enrichment via setAppInfo(name, version, url). */\n allowAppInfo: boolean;\n /** AI agent environment variable detection entries. */\n aiAgentEnvVars: AiAgentEnvVar[];\n}\n\n/** Maps an environment variable to an AI agent slug for User-Agent enrichment. */\nexport interface AiAgentEnvVar {\n /** Environment variable to check (e.g. 'CLAUDE_CODE'). */\n envVar: string;\n /** Agent name to append to User-Agent (e.g. 'ClaudeCode'). */\n agentName: string;\n}\n\n// ── Request Guards ─────────────────────────────────────────────────\n\n/** Guards that validate request params before sending. */\nexport interface RequestGuardPolicy {\n /** Keys that should be in RequestOptions, not in params.\n * If detected in the body or query params, the SDK throws an error. */\n optionKeys: string[];\n}\n\n// ── Timeouts ───────────────────────────────────────────────────────\n\n/** Timeout configuration. */\nexport interface TimeoutPolicy {\n /** Default HTTP request timeout in seconds. */\n defaultTimeoutSeconds: number;\n /** Environment variable name to override the timeout (e.g. 'SDK_REQUEST_TIMEOUT'). */\n timeoutEnvVar?: string;\n}\n\n// ── Root ───────────────────────────────────────────────────────────\n\n/** Language-agnostic runtime policies for generated SDKs.\n * Attached to `ApiSpec.sdk` and consumed by emitters via `ctx.spec.sdk`. */\nexport interface SdkBehavior {\n retry: RetryPolicy;\n errors: ErrorPolicy;\n telemetry: TelemetryPolicy;\n pagination: PaginationPolicy;\n idempotency: IdempotencyPolicy;\n logging: LoggingPolicy;\n userAgent: UserAgentPolicy;\n requestGuard: RequestGuardPolicy;\n timeout: TimeoutPolicy;\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\n/**\n * Canonical SDK behavior defaults. Per-language or per-project overrides can\n * be applied via `mergeSdkBehavior()` in each SDK's `oagen.config.ts`.\n *\n * - Retry: exponential backoff with jitter, retries on 429/5xx\n * - Errors: standard HTTP status → exception kind mapping\n * - Telemetry: enabled by default, tracks request ID + latency\n * - Pagination: no inter-page delay (Node overrides to 350ms)\n * - Idempotency: auto-generate UUID v4 for retryable POSTs\n * - Logging: all lifecycle events enabled\n * - User-Agent: SDK identifier + runtime version + app info + AI agent detection\n * - Request guards: detect misplaced RequestOptions keys in params\n * - Timeout: 60s default (Python overrides to 30s)\n */\nexport function defaultSdkBehavior(): SdkBehavior {\n return {\n retry: {\n retryableStatusCodes: [429, 500, 502, 503, 504],\n maxRetries: 3,\n retryOnConnectionError: true,\n retryOnTimeout: true,\n backoff: {\n initialDelay: 1.0,\n multiplier: 2.0,\n maxDelay: 30.0,\n jitterFactor: 0.5,\n },\n },\n errors: {\n statusCodeMap: {\n 400: 'BadRequest',\n 401: 'Authentication',\n 403: 'Authorization',\n 404: 'NotFound',\n 409: 'Conflict',\n 422: 'UnprocessableEntity',\n 429: 'RateLimitExceeded',\n },\n serverErrorKind: 'Server',\n clientErrorKind: 'Api',\n },\n telemetry: {\n enabledByDefault: true,\n headerName: 'X-Client-Telemetry',\n requestIdHeader: 'X-Request-ID',\n },\n pagination: {\n autoPageDelayMs: 0,\n },\n idempotency: {\n headerName: 'Idempotency-Key',\n autoGenerateForPost: true,\n },\n logging: {\n enabled: true,\n events: [\n 'request.start',\n 'request.success',\n 'request.retry',\n 'request.rate_limited',\n 'request.error',\n 'request.connection_error',\n ],\n },\n userAgent: {\n sdkIdentifierTemplate: '{name} {lang}/{version}',\n includeRuntimeVersion: true,\n allowAppInfo: true,\n aiAgentEnvVars: [\n { envVar: 'CLAUDE_CODE', agentName: 'ClaudeCode' },\n { envVar: 'CURSOR_AGENT', agentName: 'Cursor' },\n { envVar: 'CLINE_ACTIVE', agentName: 'Cline' },\n { envVar: 'WINDSURF_ACTIVE', agentName: 'Windsurf' },\n { envVar: 'COPILOT_AGENT', agentName: 'Copilot' },\n ],\n },\n requestGuard: {\n optionKeys: [\n 'api_key',\n 'apiKey',\n 'idempotency_key',\n 'idempotencyKey',\n 'extra_headers',\n 'extraHeaders',\n 'max_retries',\n 'maxRetries',\n 'base_url',\n 'baseUrl',\n ],\n },\n timeout: {\n defaultTimeoutSeconds: 60,\n },\n };\n}\n\n// ── Merge ──────────────────────────────────────────────────────────\n\n/** Recursive partial type for deep overrides. */\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends (infer U)[]\n ? U[] // Arrays replace entirely (don't concat)\n : T[K] extends object\n ? DeepPartial<T[K]>\n : T[K];\n};\n\n/**\n * Deep-merge partial overrides into the canonical defaults.\n * Arrays replace entirely (so `retryableStatusCodes: [429]` replaces the full list,\n * rather than appending). Object properties are merged recursively.\n */\nexport function mergeSdkBehavior(overrides: DeepPartial<SdkBehavior>): SdkBehavior {\n return deepMerge(\n defaultSdkBehavior() as unknown as Record<string, unknown>,\n overrides as unknown as Record<string, unknown>,\n ) as unknown as SdkBehavior;\n}\n\n/**\n * Self-contained deep merge (no external imports — ir/ is layer 0).\n * Arrays and primitives from `source` replace those in `target`.\n * Objects are merged recursively.\n */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (sourceVal === undefined) continue;\n if (\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n targetVal !== null &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal as Record<string, unknown>, sourceVal as Record<string, unknown>);\n } else {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n","/**\n * Structured error hierarchy for oagen.\n *\n * Every error carries a human-readable `hint` that suggests a recovery action.\n * The hint is appended to the `message` so it appears in stack traces and logs.\n */\n\n/** Base class for all oagen errors. */\nexport class OagenError extends Error {\n readonly hint: string;\n\n constructor(message: string, hint: string) {\n const fullMessage = hint ? `${message}\\nHint: ${hint}` : message;\n super(fullMessage);\n this.name = 'OagenError';\n this.hint = hint;\n }\n}\n\n/** Thrown when a command should terminate with a specific exit code. */\nexport class CommandError extends OagenError {\n readonly exitCode: number;\n\n constructor(message: string, hint: string, exitCode: number) {\n super(message, hint);\n this.name = 'CommandError';\n this.exitCode = exitCode;\n }\n}\n\n/** Thrown when an OpenAPI spec cannot be parsed or has an unsupported version. */\nexport class SpecParseError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'SpecParseError';\n }\n}\n\n/** Thrown when configuration files (manifests, API surfaces, overlays) are missing or malformed. */\nexport class ConfigError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigError';\n }\n}\n\n/** Thrown when a config file exists but cannot be loaded or evaluated. */\nexport class ConfigLoadError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigLoadError';\n }\n}\n\n/** Thrown when a config targets a different IR version than the installed package. */\nexport class ConfigVersionMismatchError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigVersionMismatchError';\n }\n}\n\n/** Thrown when an API surface extractor encounters a problem. */\nexport class ExtractorError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ExtractorError';\n }\n}\n\n/** Thrown when a requested language or extractor is not found in a registry. */\nexport class RegistryError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'RegistryError';\n }\n}\n\n/** Thrown for internal invariant violations that indicate a bug. */\nexport class InternalError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'InternalError';\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { makeDocumentFromString, bundleDocument, createConfig, BaseResolver, Oas3_1Types } from '@redocly/openapi-core';\nimport { SpecParseError } from '../errors.js';\n\nexport interface BundledSpec {\n parsed: Record<string, unknown>;\n specPath: string;\n}\n\nexport async function loadAndBundleSpec(specPath: string): Promise<BundledSpec> {\n const absolutePath = resolve(specPath);\n const content = await readFile(absolutePath, 'utf-8');\n const document = makeDocumentFromString(content, pathToFileURL(absolutePath).href);\n\n const config = await createConfig({});\n const resolver = new BaseResolver();\n\n const result = await bundleDocument({\n document,\n config,\n types: Oas3_1Types,\n externalRefResolver: resolver,\n dereference: false,\n });\n\n if (result.problems.some((p) => p.severity === 'error')) {\n const errors = result.problems\n .filter((p) => p.severity === 'error')\n .map((p) => p.message)\n .join('\\n');\n throw new SpecParseError(\n `Failed to parse spec: ${errors}`,\n `Check the OpenAPI spec at \"${absolutePath}\" for syntax errors. Run a linter such as \\`npx @redocly/cli lint ${specPath}\\` to identify issues.`,\n );\n }\n\n return {\n parsed: result.bundle.parsed as Record<string, unknown>,\n specPath: absolutePath,\n };\n}\n","import type { SdkBehavior } from './sdk-behavior.js';\n\n/** Authentication scheme extracted from OpenAPI securitySchemes */\nexport type AuthScheme =\n | { kind: 'bearer' }\n | { kind: 'apiKey'; in: 'header' | 'query' | 'cookie'; name: string }\n | { kind: 'oauth2'; flows: Record<string, unknown> };\n\n/** Root IR node representing the full API surface */\n/** A server entry from the OpenAPI servers array */\nexport interface ServerEntry {\n url: string;\n description?: string;\n}\n\n/** Root IR node representing the full API surface */\nexport interface ApiSpec {\n name: string;\n version: string;\n description?: string;\n baseUrl: string;\n servers?: ServerEntry[];\n services: Service[];\n models: Model[];\n enums: Enum[];\n auth?: AuthScheme[];\n /** Language-agnostic runtime policies (retry, errors, telemetry, etc.). */\n sdk: SdkBehavior;\n}\n\n/** A service groups related operations (maps to an SDK resource class) */\nexport interface Service {\n name: string;\n description?: string;\n operations: Operation[];\n}\n\n/** A single API operation (maps to an SDK method) */\n/** Per-operation security requirement: scheme name → scope list. */\nexport interface SecurityRequirement {\n schemeName: string;\n scopes: string[];\n}\n\nexport interface Operation {\n name: string;\n description?: string;\n httpMethod: HttpMethod;\n path: string;\n pathParams: Parameter[];\n queryParams: Parameter[];\n /**\n * Query parameters the spec also declares as request-body properties on a\n * body-carrying method (POST/PUT/PATCH). They travel in the body only, so\n * they are excluded from `queryParams`; they are kept here so inline enums\n * they declare stay reachable and the compat surface still sees them.\n * Emitters never serialize these to the URL.\n */\n bodyOwnedQueryParams?: Parameter[];\n headerParams: Parameter[];\n cookieParams?: Parameter[];\n requestBody?: TypeRef;\n requestBodyEncoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n response: TypeRef;\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n pagination?: PaginationMeta;\n injectIdempotencyKey: boolean;\n deprecated?: boolean;\n async?: boolean;\n /** Per-operation security overrides. When present, overrides the global spec-level security. */\n security?: SecurityRequirement[];\n /**\n * Mutually-exclusive parameter groups parsed from `x-mutually-exclusive-parameter-groups`.\n * Each group represents a logical choice the caller must (or may) make between\n * several subsets of query/path/header parameters. The grouped parameters remain\n * in their original arrays (queryParams, pathParams, etc.) for wire-format purposes;\n * this field adds the grouping metadata so emitters can render sum types.\n */\n parameterGroups?: ParameterGroup[];\n}\n\n/**\n * A mutually-exclusive parameter group. The caller must supply exactly one\n * variant (when `optional` is false) or may omit the group entirely (when true).\n */\nexport interface ParameterGroup {\n /** Group name from the extension (e.g. \"parent_resource\"). */\n name: string;\n /** True when the whole group may be omitted. */\n optional: boolean;\n /** Ordered variants (insertion order matches the spec). */\n variants: ParameterGroupVariant[];\n /**\n * Base name emitters must use for this group's generated wrapper type, in\n * place of `name`.\n *\n * Two operations commonly share one group name — create and update both\n * declare `protocol_options` — and emitters name the wrapper from the group\n * name alone, so both operations collapse onto one type. That is correct\n * only while their members agree. When they disagree (create's\n * `saml_options` is a `CreateConnectionSAMLOptions`, update's is a\n * `PatchConnectionSAMLOptions`) one wrapper silently forces one operation to\n * use the other operation's type.\n *\n * The parser therefore fingerprints each group's members across every\n * operation declaring it and qualifies this with the operation name\n * (`update_connection_protocol_options`) only where they genuinely diverge.\n * Groups that agree — including ones differing only by nullability, or by\n * duplicate inline enums carrying identical values — keep the bare group\n * name, so already-published wrapper types are never renamed.\n */\n wrapperName?: string;\n}\n\n/**\n * One variant within a mutually-exclusive parameter group.\n */\nexport interface ParameterGroupVariant {\n /** Variant name from the extension (e.g. \"by_id\", \"by_external_id\"). */\n name: string;\n /**\n * References to the actual parameter IR nodes. These are the same\n * objects that live in operation.queryParams / .pathParams / .headerParams --\n * shared by identity, not duplicated.\n */\n parameters: Parameter[];\n /**\n * Names of parameters that may be omitted when this variant is used —\n * optional modifiers of the variant's required fields, from the\n * extension's `optionalFields`. Absent means every parameter in the\n * variant is required with it.\n */\n optionalParameters?: string[];\n}\n\n/** Structured pagination metadata for auto-paging iterator generation */\nexport interface PaginationMeta {\n strategy: 'cursor' | 'offset' | 'link-header';\n param: string;\n limitParam?: string;\n dataPath?: string;\n itemType: TypeRef;\n}\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\nexport interface Parameter {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n style?: 'form' | 'simple' | 'label' | 'matrix';\n explode?: boolean;\n}\n\n/** Type reference — the core type system of the IR */\nexport type TypeRef = PrimitiveType | ArrayType | ModelRef | EnumRef | UnionType | NullableType | LiteralType | MapType;\n\nexport interface PrimitiveType {\n kind: 'primitive';\n type: 'string' | 'integer' | 'number' | 'boolean' | 'unknown';\n format?: string;\n}\n\nexport interface ArrayType {\n kind: 'array';\n items: TypeRef;\n}\n\nexport interface ModelRef {\n kind: 'model';\n name: string;\n}\n\nexport interface EnumRef {\n kind: 'enum';\n name: string;\n values?: (string | number)[];\n}\n\nexport interface LiteralType {\n kind: 'literal';\n value: string | number | boolean | null;\n}\n\nexport interface UnionType {\n kind: 'union';\n variants: TypeRef[];\n discriminator?: { property: string; mapping: Record<string, string> };\n /** Which OAS composition keyword produced this union. Emitters can use this to\n * distinguish inheritance (allOf) from exclusive union (oneOf) from open union (anyOf). */\n compositionKind?: 'allOf' | 'oneOf' | 'anyOf';\n}\n\nexport interface NullableType {\n kind: 'nullable';\n inner: TypeRef;\n}\n\nexport interface MapType {\n kind: 'map';\n valueType: TypeRef;\n keyType?: TypeRef;\n}\n\n/**\n * A generic type parameter on a model.\n * Example: `DirectoryUser<TCustomAttributes = Record<string, unknown>>`\n * → `{ name: 'TCustomAttributes', default: { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } } }`\n */\nexport interface TypeParam {\n name: string;\n /** Default type when the param is not specified. */\n default?: TypeRef;\n}\n\n/** Model definition (maps to an SDK model/data class) */\nexport interface Model {\n name: string;\n description?: string;\n fields: Field[];\n /** Generic type parameters. Empty/undefined for non-generic models. */\n typeParams?: TypeParam[];\n /**\n * When set, this model is a discriminated union over allOf+oneOf variants.\n * Emitters should generate a dispatcher (factory) instead of a regular dataclass.\n * The `property` field is the discriminator key (e.g. \"event\"), and `mapping`\n * maps each discriminator value to the concrete variant model name.\n */\n discriminator?: {\n property: string;\n mapping: Record<string, string>;\n };\n}\n\nexport interface Field {\n name: string;\n /**\n * Optional domain-facing name override. When set, emitters derive the\n * domain-side identifier (in their own casing) from this instead of `name`,\n * while serialization still uses `name` for the wire key. Lets an SDK expose\n * a wire field under a friendlier name (e.g. `connection_type` → `type`)\n * without changing the API contract. Set via the `fieldHints` config and\n * honored by any emitter that reads it.\n */\n domainName?: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n readOnly?: boolean;\n writeOnly?: boolean;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n}\n\n/** Enum definition */\nexport interface Enum {\n name: string;\n values: EnumValue[];\n /** Spec-level default value (the value of `default:` on the schema). Optional. */\n default?: string | number;\n}\n\nexport interface EnumValue {\n name: string;\n value: string | number;\n description?: string;\n deprecated?: boolean;\n}\n\n/**\n * Exhaustive check helper for TypeRef switches.\n * If a new kind is added to TypeRef, any switch that doesn't handle it\n * will fail to compile because `never` won't accept the unhandled variant.\n *\n * Usage:\n * switch (ref.kind) {\n * case 'primitive': ...\n * case 'array': ...\n * // If you forget 'literal', TypeScript errors here:\n * default: assertNever(ref);\n * }\n */\nexport function assertNever(x: never): never {\n // Inline to avoid importing from ../errors.js (ir/ is layer 0, must not import upward)\n const kind = (x as TypeRef).kind;\n const err = new Error(\n `Unexpected TypeRef kind: ${kind}\\nHint: If you added a new TypeRef variant, handle it in every switch/case that calls assertNever.`,\n );\n err.name = 'InternalError';\n throw err;\n}\n\n/**\n * Generic depth-first walker for TypeRef trees.\n * Handles recursion into array/nullable/union/map children and provides\n * an exhaustive `assertNever` check so callers don't need to repeat the\n * switch boilerplate. Supply callbacks only for the leaf kinds you care about.\n */\nexport function walkTypeRef(\n ref: TypeRef,\n visitor: {\n model?: (ref: ModelRef) => void;\n enum?: (ref: EnumRef) => void;\n primitive?: (ref: PrimitiveType) => void;\n literal?: (ref: LiteralType) => void;\n },\n): void {\n switch (ref.kind) {\n case 'model':\n visitor.model?.(ref);\n break;\n case 'enum':\n visitor.enum?.(ref);\n break;\n case 'array':\n walkTypeRef(ref.items, visitor);\n break;\n case 'nullable':\n walkTypeRef(ref.inner, visitor);\n break;\n case 'union':\n for (const v of ref.variants) walkTypeRef(v, visitor);\n break;\n case 'map':\n if (ref.keyType) walkTypeRef(ref.keyType, visitor);\n walkTypeRef(ref.valueType, visitor);\n break;\n case 'literal':\n visitor.literal?.(ref);\n break;\n case 'primitive':\n visitor.primitive?.(ref);\n break;\n default:\n assertNever(ref);\n }\n}\n\n/**\n * Generic depth-first mapper for TypeRef trees.\n * Like walkTypeRef but returns a transformed value instead of void.\n * Handles recursion into array/nullable/union/map children, passing\n * already-mapped child values to the parent callback.\n */\nexport function mapTypeRef<T>(\n ref: TypeRef,\n mapper: {\n primitive: (ref: PrimitiveType) => T;\n array: (ref: ArrayType, mappedItems: T) => T;\n model: (ref: ModelRef) => T;\n enum: (ref: EnumRef) => T;\n union: (ref: UnionType, mappedVariants: T[]) => T;\n nullable: (ref: NullableType, mappedInner: T) => T;\n literal: (ref: LiteralType) => T;\n map: (ref: MapType, mappedValue: T, mappedKey?: T) => T;\n },\n): T {\n switch (ref.kind) {\n case 'primitive':\n return mapper.primitive(ref);\n case 'array':\n return mapper.array(ref, mapTypeRef(ref.items, mapper));\n case 'model':\n return mapper.model(ref);\n case 'enum':\n return mapper.enum(ref);\n case 'union':\n return mapper.union(\n ref,\n ref.variants.map((v) => mapTypeRef(v, mapper)),\n );\n case 'nullable':\n return mapper.nullable(ref, mapTypeRef(ref.inner, mapper));\n case 'literal':\n return mapper.literal(ref);\n case 'map':\n return mapper.map(\n ref,\n mapTypeRef(ref.valueType, mapper),\n ref.keyType ? mapTypeRef(ref.keyType, mapper) : undefined,\n );\n default:\n return assertNever(ref);\n }\n}\n\n// --- IR traversal utilities ---\n\n/**\n * Collect all model names referenced (directly or transitively) by a TypeRef.\n */\nexport function collectModelRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { model: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all enum names referenced by a TypeRef.\n */\nexport function collectEnumRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { enum: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all TypeRef-referenced model and enum names from a model's fields.\n * Returns { models, enums } sets for generating import statements.\n */\nexport function collectFieldDependencies(model: Model): {\n models: Set<string>;\n enums: Set<string>;\n} {\n const models = new Set<string>();\n const enums = new Set<string>();\n\n for (const field of model.fields) {\n for (const name of collectModelRefs(field.type)) {\n if (name !== model.name) models.add(name);\n }\n for (const name of collectEnumRefs(field.type)) {\n enums.add(name);\n }\n }\n\n return { models, enums };\n}\n\n/**\n * Assign each model to the service that first references it.\n * Models referenced by multiple services are assigned to the first.\n * Models not referenced by any service are unassigned (absent from the map).\n *\n * @param hints - Optional pin overrides keyed by IR model name → IR service\n * name. Applied after the natural assignment loop. A hint only pins a model\n * present in THIS `models` slice; the target service is resolved by name\n * downstream, so a hint pointing at a service outside `services` still lands\n * the model in the right directory. Callers may pass a PARTIAL slice (e.g.\n * discriminated-union planning, per-service barrels, or a `--services`-scoped\n * run), so this function never rejects a hint — typo validation lives in\n * {@link validateModelHints}, which runs once against the full spec.\n */\nexport function assignModelsToServices(\n models: Model[],\n services: Service[],\n hints?: Record<string, string>,\n): Map<string, string> {\n const modelToService = new Map<string, string>();\n const modelNames = new Set(models.map((m) => m.name));\n\n for (const service of services) {\n const referencedModels = new Set<string>();\n\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n referencedModels.add(name);\n }\n }\n for (const name of collectModelRefs(op.response)) {\n referencedModels.add(name);\n }\n for (const param of [\n ...op.pathParams,\n ...op.queryParams,\n ...(op.bodyOwnedQueryParams ?? []),\n ...op.headerParams,\n ...(op.cookieParams ?? []),\n ]) {\n for (const name of collectModelRefs(param.type)) {\n referencedModels.add(name);\n }\n }\n if (op.pagination) {\n for (const name of collectModelRefs(op.pagination.itemType)) {\n referencedModels.add(name);\n }\n }\n }\n\n // Transitively collect models referenced by the directly-referenced models\n const toVisit = [...referencedModels];\n while (toVisit.length > 0) {\n const name = toVisit.pop()!;\n const model = models.find((m) => m.name === name);\n if (!model) continue;\n for (const field of model.fields) {\n for (const ref of collectModelRefs(field.type)) {\n if (!referencedModels.has(ref) && modelNames.has(ref)) {\n referencedModels.add(ref);\n toVisit.push(ref);\n }\n }\n }\n }\n\n for (const name of referencedModels) {\n if (!modelToService.has(name)) {\n modelToService.set(name, service.name);\n }\n }\n }\n\n if (hints) {\n for (const [modelName, serviceName] of Object.entries(hints)) {\n // Only pin models present in THIS slice; an out-of-slice hint is applied\n // where its own slice is processed. The target service resolves by name\n // downstream, so it need not appear in this slice's `services`. Genuine\n // typos are caught up front by validateModelHints against the full spec.\n if (!modelNames.has(modelName)) continue;\n modelToService.set(modelName, serviceName);\n }\n }\n\n return modelToService;\n}\n\n/**\n * Validate model-placement hints against the FULL spec. Run once at the start of\n * generation — where the complete model/service universe is known — so typos in\n * `modelHints` fail loud even though {@link assignModelsToServices} is\n * intentionally lenient about the partial slices it may be handed.\n */\nexport function validateModelHints(models: Model[], services: Service[], hints: Record<string, string>): void {\n const modelNames = new Set(models.map((m) => m.name));\n const serviceNames = new Set(services.map((s) => s.name));\n for (const [modelName, serviceName] of Object.entries(hints)) {\n if (!modelNames.has(modelName)) {\n const err = new Error(\n `modelHints: unknown model \"${modelName}\". Hint keys must match an IR model name (post-cleanSchemaName/schemaNameTransform).`,\n );\n err.name = 'ConfigError';\n throw err;\n }\n if (!serviceNames.has(serviceName)) {\n const err = new Error(\n `modelHints: unknown service \"${serviceName}\" for model \"${modelName}\". Hint values must match an IR service name (PascalCase, derived from the operation's first tag).`,\n );\n err.name = 'ConfigError';\n throw err;\n }\n }\n}\n\n/**\n * Collect all model names referenced as request bodies across all services.\n */\nexport function collectRequestBodyModels(services: Service[]): Set<string> {\n const result = new Set<string>();\n for (const service of services) {\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n result.add(name);\n }\n }\n }\n }\n return result;\n}\n\nexport interface ErrorResponse {\n statusCode: number;\n type?: TypeRef;\n}\n\n/** A successful response entry from a 2xx status code */\nexport interface SuccessResponse {\n statusCode: number;\n type: TypeRef;\n}\n","import type { Model, Field } from '../ir/types.js';\nimport { toPascalCase, stripListItemMarkers, singularize } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { buildFieldFromSchema, resolveSchemaName } from './schemas.js';\n\n/**\n * Qualify an inline model name with the parent schema name.\n * If `parentName` is provided and the field name doesn't already start with\n * the parent, the result is `${parentName}${PascalField}` with the trailing\n * word singularized (e.g., Connection + Domains → ConnectionDomain).\n */\nexport function qualifyInlineModelName(baseName: string, parentName?: string): string {\n if (!parentName) return baseName;\n // Strip ListItem/ByExternalId markers from parent name so inline model names\n // are clean and match the names produced by qualifyNestedName() in responses.ts.\n // e.g., ConnectionListItem + Domains → Connection + Domain = ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n if (baseName.startsWith(cleanParent)) return baseName;\n // Singularize the trailing PascalCase word of the combined name.\n // Split baseName into leading words + trailing word, singularize trailing.\n const trailingMatch = baseName.match(/^(.*?)([A-Z][a-z]*)$/);\n if (trailingMatch) {\n const [, prefix, trailingWord] = trailingMatch;\n const singular = singularize(trailingWord);\n return `${cleanParent}${prefix}${singular}`;\n }\n return `${cleanParent}${baseName}`;\n}\n\n/**\n * Walk all component schemas and extract inline Model definitions for fields\n * that are objects with properties (or arrays of such objects).\n * These correspond to the ModelRef entries created by schemaToTypeRef.\n */\nexport function extractInlineModelsFromSchemas(schemas: Record<string, SchemaObject> | undefined): Model[] {\n if (!schemas) return [];\n\n const inlineModels: Model[] = [];\n\n for (const [schemaName, schema] of Object.entries(schemas)) {\n const parentName = resolveSchemaName(schemaName);\n extractInlineModelsFromProperties(schema, inlineModels, parentName);\n }\n\n return inlineModels;\n}\n\nexport function extractInlineModelsFromProperties(schema: SchemaObject, results: Model[], parentName?: string): void {\n const properties = schema.properties ?? {};\n const allOfSchemas = schema.allOf ?? [];\n\n for (const sub of allOfSchemas) {\n if (sub.properties) {\n extractInlineModelsFromProperties(sub, results, parentName);\n }\n }\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n // Direct inline object with properties (with or without explicit type: 'object')\n if (fieldSchema.properties && (fieldSchema.type === 'object' || !fieldSchema.type)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, fieldSchema));\n extractInlineModelsFromProperties(fieldSchema, results, modelName);\n }\n\n // Array of inline objects\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const items = fieldSchema.items;\n if (items.properties && (items.type === 'object' || !items.type)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, items));\n extractInlineModelsFromProperties(items, results, modelName);\n }\n }\n\n // Inline object expressed via `allOf` (no $ref / oneOf / anyOf members).\n // schemaToTypeRef collapses such a field into a single merged model ref, so\n // materialize that model — otherwise the ref dangles exactly like a direct\n // inline object would. An `allOf` containing a `$ref` is the augmentation\n // case resolved through the ref path and is intentionally left alone here.\n if (fieldSchema.allOf && fieldSchema.allOf.every((s) => !s.$ref && !s.oneOf && !s.anyOf)) {\n const merged = mergeAllOfObjectSchema(fieldSchema);\n if (Object.keys(merged.properties ?? {}).length > 0) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, merged));\n extractInlineModelsFromProperties(merged, results, modelName);\n }\n }\n\n // oneOf containing objects — extract every inline object variant as a\n // model so each gets its own typed class. Variant 0 keeps the bare\n // qualified inline name (e.g. `ApiKeyCreatedDataOwner`); subsequent\n // variants are prefixed by their const-discriminator value via\n // `nameOneOfVariant` (e.g. `UserApiKeyCreatedDataOwner`). When the\n // oneOf doesn't have a const-discriminator (single object variant + null\n // for nullable, or single object variant only), only variant 0 is\n // extracted and the bare name pattern preserves backward compat.\n if (fieldSchema.oneOf) {\n const inlineObjectVariants = fieldSchema.oneOf.filter(\n (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n );\n if (inlineObjectVariants.length > 0) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n const existingNames = new Set(results.map((r) => r.name));\n const namingDiscProp = deriveOneOfNamingDiscriminator(inlineObjectVariants);\n const emittedNames: string[] = [];\n for (const variant of inlineObjectVariants) {\n const variantName = nameOneOfVariant(variant, modelName, emittedNames, namingDiscProp);\n emittedNames.push(variantName);\n if (!existingNames.has(variantName)) {\n existingNames.add(variantName);\n results.push(buildInlineModel(variantName, variant));\n extractInlineModelsFromProperties(variant, results, variantName);\n }\n }\n }\n }\n }\n}\n\n/** Find a single string-const-valued property shared by every variant whose\n * values are all distinct — the implicit discriminator. Returns null when no\n * such property exists. Mirrors `deriveConstNamingDiscriminator` in schemas.ts. */\nfunction deriveOneOfNamingDiscriminator(variants: SchemaObject[]): string | null {\n if (variants.length < 2) return null;\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n const values = variants.map((v) => readConstString(v.properties?.[propName]));\n if (values.some((v) => v === null)) continue;\n if (new Set(values).size !== values.length) continue;\n return propName;\n }\n return null;\n}\n\nfunction readConstString(prop: SchemaObject | undefined): string | null {\n if (!prop) return null;\n if (typeof prop.const === 'string') return prop.const;\n if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n return prop.enum[0];\n }\n return null;\n}\n\n/** Produce a per-variant model name. Variant 0 keeps the bare parent name;\n * later variants are prefixed by the const-derived label. Mirrors\n * `nameVariantModel` in schemas.ts. Falls back to a numeric suffix when no\n * discriminator is available, the const value PascalCases to nothing, or\n * the derived candidate collides with the parent or an already-emitted name. */\nfunction nameOneOfVariant(\n variant: SchemaObject,\n parentName: string,\n alreadyEmitted: string[],\n discriminatorProperty: string | null,\n): string {\n if (alreadyEmitted.length === 0) return parentName;\n if (discriminatorProperty) {\n const constValue = readConstString(variant.properties?.[discriminatorProperty]);\n if (constValue) {\n const prefix = toPascalCase(constValue);\n if (prefix) {\n const candidate = parentName.startsWith(prefix) ? parentName : `${prefix}${parentName}`;\n const collision = candidate === parentName || alreadyEmitted.includes(candidate);\n if (!collision) return candidate;\n }\n }\n }\n return `${parentName}${alreadyEmitted.length + 1}`;\n}\n\n/**\n * Merge the object members of an `allOf` (recursively) into a single\n * object-shaped schema, so an inline object expressed via `allOf` can be\n * materialized as one model — mirroring how schemaToTypeRef collapses such a\n * field into a single merged model ref. Earlier members win on key conflicts,\n * matching the merge order used elsewhere in the parser.\n */\nfunction mergeAllOfObjectSchema(schema: SchemaObject): SchemaObject {\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const visit = (s: SchemaObject): void => {\n if (s.properties) {\n for (const [key, value] of Object.entries(s.properties)) {\n if (value && !(key in properties)) properties[key] = value;\n }\n }\n if (s.required) required.push(...s.required);\n if (s.allOf) for (const sub of s.allOf) visit(sub);\n };\n visit(schema);\n return { type: 'object', properties, required, description: schema.description };\n}\n\nfunction buildInlineModel(name: string, schema: SchemaObject): Model {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n }\n\n return { name, description: schema.description, fields };\n}\n","import type { Model, Enum, EnumValue, Field, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport {\n toPascalCase,\n toUpperSnakeCase,\n cleanSchemaName,\n singularize,\n stripListItemMarkers,\n splitWords,\n} from '../utils/naming.js';\n\n/**\n * Module-level transform set during extractSchemas(). Used by schemaToTypeRef()\n * to apply the same name transform to $ref model/enum references.\n */\nlet activeSchemaNameTransform: ((name: string) => string) | null = null;\n\n/**\n * Module-level set of resolved schema names whose components/schemas entry is\n * an enum (i.e. has `enum:`). Populated by extractSchemas() so schemaToTypeRef()\n * can classify a `$ref` to a top-level enum schema as `kind: 'enum'` instead of\n * `kind: 'model'`. Without this, every `$ref` was naively returned as a model\n * ref, even when the target was a shared enum like `PaginationOrder`.\n */\nlet activeEnumSchemaNames: Set<string> = new Set();\n\n/** Apply cleanSchemaName + the active transform (if any) to a raw schema name. */\nexport function resolveSchemaName(rawName: string): string {\n let name = cleanSchemaName(toPascalCase(rawName));\n if (activeSchemaNameTransform) name = activeSchemaNameTransform(name);\n return name;\n}\n\nexport interface SchemaExtractionOptions {\n schemaNameTransform?: (name: string) => string;\n}\n\nexport interface SchemaObject {\n type?: string | string[];\n format?: string;\n description?: string;\n properties?: Record<string, SchemaObject | undefined>;\n required?: string[];\n items?: SchemaObject;\n enum?: (string | number)[];\n allOf?: SchemaObject[];\n oneOf?: SchemaObject[];\n anyOf?: SchemaObject[];\n discriminator?: { propertyName: string; mapping?: Record<string, string> };\n readOnly?: boolean;\n writeOnly?: boolean;\n nullable?: boolean;\n $ref?: string;\n additionalProperties?: boolean | SchemaObject;\n const?: unknown;\n patternProperties?: Record<string, SchemaObject>;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n [key: string]: unknown;\n}\n\nexport interface ExtractedSchemas {\n models: Model[];\n enums: Enum[];\n}\n\nexport function extractSchemas(\n schemas: Record<string, SchemaObject> | undefined,\n options?: SchemaExtractionOptions,\n): ExtractedSchemas {\n const enums: Enum[] = [];\n\n if (!schemas) return { models: [], enums };\n\n // Build collision-safe transform if provided\n if (options?.schemaNameTransform) {\n const transform = options.schemaNameTransform;\n const rawNames = Object.keys(schemas);\n const cleanedNames = rawNames.map((n) => cleanSchemaName(toPascalCase(n)));\n const transformedToOriginals = new Map<string, string[]>();\n for (const cleaned of cleanedNames) {\n const transformed = transform(cleaned);\n if (!transformedToOriginals.has(transformed)) transformedToOriginals.set(transformed, []);\n transformedToOriginals.get(transformed)!.push(cleaned);\n }\n const unsafeToTransform = new Set<string>();\n for (const [, originals] of transformedToOriginals) {\n if (originals.length > 1) {\n for (const n of originals) unsafeToTransform.add(n);\n }\n }\n activeSchemaNameTransform = (name: string) => (unsafeToTransform.has(name) ? name : transform(name));\n } else {\n activeSchemaNameTransform = null;\n }\n\n // Pre-compute the set of resolved names whose component schema is an enum so\n // schemaToTypeRef() can classify `$ref` targets correctly. Built in a separate\n // pass because the per-schema loop mutates models/enums and we want this map\n // available before any TypeRef is resolved (operations + nested fields both\n // call schemaToTypeRef during extraction).\n activeEnumSchemaNames = new Set();\n for (const [name, schema] of Object.entries(schemas)) {\n if (schema.enum) activeEnumSchemaNames.add(resolveSchemaName(name));\n }\n\n const modelsByCleanName = new Map<string, Model>();\n\n for (const [name, schema] of Object.entries(schemas)) {\n const pascalName = resolveSchemaName(name);\n\n if (schema.enum) {\n enums.push(extractEnum(pascalName, schema));\n } else {\n const model = extractModel(pascalName, schema, schemas);\n const existing = modelsByCleanName.get(pascalName);\n if (existing) {\n // Keep the model with more fields when names collide after cleaning\n if (model.fields.length > existing.fields.length) {\n modelsByCleanName.set(pascalName, model);\n }\n } else {\n modelsByCleanName.set(pascalName, model);\n }\n\n for (const inlineModel of extractDiscriminatedAllOfVariantModels(schema, pascalName)) {\n const existingInline = modelsByCleanName.get(inlineModel.name);\n if (existingInline) {\n if (inlineModel.fields.length > existingInline.fields.length) {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n } else {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n }\n }\n }\n\n const models = [...modelsByCleanName.values()];\n\n // Collect inline models from nested object/oneOf properties\n // that schemaToTypeRef created model refs for but weren't extracted\n const modelNames = new Set(models.map((m) => m.name));\n const inlineQueue: Model[] = [...models];\n while (inlineQueue.length > 0) {\n const model = inlineQueue.pop()!;\n for (const field of model.fields) {\n collectNestedInlineModels(field.type, field.name, model.name, schemas ?? {}, models, modelNames, inlineQueue);\n }\n }\n\n // Collect inline enums from model fields\n for (const model of models) {\n collectInlineEnums(model.fields, enums);\n }\n\n // NOTE: activeSchemaNameTransform is intentionally NOT cleared here.\n // extractOperations() calls schemaToTypeRef() for $ref resolution and\n // needs the same transform active. parseSpec() calls clearSchemaNameTransform()\n // after all extraction is complete.\n return { models, enums };\n}\n\n/** Clear the module-level schemaNameTransform. Called by parseSpec() after all extraction phases. */\nexport function clearSchemaNameTransform(): void {\n activeSchemaNameTransform = null;\n activeEnumSchemaNames = new Set();\n}\n\n/**\n * Walk a single TypeRef and extract inline enum refs as top-level enum definitions.\n * Shared by both schemas.ts (field-level) and parse.ts (model-level) collection passes.\n */\nexport function collectInlineEnumFromRef(ref: TypeRef, enums: Enum[], seen: Set<string>): void {\n walkTypeRef(ref, {\n enum: (r) => {\n if (r.values && !seen.has(r.name)) {\n seen.add(r.name);\n enums.push({\n name: r.name,\n values: r.values.map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: v,\n description: undefined,\n })),\n });\n }\n },\n });\n}\n\n/**\n * Walk model fields and extract inline enum refs as top-level enum definitions.\n * This ensures type alias files are generated for inline enums.\n */\nfunction collectInlineEnums(fields: Field[], enums: Enum[]): void {\n const seen = new Set(enums.map((e) => e.name));\n for (const field of fields) {\n collectInlineEnumFromRef(field.type, enums, seen);\n }\n}\n\n/**\n * Walk a TypeRef tree and extract inline models for any model refs that point\n * to schemas with inline object properties (not in components/schemas).\n * This handles nested objects like `totp: { oneOf: [{ type: object, properties: {...} }] }`\n * that schemaToTypeRef turns into model refs but aren't extracted from components.\n */\nfunction collectNestedInlineModels(\n ref: TypeRef,\n fieldName: string,\n parentModelName: string,\n schemas: Record<string, SchemaObject>,\n models: Model[],\n modelNames: Set<string>,\n queue: Model[],\n): void {\n walkTypeRef(ref, {\n model: (modelRef) => {\n if (modelNames.has(modelRef.name)) return; // already extracted\n // Check if this model name corresponds to a component schema\n // by checking all possible original names that would map to this PascalCase name\n const isComponent = Object.keys(schemas).some((k) => resolveSchemaName(k) === modelRef.name);\n if (isComponent) return; // will be extracted from components\n\n // This is a reference to a nested inline model that wasn't extracted.\n // Look up the field schema in the parent model's component schema to extract it.\n const parentSchema = findSchemaByName(parentModelName, schemas);\n if (!parentSchema) return;\n\n const fieldSchema = findNestedFieldSchema(fieldName, parentSchema, schemas);\n if (!fieldSchema) return;\n\n // Extract inline models from the field schema\n const extracted = extractNestedSchema(modelRef.name, fieldSchema);\n for (const m of extracted) {\n if (!modelNames.has(m.name)) {\n models.push(m);\n modelNames.add(m.name);\n queue.push(m); // re-scan for deeper nesting\n }\n }\n },\n });\n}\n\n/** Find a component schema by PascalCase name. */\nfunction findSchemaByName(pascalName: string, schemas: Record<string, SchemaObject>): SchemaObject | null {\n for (const [k, v] of Object.entries(schemas)) {\n if (resolveSchemaName(k) === pascalName) return v;\n }\n return null;\n}\n\n/** Walk into a schema to find a field's sub-schema, resolving allOf and oneOf/anyOf. */\nfunction findNestedFieldSchema(\n fieldName: string,\n parentSchema: SchemaObject,\n schemas: Record<string, SchemaObject>,\n): SchemaObject | null {\n if (parentSchema.properties?.[fieldName]) {\n return parentSchema.properties[fieldName]!;\n }\n if (parentSchema.allOf) {\n for (const sub of parentSchema.allOf) {\n let resolved = sub;\n if (sub.$ref) {\n const segments = sub.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n }\n // Also check inside oneOf/anyOf variants (pure oneOf schemas flatten variant\n // properties into the model, so the field may live inside a variant).\n for (const variant of [...(parentSchema.oneOf ?? []), ...(parentSchema.anyOf ?? [])]) {\n let resolved = variant;\n if (variant.$ref) {\n const segments = variant.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n return null;\n}\n\n/** Extract a model (and nested models) from an inline field schema. */\nfunction extractNestedSchema(name: string, schema: SchemaObject): Model[] {\n // Handle oneOf: extract each object variant as its own model\n if (schema.oneOf) {\n const models: Model[] = [];\n\n // Collect the inline object variants up front. When every variant pins\n // the same property to a const value, we can derive meaningful names\n // from the const (e.g. `UserApiKeyOwner` instead of `ApiKeyOwner2`)\n // — much friendlier for SDK consumers than numeric suffixes.\n const inlineObjectVariants: SchemaObject[] = schema.oneOf.filter(\n (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n );\n const constNamingDiscriminator = deriveConstNamingDiscriminator(inlineObjectVariants);\n\n for (const variant of schema.oneOf) {\n if (variant.$ref) continue;\n if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const requiredSet = new Set(variant.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(variant.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n const variantName = nameVariantModel(variant, name, models, constNamingDiscriminator);\n models.push({ name: variantName, description: variant.description, fields });\n }\n }\n return models;\n }\n\n // Handle direct object\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n return [{ name, description: schema.description, fields }];\n }\n\n // Handle array with inline items\n if (schema.type === 'array' && schema.items?.properties) {\n const requiredSet = new Set(schema.items.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.items.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n return [{ name, description: schema.items.description, fields }];\n }\n\n return [];\n}\n\n/**\n * Derive a meaningful name for a oneOf object variant past the first,\n * falling back to the numeric-suffix scheme (`Foo2`, `Foo3`) when no\n * better signal is available. The \"better signal\" is a const-valued\n * discriminator property that distinguishes one variant from the others.\n *\n * For a schema like `ApiKey.owner` whose oneOf has two variants — one\n * with `type: { const: \"organization\" }` and one with `type: { const:\n * \"user\" }` — this returns `ApiKeyOwner` for the first variant (the\n * baseline name that the union TypeRef will reference, so consumer-\n * visible typed fields stay backward-compatible) and `UserApiKeyOwner`\n * for the second instead of `ApiKeyOwner2`. SDK consumers reading the\n * generated types can tell the variants apart at a glance.\n *\n * The first variant always keeps the bare parent name because\n * `schemaToTypeRef` builds union variants whose model refs collapse to\n * `qualifyInlineModelName(field, parent)` — so the first model name\n * must match for the union's degenerate-collapse to land on a valid\n * type. Renaming variant 0 would orphan it.\n *\n * Falls back to numeric suffix when:\n * - The variant has no discriminator property (no shared const\n * property across all object variants), OR\n * - The const value PascalCases to an empty/whitespace name, OR\n * - The derived name collides with the parent name or an already-\n * emitted variant name (numeric keeps uniqueness).\n */\nfunction nameVariantModel(\n variant: SchemaObject,\n parentName: string,\n alreadyEmitted: Model[],\n discriminator: { property: string } | null,\n): string {\n // Variant 0 keeps the bare parent name so the union TypeRef's degenerate\n // collapse target exists in the model registry.\n if (alreadyEmitted.length === 0) return parentName;\n\n if (discriminator) {\n const constValue = getConstPropertyValue(variant, discriminator.property);\n if (constValue) {\n const prefix = toPascalCase(constValue);\n if (prefix) {\n const candidate = parentName.startsWith(prefix) ? parentName : `${prefix}${parentName}`;\n const collision = candidate === parentName || alreadyEmitted.some((m) => m.name === candidate);\n if (!collision) return candidate;\n }\n }\n }\n return `${parentName}${alreadyEmitted.length + 1}`;\n}\n\n/**\n * Returns a discriminator descriptor when every inline object variant in a\n * oneOf has a string-const value on the same property — the signature of a\n * discriminated union without an explicit `discriminator:` keyword. Used by\n * `nameVariantModel` to derive variant names from the const values.\n *\n * Distinct from `detectConstPropertyDiscriminator` (which requires every\n * variant to carry a `$ref` or `title` so a name mapping can be built):\n * this pass operates on inline anonymous variants, where naming is exactly\n * what we're trying to derive.\n */\nfunction deriveConstNamingDiscriminator(variants: SchemaObject[]): { property: string } | null {\n if (variants.length < 2) return null;\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n const values = variants.map((v) => getConstPropertyValue(v, propName));\n if (values.some((v) => v === null)) continue;\n if (new Set(values).size !== values.length) continue; // collisions = no signal\n return { property: propName };\n }\n return null;\n}\n\n/** Build a single Field from a schema property entry. Shared across all extraction sites. */\nexport function buildFieldFromSchema(\n fieldName: string,\n fieldSchema: SchemaObject,\n contextName: string,\n requiredSet: Set<string>,\n): Field {\n return {\n name: fieldName,\n type: schemaToTypeRef(fieldSchema, fieldName, contextName),\n required: requiredSet.has(fieldName),\n description: fieldSchema.description,\n readOnly: fieldSchema.readOnly || undefined,\n writeOnly: fieldSchema.writeOnly || undefined,\n deprecated: fieldSchema.deprecated || undefined,\n default: fieldSchema.default,\n example: fieldSchema.example,\n };\n}\n\n/**\n * If every non-null oneOf/anyOf variant is a string-valued const, return the\n * list of those const values so the union can collapse into a single enum.\n * Returns null when any variant isn't a pure string-const (model ref,\n * number const, nullable, etc.).\n */\nfunction collectLiteralStringConsts(variants: SchemaObject[]): string[] | null {\n if (variants.length === 0) return null;\n const values: string[] = [];\n for (const v of variants) {\n // A single-element enum is semantically identical to const.\n if (typeof v.const === 'string') {\n values.push(v.const);\n continue;\n }\n if (Array.isArray(v.enum) && v.enum.length === 1 && typeof v.enum[0] === 'string') {\n values.push(v.enum[0]);\n continue;\n }\n return null;\n }\n return values;\n}\n\n/** Build an EnumRef the same way the regular enum path does for naming. */\nfunction buildSyntheticEnumRef(\n values: string[],\n contextName: string | undefined,\n parentModelName: string | undefined,\n): TypeRef {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n // Run the same `schemaNameTransform` we apply to component-schema names so\n // a project-level rename map (e.g. `RadarAction` → `RadarListAction` in\n // `oagen.config.ts`) catches inline parameter enums too.\n const finalName = activeSchemaNameTransform ? activeSchemaNameTransform(qualifiedName) : qualifiedName;\n return { kind: 'enum', name: finalName, values };\n}\n\n/**\n * Detect an implicit discriminator on an oneOf where every variant is an\n * object schema that pins the same property to a const value. Returns\n * { property, mapping } so the IR can represent the union as discriminated\n * without needing an explicit `discriminator:` key in the spec.\n *\n * Both shapes are supported:\n * { properties: { event: { const: \"x\" } }, required: [\"event\"] }\n * { properties: { event: { type: \"string\", enum: [\"x\"] } } }\n *\n * Returns null when any variant doesn't fit the pattern or when variants\n * disagree on which property carries the discriminator.\n */\nfunction detectConstPropertyDiscriminator(\n variants: SchemaObject[],\n): { property: string; mapping: Record<string, string> } | null {\n if (variants.length < 2) return null;\n\n // Find properties whose const value is present on every variant.\n let candidateProperty: string | null = null;\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n if (variants.every((v) => getConstPropertyValue(v, propName) !== null)) {\n candidateProperty = propName;\n break;\n }\n }\n\n if (!candidateProperty) return null;\n\n const mapping: Record<string, string> = {};\n for (const v of variants) {\n const value = getConstPropertyValue(v, candidateProperty);\n if (value === null) return null;\n // Require a $ref or title so we have a concrete model name to map to.\n const variantName = resolveVariantModelName(v);\n if (!variantName) return null;\n mapping[value] = variantName;\n }\n\n return { property: candidateProperty, mapping };\n}\n\nfunction getConstPropertyValue(schema: SchemaObject, property: string): string | null {\n const prop = schema.properties?.[property];\n if (!prop) return null;\n if (typeof prop.const === 'string') return prop.const;\n if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n return prop.enum[0];\n }\n return null;\n}\n\nfunction resolveVariantModelName(schema: SchemaObject): string | null {\n if (schema.$ref) {\n return resolveSchemaName(schema.$ref.replace(/^#\\/components\\/schemas\\//, ''));\n }\n const title = typeof schema['title'] === 'string' ? (schema['title'] as string) : null;\n if (title) return resolveSchemaName(title);\n return null;\n}\n\n/** Look up the discriminator's mapped variant name for an inline object\n * variant by reading its const-valued discriminator property. Returns null\n * when the variant doesn't pin the property to a string const, or when\n * the value isn't in the mapping. */\nfunction mapVariantToDiscriminatorEntry(\n variant: SchemaObject,\n discriminator: { property: string; mapping: Record<string, string> },\n): string | null {\n const value = getConstPropertyValue(variant, discriminator.property);\n if (value === null) return null;\n return discriminator.mapping[value] ?? null;\n}\n\n/**\n * Derive a discriminator value → variant model name mapping for an inline-\n * variant `oneOf` whose explicit `discriminator:` has no `mapping:` clause.\n *\n * Each variant model name is reproduced via `nameVariantModel` so it matches\n * what `extractNestedSchema` registered when it walked the same `oneOf` to\n * pull variants out as named models. Variant 0 keeps the bare parent name\n * (e.g. `ApiKeyOwner`); subsequent variants get a const-derived prefix\n * (e.g. `UserApiKeyOwner` for the `type: const: user` variant).\n *\n * The \"parent name\" used here mirrors the one `collectNestedInlineModels`\n * passes to `extractNestedSchema`: it's the qualified inline model name\n * built from `contextName` (the field name) plus `parentModelName` (the\n * containing model). Returns null when any non-object variant is present\n * or when a variant lacks a const value on the discriminator property.\n */\nfunction deriveInlineVariantMapping(\n variants: SchemaObject[],\n discriminatorProperty: string,\n contextName: string | undefined,\n parentModelName: string | undefined,\n): Record<string, string> | null {\n if (variants.length === 0 || !contextName) return null;\n const inlineObjectVariants = variants.filter((v) => !v.$ref && v.properties && (v.type === 'object' || !v.type));\n if (inlineObjectVariants.length !== variants.length) return null;\n\n const baseInlineName = qualifyInlineModelName(toPascalCase(contextName), parentModelName);\n const namingDiscriminator = { property: discriminatorProperty };\n const mapping: Record<string, string> = {};\n const emittedSoFar: Model[] = [];\n for (const variant of inlineObjectVariants) {\n const constValue = getConstPropertyValue(variant, discriminatorProperty);\n if (constValue === null) return null;\n const variantName = nameVariantModel(variant, baseInlineName, emittedSoFar, namingDiscriminator);\n mapping[constValue] = variantName;\n emittedSoFar.push({ name: variantName, fields: [] });\n }\n return mapping;\n}\n\nfunction extractEnum(name: string, schema: SchemaObject): Enum {\n const values: EnumValue[] = (schema.enum ?? []).map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: typeof v === 'number' ? v : String(v),\n description: undefined,\n }));\n\n const rawDefault = schema.default;\n const def =\n rawDefault !== undefined && values.some((v) => v.value === rawDefault)\n ? (rawDefault as string | number)\n : undefined;\n\n return { name, values, default: def };\n}\nfunction extractModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n if (schema.allOf) {\n return extractAllOfModel(name, schema, schemas);\n }\n\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n }\n\n // Pure oneOf/anyOf schemas (no allOf, no properties): merge variant fields\n // as optional. This handles schemas like UpdateOrganizationMembership which\n // is a oneOf with mutually exclusive field groups (role_slug vs role_slugs).\n if (fields.length === 0 && (schema.oneOf || schema.anyOf)) {\n const variants = schema.oneOf ?? schema.anyOf ?? [];\n const emptyRequired = new Set<string>();\n const seenFieldNames = new Set<string>();\n for (const variant of variants) {\n if (!variant.properties) continue;\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n seenFieldNames.add(fieldName);\n fields.push(buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired));\n }\n }\n }\n\n // When additionalProperties is an object schema alongside properties,\n // surface it as a catch-all map field so emitters can generate Map<string, T>.\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && schema.properties) {\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n const valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, 'additionalProperties', name);\n fields.push({\n name: 'additionalProperties',\n type: { kind: 'map', valueType },\n required: false,\n description: 'Additional properties not captured by named fields',\n });\n }\n }\n\n return { name, description: schema.description, fields };\n}\n\nfunction extractAllOfModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n const fields: Field[] = [];\n const requiredSet = new Set<string>();\n let resultDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n\n for (const subSchema of schema.allOf ?? []) {\n // Resolve $ref sub-schemas by looking up the referenced component schema\n let resolved = subSchema;\n if (subSchema.$ref && schemas) {\n const segments = subSchema.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) {\n resolved = schemas[refName];\n }\n }\n\n // If the resolved schema is itself an allOf, recursively extract its fields\n if (resolved.allOf) {\n const nested = extractAllOfModel(name, resolved, schemas);\n for (const f of nested.fields) {\n fields.push({ ...f, required: false }); // will be re-set below\n if (f.required) requiredSet.add(f.name);\n }\n } else if (resolved.oneOf || resolved.anyOf) {\n const variants = resolved.oneOf ?? resolved.anyOf ?? [];\n // Detect discriminated union: every variant pins the same property to a\n // distinct const value (e.g. EventSchema where each variant has event: const).\n // When detected, store the discriminator instead of flattening variant fields —\n // the base allOf schema already captures the common fields.\n const discriminatorInfo = detectAllOfVariantDiscriminator(variants, name);\n if (discriminatorInfo) {\n resultDiscriminator = discriminatorInfo;\n } else {\n // Flatten oneOf/anyOf variant fields into the parent model as optional\n // fields. This handles the common allOf + oneOf pattern where the spec\n // uses mutually exclusive variant groups (e.g. password vs password_hash).\n const emptyRequired = new Set<string>();\n const seenFieldNames = new Set(fields.map((f) => f.name));\n for (const variant of variants) {\n if (!variant.properties) continue;\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n seenFieldNames.add(fieldName);\n fields.push(buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired));\n }\n }\n // Do NOT add variant-level required to the requiredSet — these fields\n // are optional at the parent level because they come from mutually\n // exclusive branches.\n }\n } else {\n if (resolved.required) {\n for (const r of resolved.required) requiredSet.add(r);\n }\n if (resolved.properties) {\n // Use an empty requiredSet — required flags are set in the final pass below\n const emptyRequired = new Set<string>();\n for (const [fieldName, fieldSchema] of Object.entries(resolved.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, emptyRequired));\n }\n }\n }\n }\n\n // Also collect required from the outer schema\n if (schema.required) {\n for (const r of schema.required) requiredSet.add(r);\n }\n\n // Set required flags\n for (const f of fields) {\n f.required = requiredSet.has(f.name);\n }\n\n return {\n name,\n description: schema.description,\n fields,\n ...(resultDiscriminator ? { discriminator: resultDiscriminator } : {}),\n };\n}\n\n/**\n * Walk through `allOf` wrappers to collect the effective top-level properties\n * of a schema. Stops at `oneOf` / `anyOf` boundaries — those are different\n * variant axes, not part of the same flat object.\n *\n * Used by `detectAllOfVariantDiscriminator` and `deriveDiscriminatedVariantName`\n * so a oneOf variant of the form `{ allOf: [{ properties: { … } }, { oneOf: […] }] }`\n * still surfaces its top-level `properties` (in particular its discriminator\n * `const`) instead of being treated as having none.\n */\nfunction getEffectiveProperties(schema: SchemaObject): Record<string, SchemaObject> {\n const props: Record<string, SchemaObject> = {};\n const visit = (s: SchemaObject): void => {\n if (s.properties) {\n for (const [k, v] of Object.entries(s.properties)) {\n if (!(k in props) && v) props[k] = v;\n }\n }\n if (s.allOf) {\n for (const sub of s.allOf) visit(sub);\n }\n // Do NOT walk into oneOf / anyOf — those are alternatives, not\n // simultaneously-present properties.\n };\n visit(schema);\n return props;\n}\n\nfunction getEffectiveConstPropertyValue(schema: SchemaObject, property: string): string | null {\n const direct = getConstPropertyValue(schema, property);\n if (direct !== null) return direct;\n const effective = getEffectiveProperties(schema)[property];\n if (!effective) return null;\n if (typeof effective.const === 'string') return effective.const;\n if (Array.isArray(effective.enum) && effective.enum.length === 1 && typeof effective.enum[0] === 'string') {\n return effective.enum[0];\n }\n return null;\n}\n\n/**\n * Detect an implicit discriminator on an allOf+oneOf where every variant is an\n * object that pins the same property to a distinct const value. Unlike\n * detectConstPropertyDiscriminator (which requires $ref or title for variant\n * model names), this version derives model names from the const value itself\n * using deriveDiscriminatedVariantName — matching how extractDiscriminatedAllOfVariantModels\n * names those models.\n *\n * Walks through allOf wrappers on each variant so a oneOf branch like\n * { allOf: [{ properties: { type: { const: 'oauth' } } }, { oneOf: […] }] }\n * still surfaces `type` as a candidate discriminator.\n *\n * Returns null when no discriminator can be reliably detected.\n */\nfunction detectAllOfVariantDiscriminator(\n variants: SchemaObject[],\n fallbackName: string,\n): { property: string; mapping: Record<string, string> } | null {\n if (variants.length < 2) return null;\n\n // Find a property whose const value is present on every variant\n // (looking through allOf wrappers on each variant).\n const firstProps = getEffectiveProperties(variants[0] ?? {});\n let candidateProperty: string | null = null;\n for (const propName of Object.keys(firstProps)) {\n if (variants.every((v) => getEffectiveConstPropertyValue(v, propName) !== null)) {\n candidateProperty = propName;\n break;\n }\n }\n if (!candidateProperty) return null;\n\n const mapping: Record<string, string> = {};\n const seenModelNames = new Set<string>();\n for (const v of variants) {\n const value = getEffectiveConstPropertyValue(v, candidateProperty);\n if (value === null) return null;\n const modelName = deriveDiscriminatedVariantName(v, fallbackName);\n // If two variants map to the same model name, the discriminator is ambiguous\n if (seenModelNames.has(modelName)) return null;\n seenModelNames.add(modelName);\n mapping[value] = modelName;\n }\n\n return { property: candidateProperty, mapping };\n}\n\nfunction extractDiscriminatedAllOfVariantModels(schema: SchemaObject, fallbackName: string): Model[] {\n const models: Model[] = [];\n const seenNames = new Set<string>();\n\n // Collect base-object properties + required from the allOf wrapper so each\n // variant can be emitted as a complete, self-contained type. Schemas like\n // `EventSchema` repeat the base fields inside every variant in the spec\n // (so this merge is a no-op there), but `ConnectApplication`'s OAuth /\n // M2M variants don't — without this, dispatcher consumers would get a\n // variant that's missing the shared `id` / `name` / `object` etc.\n const baseProperties: Record<string, SchemaObject> = {};\n const baseRequired = new Set<string>();\n for (const subSchema of schema.allOf ?? []) {\n if (subSchema.oneOf) continue; // the variant axis, handled below\n const flat = subSchema.allOf ? flattenVariantForExtraction(subSchema) : subSchema;\n if (flat.properties) {\n for (const [k, v] of Object.entries(flat.properties)) {\n if (!(k in baseProperties) && v) baseProperties[k] = v;\n }\n }\n if (flat.required) for (const r of flat.required) baseRequired.add(r);\n }\n\n for (const subSchema of schema.allOf ?? []) {\n for (const variant of subSchema.oneOf ?? []) {\n // Flatten any allOf wrapper on the variant (e.g. `ConnectApplication`'s\n // OAuth branch is `allOf: [{ properties: {…} }, { oneOf: [first-party\n // sub-variants] }]`). The flattened object has merged properties and\n // an inlined sub-variant `oneOf` so `extractInlineModelDeep` can pull\n // out a complete variant model.\n const flat = flattenVariantForExtraction(variant);\n if (!flat.properties || (flat.type !== undefined && flat.type !== 'object')) continue;\n\n // Merge base fields into the variant. Variant-specific properties win\n // on name collisions because the spec may pin a base field to a more\n // specific shape inside a variant.\n const mergedProperties: Record<string, SchemaObject> = { ...baseProperties };\n for (const [k, v] of Object.entries(flat.properties)) {\n if (v) mergedProperties[k] = v;\n }\n const mergedRequired = new Set<string>([...baseRequired, ...(flat.required ?? [])]);\n const merged: SchemaObject = {\n type: 'object',\n properties: mergedProperties,\n required: [...mergedRequired],\n };\n\n const variantName = deriveDiscriminatedVariantName(variant, fallbackName);\n for (const model of extractInlineModelDeep(variantName, merged)) {\n if (seenNames.has(model.name)) continue;\n seenNames.add(model.name);\n models.push(model);\n }\n }\n }\n\n return models;\n}\n\n/**\n * Flatten a oneOf variant schema into a single object-shaped schema for\n * variant-model extraction. Recursively merges `allOf` members and folds\n * any nested `oneOf` into an inline-oneOf field group whose properties are\n * the union across sub-branches (required only when present in every\n * sub-branch). Returns the schema unchanged when no flattening is needed.\n */\nfunction flattenVariantForExtraction(variant: SchemaObject): SchemaObject {\n if (!variant.allOf) return variant;\n\n const mergedProperties: Record<string, SchemaObject> = {};\n const mergedRequired = new Set<string>();\n const nestedOneOfs: SchemaObject[][] = [];\n\n const collect = (s: SchemaObject): void => {\n if (s.properties) {\n for (const [k, v] of Object.entries(s.properties)) {\n if (!(k in mergedProperties) && v) mergedProperties[k] = v;\n }\n }\n if (s.required) {\n for (const r of s.required) mergedRequired.add(r);\n }\n if (s.allOf) {\n for (const sub of s.allOf) collect(sub);\n }\n if (s.oneOf) nestedOneOfs.push(s.oneOf);\n };\n collect(variant);\n\n // Fold each nested oneOf into the merged shape: any field appearing in any\n // sub-branch is included as optional (or required iff present-and-required\n // in every sub-branch). Conflicting literal types widen to their primitive\n // base. This handles the `is_first_party: true | false` widening on the\n // OAuth variant's first-party sub-oneOf.\n for (const branches of nestedOneOfs) {\n const flatBranches = branches.map(flattenVariantForExtraction);\n const branchKeys = new Set<string>();\n for (const b of flatBranches) {\n for (const k of Object.keys(b.properties ?? {})) branchKeys.add(k);\n }\n for (const key of branchKeys) {\n const schemas: SchemaObject[] = [];\n for (const b of flatBranches) {\n const s = b.properties?.[key];\n if (s) schemas.push(s);\n }\n const merged = mergeBranchPropertySchemas(schemas);\n if (!(key in mergedProperties)) mergedProperties[key] = merged;\n const inAllBranches = flatBranches.every((b) => b.properties && key in b.properties);\n const requiredInAll = inAllBranches && flatBranches.every((b) => (b.required ?? []).includes(key));\n if (requiredInAll) mergedRequired.add(key);\n }\n }\n\n return {\n type: 'object',\n properties: mergedProperties,\n required: [...mergedRequired],\n };\n}\n\n/**\n * Merge same-named property schemas from across sub-variants. If every\n * occurrence is a boolean const, widen to plain boolean; if every occurrence\n * is a distinct string const, widen to plain string. Otherwise return the\n * first occurrence — emitters that build their own widened types (e.g. the\n * Node discriminated-models module) re-derive from the raw spec.\n */\nfunction mergeBranchPropertySchemas(schemas: SchemaObject[]): SchemaObject {\n if (schemas.length === 0) return {};\n if (schemas.length === 1) return schemas[0];\n\n const allBoolConst = schemas.every((s) => s.type === 'boolean' && typeof s.const === 'boolean');\n if (allBoolConst) {\n return { type: 'boolean', description: schemas[0].description };\n }\n const allStringConst = schemas.every((s) => s.type === 'string' && typeof s.const === 'string');\n if (allStringConst) {\n const values = schemas.map((s) => s.const as string);\n if (new Set(values).size === 1) return schemas[0];\n return { type: 'string', description: schemas[0].description };\n }\n return schemas[0];\n}\n\nfunction deriveDiscriminatedVariantName(schema: SchemaObject, fallbackName: string): string {\n // Walk through allOf wrappers so a variant of the form\n // `{ allOf: [{ properties: { type: const: 'oauth' } }, { oneOf: […] }] }`\n // still surfaces its discriminator const value for naming.\n const effective = getEffectiveProperties(schema);\n if (Object.keys(effective).length === 0) return fallbackName;\n\n const pickConst = (name: string): string | null => {\n const field = effective[name];\n if (!field) return null;\n if (typeof field.const === 'string') return field.const;\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return field.enum[0];\n }\n return null;\n };\n\n let constValue: string | null = null;\n for (const preferred of ['event', 'type', 'object']) {\n constValue = pickConst(preferred);\n if (constValue) break;\n }\n if (constValue === null) {\n for (const name of Object.keys(effective)) {\n constValue = pickConst(name);\n if (constValue) break;\n }\n }\n if (constValue === null) return fallbackName;\n\n const pascal = toPascalCase(constValue);\n if (!pascal) return fallbackName;\n\n // A single-word const like `oauth` or `m2m` is too generic to stand alone\n // as a top-level model name — it would collide with unrelated schemas. Pair\n // it with the parent name so the variant resolves to e.g. `ConnectApplicationOAuth`\n // / `ConnectApplicationM2M`. Multi-word consts like `action.authentication.denied`\n // are already specific enough on their own, matching the established\n // EventSchema variant naming.\n const wordCount = splitWords(constValue).length;\n if (wordCount >= 2) return pascal;\n if (pascal === fallbackName) return pascal;\n if (fallbackName.startsWith(pascal)) return fallbackName;\n if (pascal.endsWith(fallbackName)) return pascal;\n return `${fallbackName}${pascal}`;\n}\n\nfunction extractInlineModelDeep(name: string, schema: SchemaObject): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema));\n }\n\n if (fieldSchema.type === 'array' && fieldSchema.items?.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema.items));\n }\n\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n nestedModels.push(\n ...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), {\n type: 'object',\n properties: mergedProperties,\n required: mergedRequired,\n }),\n );\n }\n }\n\n if (fieldSchema.oneOf) {\n const inlineObjectVariants = fieldSchema.oneOf.filter(\n (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n );\n if (inlineObjectVariants.length > 0) {\n const baseQualified = qualifyNestedInlineName(name, fieldName);\n const namingDisc = deriveConstNamingDiscriminator(inlineObjectVariants);\n const emitted: Model[] = [];\n for (const variant of inlineObjectVariants) {\n const variantName = nameVariantModel(variant, baseQualified, emitted, namingDisc);\n emitted.push({ name: variantName, fields: [] });\n nestedModels.push(...extractInlineModelDeep(variantName, variant));\n }\n }\n }\n }\n\n return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n\nfunction qualifyNestedInlineName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n if (pascalField.startsWith(parentName)) return pascalField;\n\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n return match[1] + singularize(match[2]);\n }\n return qualified;\n}\n\nexport function schemaToTypeRef(schema: SchemaObject, contextName?: string, parentModelName?: string): TypeRef {\n // Handle $ref → ModelRef or EnumRef.\n // A `$ref` to a top-level component schema needs to preserve whether the\n // target is a model or an enum, because emitters route imports differently\n // for the two kinds (e.g. com.example.models.X vs com.example.types.X). The\n // set of enum names is precomputed by extractSchemas() in a first pass so\n // it's available even when called recursively for nested $refs.\n if (schema.$ref) {\n const segments = schema.$ref.split('/');\n const rawName = segments[segments.length - 1];\n const resolved = resolveSchemaName(rawName);\n if (activeEnumSchemaNames.has(resolved)) {\n return { kind: 'enum', name: resolved };\n }\n return { kind: 'model', name: resolved };\n }\n\n // Handle OAS 3.1 nullable type arrays: type: [string, null]\n if (Array.isArray(schema.type)) {\n const nonNullTypes = schema.type.filter((t: string) => t !== 'null');\n // type: ['null'] — only null, no real type\n if (nonNullTypes.length === 0) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n if (schema.type.includes('null') && nonNullTypes.length === 1) {\n return {\n kind: 'nullable',\n inner: schemaToTypeRef({ ...schema, type: nonNullTypes[0], nullable: false }, contextName),\n };\n }\n // Multiple non-null types → union\n if (nonNullTypes.length > 1) {\n const variants = nonNullTypes.map((t: string) => schemaToTypeRef({ ...schema, type: t }, contextName));\n const ref: TypeRef = { kind: 'union', variants };\n if (schema.type.includes('null')) {\n return { kind: 'nullable', inner: ref };\n }\n return ref;\n }\n }\n\n // Handle OAS 3.0 nullable flag\n if (schema.nullable && schema.type) {\n return {\n kind: 'nullable',\n inner: schemaToTypeRef({ ...schema, nullable: false }, contextName),\n };\n }\n\n // Handle allOf — merge properties from all sub-schemas.\n // This handles patterns like: allOf: [{ type: object, properties: {...} }, { oneOf: [...] }]\n // which are valid OAS 3.1 but weren't handled for field-level schemas.\n if (schema.allOf) {\n // If allOf contains a $ref, prefer the ref (it's a named type)\n const refItem = schema.allOf.find((s: SchemaObject) => s.$ref);\n if (refItem) {\n // If allOf has $ref AND siblings with properties, return a merged model ref\n // to avoid losing the augmentation properties\n const hasAugmentation = schema.allOf.some((s: SchemaObject) => !s.$ref && (s.properties || s.type === 'object'));\n if (hasAugmentation) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return { kind: 'model', name: qualifyInlineModelName(baseName, parentModelName) };\n }\n return schemaToTypeRef(refItem, contextName, parentModelName);\n }\n // If allOf has a single item, unwrap it\n if (schema.allOf.length === 1) {\n return schemaToTypeRef(schema.allOf[0], contextName, parentModelName);\n }\n // If allOf items all have properties, treat as a merged model\n const hasProperties = schema.allOf.some((s: SchemaObject) => s.properties);\n if (hasProperties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n // Fall through to other checks\n }\n\n // Handle oneOf / anyOf → Union or Nullable\n // Valid OAS 3.1: properties can have { oneOf: [{ type: object }, { type: 'null' }] }\n // without a wrapping `type` field.\n if (schema.oneOf || schema.anyOf) {\n const compositionKind: 'oneOf' | 'anyOf' = schema.oneOf ? 'oneOf' : 'anyOf';\n const rawVariants: SchemaObject[] = schema.oneOf ?? schema.anyOf ?? [];\n\n // Check for nullable pattern: oneOf: [realType, { type: 'null' }]\n const nullVariant = rawVariants.find(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.length === 1 && v.type[0] === 'null'),\n );\n const nonNullVariants = rawVariants.filter((v) => v !== nullVariant);\n\n if (nullVariant && nonNullVariants.length === 1) {\n // Nullable single type — unwrap as nullable\n return {\n kind: 'nullable',\n inner: schemaToTypeRef(nonNullVariants[0], contextName, parentModelName),\n };\n }\n\n // Collapse an oneOf/anyOf whose non-null variants are all string-const\n // schemas into a single enum. This turns patterns like\n // provider: { oneOf: [{ const: \"AppleOAuth\" }, { const: \"GitHubOAuth\" }, ...] }\n // into a proper enum type with one member per variant instead of a\n // structurally-opaque union of literal refs.\n const literalStrings = collectLiteralStringConsts(nonNullVariants);\n if (literalStrings !== null && literalStrings.length >= 2) {\n const enumRef = buildSyntheticEnumRef(literalStrings, contextName, parentModelName);\n return nullVariant ? { kind: 'nullable', inner: enumRef } : enumRef;\n }\n\n // Resolve the discriminator. Three sources, in order:\n // 1. Explicit `discriminator:` with explicit `mapping:` — trust the spec.\n // 2. Explicit `discriminator:` with no `mapping:` — derive mapping from\n // variants' const values on the discriminator property, pairing each\n // to its inline-extracted variant model name (built the same way\n // `extractNestedSchema` names them via `nameVariantModel`). This\n // covers `ApiKey.owner`-shaped schemas where the spec uses\n // `discriminator: { propertyName: type }` but lists inline anonymous\n // `oneOf` variants instead of `$ref` links.\n // 3. No explicit discriminator but every variant pins the same const-\n // valued property AND the variants are nameable via $ref/title —\n // `detectConstPropertyDiscriminator` covers this.\n // 4. As a last resort, when (3) doesn't apply because variants are\n // inline anonymous objects, derive the same const → variant-model-\n // name mapping using `nameVariantModel`. This covers\n // `ApiKeyCreatedData.owner`-shaped schemas (oneOf with inline\n // const-discriminating variants but no `discriminator:` keyword).\n let resolvedDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n if (schema.discriminator) {\n const property = schema.discriminator.propertyName;\n const explicitMapping = schema.discriminator.mapping ?? {};\n let mapping: Record<string, string> = Object.fromEntries(\n Object.entries(explicitMapping).map(([k, v]) => [k, v.replace(/^#\\/components\\/schemas\\//, '')]),\n );\n if (Object.keys(mapping).length === 0) {\n const inlineMapping = deriveInlineVariantMapping(nonNullVariants, property, contextName, parentModelName);\n if (inlineMapping) mapping = inlineMapping;\n }\n resolvedDiscriminator = { property, mapping };\n } else if (compositionKind === 'oneOf') {\n const synthetic = detectConstPropertyDiscriminator(nonNullVariants);\n if (synthetic) {\n resolvedDiscriminator = synthetic;\n } else {\n const namingDisc = deriveConstNamingDiscriminator(nonNullVariants);\n if (namingDisc) {\n const inlineMapping = deriveInlineVariantMapping(\n nonNullVariants,\n namingDisc.property,\n contextName,\n parentModelName,\n );\n if (inlineMapping) {\n resolvedDiscriminator = { property: namingDisc.property, mapping: inlineMapping };\n }\n }\n }\n }\n\n // Build variants. When we have a discriminator with a known mapping and\n // every non-null variant is an inline object that pins the discriminator\n // property to a const, route each variant's TypeRef through that mapping.\n // This avoids the degenerate case where `qualifyInlineModelName` would\n // assign the same parent-derived name (e.g. `ApiKeyOwner`) to every\n // inline variant, collapsing the union to a single repeated model ref.\n const variants: TypeRef[] = [];\n for (const v of rawVariants) {\n if (v === nullVariant) continue;\n const inlineMappingName =\n resolvedDiscriminator && !v.$ref && v.properties && (v.type === 'object' || !v.type)\n ? mapVariantToDiscriminatorEntry(v, resolvedDiscriminator)\n : null;\n if (inlineMappingName) {\n variants.push({ kind: 'model', name: inlineMappingName });\n } else {\n variants.push(schemaToTypeRef(v, contextName, parentModelName));\n }\n }\n const hasNull = !!nullVariant;\n\n const union: TypeRef = {\n kind: 'union',\n variants,\n compositionKind,\n ...(resolvedDiscriminator ? { discriminator: resolvedDiscriminator } : {}),\n };\n return hasNull ? { kind: 'nullable', inner: union } : union;\n }\n\n // Handle const → LiteralType (supports string, number, boolean)\n if (schema.const !== undefined) {\n if (typeof schema.const === 'string' || typeof schema.const === 'number' || typeof schema.const === 'boolean') {\n return { kind: 'literal', value: schema.const };\n }\n // null const → nullable unknown\n if (schema.const === null) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n // const of object/array → map or array with unknown values\n if (typeof schema.const === 'object') {\n if (Array.isArray(schema.const)) {\n return { kind: 'array', items: { kind: 'primitive', type: 'unknown' } };\n }\n return { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } };\n }\n }\n if (schema.enum && schema.enum.length === 1) {\n const v = schema.enum[0];\n return { kind: 'literal', value: typeof v === 'number' ? v : String(v) };\n }\n\n // Handle enum\n if (schema.enum) {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n // Strip ListItem/ByExternalId markers from parent name so enum names are clean:\n // e.g., DirectoryListItem + State → Directory + State = DirectoryState\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n // Avoid redundant prefix: Connection + ConnectionType → ConnectionType\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n // Run `schemaNameTransform` so project-level rename maps in\n // `oagen.config.ts` reach inline parameter/field enums too — without\n // this, `RadarAction` (built from path param `action` on the Radar\n // service) couldn't be redirected to `RadarListAction` from config.\n const finalName = activeSchemaNameTransform ? activeSchemaNameTransform(qualifiedName) : qualifiedName;\n return {\n kind: 'enum',\n name: finalName,\n values: schema.enum.map((v) => (typeof v === 'number' ? v : String(v))),\n };\n }\n\n // Handle array — pass parentModelName through to qualify inline items\n if (schema.type === 'array' && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(schema.items, contextName, parentModelName),\n };\n }\n // Handle array without explicit type but with items (valid OAS 3.1)\n if (!schema.type && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(schema.items, contextName, parentModelName),\n };\n }\n\n // Handle object → ModelRef (if it has properties, it's a named model reference)\n // When additionalProperties is also present, we still return a ModelRef so the\n // named properties are preserved. The extractModel path will pick up the extra\n // properties as a catch-all map field named `additionalProperties`.\n if (schema.type === 'object' && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Handle freeform object with additionalProperties or patternProperties → Map<string, T>\n if (schema.type === 'object' && !schema.properties) {\n let valueType: TypeRef = { kind: 'primitive', type: 'unknown' };\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n // Empty additionalProperties ({}) means \"any value\" — keep as unknown\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, contextName);\n }\n } else if (schema.patternProperties) {\n // patternProperties: { \"pattern\": schema } → use the first pattern's schema as value type\n const patterns = Object.values(schema.patternProperties);\n if (patterns.length > 0) {\n valueType = schemaToTypeRef(patterns[0], contextName);\n }\n }\n return {\n kind: 'map',\n valueType,\n };\n }\n\n // Handle primitives\n const primitiveMap: Record<string, 'string' | 'integer' | 'number' | 'boolean'> = {\n string: 'string',\n integer: 'integer',\n number: 'number',\n boolean: 'boolean',\n };\n\n const typeStr = Array.isArray(schema.type) ? schema.type[0] : schema.type;\n if (typeStr && primitiveMap[typeStr]) {\n return {\n kind: 'primitive',\n type: primitiveMap[typeStr],\n ...(schema.format ? { format: schema.format } : {}),\n };\n }\n\n // Handle schemas with no type — if it has properties, treat as model\n if (!schema.type && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Empty schema {} → unknown\n if (\n !schema.type &&\n !schema.$ref &&\n !schema.oneOf &&\n !schema.anyOf &&\n !schema.allOf &&\n !schema.enum &&\n !schema.properties &&\n !schema.items\n ) {\n return { kind: 'primitive', type: 'unknown' };\n }\n\n // Fallback: treat unknown schemas as unknown\n if (contextName) {\n console.warn(`[oagen] Warning: Unknown schema shape treated as unknown (context: ${contextName})`);\n }\n return { kind: 'primitive', type: 'unknown' };\n}\n\nimport { qualifyInlineModelName } from './inline-models.js';\n\nexport { qualifyInlineModelName, extractInlineModelsFromSchemas } from './inline-models.js';\n","import type { TypeRef, Parameter, PaginationMeta } from '../ir/types.js';\n\nconst CURSOR_PARAMS = ['cursor', 'after', 'before', 'starting_after', 'ending_before', 'page_token', 'next_token'];\n\nconst OFFSET_PARAMS = ['offset', 'page', 'page_number', 'skip'];\nconst LIMIT_PARAMS = ['limit', 'page_size', 'per_page', 'size', 'count'];\n\n/**\n * Detect if an operation uses pagination and return structured metadata\n * for auto-paging iterator generation.\n *\n * Supports two strategies:\n * 1. **Cursor-based**: query params include a cursor-like parameter\n * 2. **Offset-based**: query params include both an offset-like and limit-like parameter\n *\n * Returns null if no pagination pattern is detected.\n */\nexport function detectPagination(\n response: TypeRef,\n queryParams: Parameter[],\n dataPath?: string,\n): PaginationMeta | null {\n // Try cursor-based first (preferred). Scan in CURSOR_PARAMS priority order\n // rather than queryParams order so that an endpoint exposing both `before`\n // and `after` reports `after` (forward iteration) — matches the wire\n // convention where `after` advances through pages.\n const cursorParam = CURSOR_PARAMS.map((name) => queryParams.find((p) => p.name === name)).find(\n (p): p is Parameter => p !== undefined,\n );\n\n if (cursorParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'cursor',\n param: cursorParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n // Try offset-based pagination\n const offsetParam = queryParams.find((p) => OFFSET_PARAMS.includes(p.name));\n const limitParam = queryParams.find((p) => LIMIT_PARAMS.includes(p.name));\n\n if (offsetParam && limitParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'offset',\n param: offsetParam.name,\n limitParam: limitParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n return null;\n}\n","import type { TypeRef, Model, Field } from '../ir/types.js';\nimport { toPascalCase, singularize, stripListItemMarkers } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\n\nexport interface ResponseExtractionResult {\n /** The TypeRef to use as the operation's response type */\n response: TypeRef;\n /** Any inline models discovered during extraction (to merge into ir.models) */\n inlineModels: Model[];\n /** Whether this response indicates a paginated list */\n isPaginated: boolean;\n /** Path to the data array within the response envelope (e.g., 'data') */\n dataPath?: string;\n /** TypeRef of individual items in a paginated list */\n itemType?: TypeRef;\n}\n\nexport function classifyAndExtractResponse(\n schema: SchemaObject,\n contextName: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ResponseExtractionResult {\n // 1. If schema is a $ref, resolve to model name (Phase 1)\n if (schema.$ref) {\n return { response: schemaToTypeRef(schema, contextName), inlineModels: [], isPaginated: false };\n }\n\n // 2. Check for list envelope (structural detection: array prop + non-array companion)\n const envelope = detectListEnvelope(schema);\n if (envelope.isEnvelope) {\n return extractListResponse(schema, contextName, envelope.dataPath!);\n }\n\n // 3. Check for single-resource wrapper ({ resource_name: { object: \"...\", ... } })\n if (isSingleResourceWrapper(schema)) {\n return extractWrappedResource(schema, contextName);\n }\n\n // 4. Direct resource or plain inline object\n return extractDirectResource(schema, contextName, componentSchemas);\n}\n\ninterface ListEnvelopeResult {\n isEnvelope: boolean;\n dataPath: string | null;\n}\n\nconst KNOWN_DATA_PATHS = new Set(['data', 'items', 'results', 'records', 'entries', 'values', 'nodes', 'edges']);\n\nconst PAGINATION_METADATA_PATTERNS = [\n 'meta',\n 'metadata',\n 'pagination',\n 'cursor',\n 'has_more',\n 'page_info',\n 'total',\n 'next_page',\n 'previous_page',\n 'offset',\n];\n\nfunction detectListEnvelope(schema: SchemaObject): ListEnvelopeResult {\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n if (propSources.length === 0) return { isEnvelope: false, dataPath: null };\n\n // Merge all properties into a single view\n const mergedProps: Record<string, SchemaObject | undefined> = {};\n for (const source of propSources) {\n Object.assign(mergedProps, source);\n }\n\n // Find array-typed properties and non-array companion properties\n const arrayProps: string[] = [];\n const nonArrayKeys: string[] = [];\n\n for (const [key, propSchema] of Object.entries(mergedProps)) {\n if (!propSchema) continue;\n if (propSchema.type === 'array') {\n arrayProps.push(key);\n } else {\n nonArrayKeys.push(key);\n }\n }\n\n // List envelope heuristic: exactly one array property + at least one non-array companion\n // that looks like pagination metadata. A `data` array alone (e.g. with only an\n // `object` discriminant companion) is NOT sufficient — the companion must indicate\n // actual pagination (cursor, metadata, total, etc.).\n if (arrayProps.length === 1 && nonArrayKeys.length >= 1) {\n const arrayPropName = arrayProps[0];\n\n const hasPaginationCompanion = nonArrayKeys.some((key) =>\n PAGINATION_METADATA_PATTERNS.some((pattern) => key.toLowerCase().includes(pattern)),\n );\n\n if (KNOWN_DATA_PATHS.has(arrayPropName) && hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n\n // Non-standard array property name — still treat as envelope if pagination companion exists\n if (hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n }\n\n return { isEnvelope: false, dataPath: null };\n}\n\nfunction extractListResponse(schema: SchemaObject, contextName: string, dataPath: string): ResponseExtractionResult {\n let itemTypeRef: TypeRef = { kind: 'primitive', type: 'string' };\n const inlineModels: Model[] = [];\n\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n for (const props of propSources) {\n const dataProp = props[dataPath];\n if (!dataProp) continue;\n\n if (dataProp.type === 'array' && dataProp.items) {\n const items = dataProp.items;\n if (items.$ref) {\n itemTypeRef = schemaToTypeRef(items, contextName);\n } else if (items.type === 'object' && items.properties) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n itemTypeRef = { kind: 'model', name: itemName };\n inlineModels.push(...extractInlineModel(itemName, items));\n }\n }\n }\n\n return {\n response: { kind: 'array', items: itemTypeRef },\n inlineModels,\n isPaginated: true,\n dataPath,\n itemType: itemTypeRef,\n };\n}\n\nfunction hasDiscriminantConstField(schema: SchemaObject): { property: string; value: string } | null {\n if (!schema.properties) return null;\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n // Fall back to any property with a const or single-value enum\n for (const [name, field] of Object.entries(schema.properties)) {\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n return null;\n}\n\nfunction isSingleResourceWrapper(schema: SchemaObject): boolean {\n if (schema.type !== 'object') return false;\n if (!schema.properties) return false;\n\n // Find the wrapper property: use required[0] if available, or the single property key\n let wrapperKey: string | undefined;\n if (schema.required && schema.required.length === 1) {\n wrapperKey = schema.required[0];\n } else {\n const propKeys = Object.keys(schema.properties);\n if (propKeys.length === 1) {\n wrapperKey = propKeys[0];\n }\n }\n if (!wrapperKey) return false;\n\n const propSchema = schema.properties[wrapperKey];\n if (!propSchema) return false;\n\n // Direct object with a discriminant const field\n if (propSchema.type === 'object' && hasDiscriminantConstField(propSchema) !== null) return true;\n\n // oneOf with object + null (nullable resource)\n if (propSchema.oneOf) {\n return propSchema.oneOf.some((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n }\n\n return false;\n}\n\nfunction extractWrappedResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n const props = schema.properties!;\n const wrapperKey = schema.required && schema.required.length === 1 ? schema.required[0] : Object.keys(props)[0];\n const propSchema = props[wrapperKey]!;\n const inlineModels: Model[] = [];\n\n // Derive model name from the object const value or wrapper property name\n const resourceName = contextName.replace(/Response$/, '');\n\n if (propSchema.oneOf) {\n const objectVariant = propSchema.oneOf.find((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n\n if (objectVariant) {\n const modelName = deriveModelName(objectVariant, resourceName);\n inlineModels.push(...extractInlineModel(modelName, objectVariant));\n\n const hasNullVariant = propSchema.oneOf.some(\n (v) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n\n const modelRef: TypeRef = { kind: 'model', name: modelName };\n return {\n response: hasNullVariant ? { kind: 'nullable', inner: modelRef } : modelRef,\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Direct object\n const modelName = deriveModelName(propSchema, resourceName);\n inlineModels.push(...extractInlineModel(modelName, propSchema));\n\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction extractDirectResource(\n schema: SchemaObject,\n contextName: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ResponseExtractionResult {\n const inlineModels: Model[] = [];\n\n // Direct object with properties (with or without explicit type: 'object')\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const modelName = deriveModelName(schema, contextName);\n inlineModels.push(...extractInlineModel(modelName, schema));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n\n // allOf — merge into a single model. $ref branches are resolved against\n // component schemas so the referenced model's fields are merged rather\n // than silently dropped.\n if (schema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n const unresolvedRefs: string[] = [];\n const seenRefs = new Set<string>();\n let mergedRefFields = false;\n\n const mergeSubSchemas = (subs: SchemaObject[]) => {\n for (const sub of subs) {\n let resolved: SchemaObject = sub;\n if (sub.$ref) {\n if (seenRefs.has(sub.$ref)) continue;\n seenRefs.add(sub.$ref);\n const segments = sub.$ref.split('/');\n const refName = segments[segments.length - 1];\n const refSchema = refName ? componentSchemas?.[refName] : undefined;\n if (!refSchema) {\n unresolvedRefs.push(sub.$ref);\n continue;\n }\n resolved = refSchema;\n mergedRefFields = true;\n }\n if (resolved.allOf) mergeSubSchemas(resolved.allOf);\n if (resolved.properties) Object.assign(mergedProperties, resolved.properties);\n if (resolved.required) mergedRequired.push(...resolved.required);\n }\n };\n mergeSubSchemas(schema.allOf);\n\n // An unresolvable $ref branch (no component schema map) would drop the\n // referenced model's fields entirely — prefer the referenced model as\n // the response type over a merge that silently guts it.\n if (unresolvedRefs.length === 1 && !mergedRefFields) {\n return {\n response: schemaToTypeRef({ $ref: unresolvedRefs[0] }, contextName),\n inlineModels,\n isPaginated: false,\n };\n }\n\n if (Object.keys(mergedProperties).length > 0) {\n const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n // Fields merged from a $ref carry the referenced model's const\n // discriminant (e.g. object: 'magic_auth'); deriving the name from it\n // would collide with the component model, so keep the context name.\n const modelName = mergedRefFields ? toPascalCase(contextName) : deriveModelName(merged, contextName);\n inlineModels.push(...extractInlineModel(modelName, merged));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // oneOf — delegate to schemaToTypeRef (returns union) but also extract inline models\n // from object variants so the model refs resolve\n if (schema.oneOf) {\n for (const variant of schema.oneOf) {\n if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const modelName = deriveModelName(variant, contextName);\n const existingNames = new Set(inlineModels.map((m) => m.name));\n if (!existingNames.has(modelName)) {\n inlineModels.push(...extractInlineModel(modelName, variant));\n }\n }\n }\n }\n\n // Array with inline object items — extract the item model\n if (schema.type === 'array' && schema.items) {\n const items = schema.items;\n if (items.$ref) {\n return {\n response: { kind: 'array', items: schemaToTypeRef(items, contextName) },\n inlineModels,\n isPaginated: false,\n };\n }\n if (items.properties && (items.type === 'object' || !items.type)) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n inlineModels.push(...extractInlineModel(itemName, items));\n return {\n response: { kind: 'array', items: { kind: 'model', name: itemName } },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Non-object schema (primitive, union, etc.) — delegate to schemaToTypeRef\n return {\n response: schemaToTypeRef(schema, contextName),\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction deriveModelName(schema: SchemaObject, fallback: string): string {\n if (!schema.properties) return toPascalCase(fallback);\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n // Fall back to any property with a const string value\n for (const [, field] of Object.entries(schema.properties)) {\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n return toPascalCase(fallback);\n}\n\n/**\n * Qualify a nested inline model name with its parent to avoid generic names.\n * e.g., parent=\"Connection\" + field=\"domains\" → \"ConnectionDomain\" (singularized)\n * Only qualifies when the field name alone would be too generic.\n */\nfunction qualifyNestedName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n // If the field name already starts with the parent name, don't double-prefix\n if (pascalField.startsWith(parentName)) return pascalField;\n // Qualify with parent and singularize:\n // Connection + Domains → ConnectionDomains → singularize lead word → ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n // Singularize the trailing word: ConnectionDomains → ConnectionDomain\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n const trailing = singularize(match[2]);\n return match[1] + trailing;\n }\n return qualified;\n}\n\nfunction extractInlineModel(name: string, schema: SchemaObject): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n // Recursively extract nested inline objects — qualify with parent name\n // to avoid generic names like \"Domains\" when multiple parents have a \"domains\" field\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n const nestedName = qualifyNestedName(name, fieldName);\n nestedModels.push(...extractInlineModel(nestedName, fieldSchema));\n }\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const items = fieldSchema.items;\n if (items.type === 'object' && items.properties) {\n const nestedName = qualifyNestedName(name, fieldName);\n nestedModels.push(...extractInlineModel(nestedName, items));\n }\n }\n // Handle allOf with inline object properties — merge into a single nested model\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n const nestedName = qualifyNestedName(name, fieldName);\n const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n const existingNames = new Set(nestedModels.map((m) => m.name));\n if (!existingNames.has(nestedName)) {\n nestedModels.push(...extractInlineModel(nestedName, merged));\n }\n }\n }\n // Handle oneOf containing inline objects — extract the first non-null object variant\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n const nestedName = qualifyNestedName(name, fieldName);\n const existingNames = new Set(nestedModels.map((m) => m.name));\n if (!existingNames.has(nestedName)) {\n nestedModels.push(...extractInlineModel(nestedName, objectVariant));\n }\n }\n }\n }\n\n return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n","import type {\n Service,\n Operation,\n HttpMethod,\n Parameter,\n ParameterGroup,\n TypeRef,\n ErrorResponse,\n SuccessResponse,\n SecurityRequirement,\n Model,\n Field,\n PaginationMeta,\n} from '../ir/types.js';\nimport { toPascalCase, toCamelCase, cleanSchemaName } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema, resolveSchemaName } from './schemas.js';\nimport { extractInlineModelsFromProperties } from './inline-models.js';\nimport { detectPagination } from './pagination.js';\nimport { classifyAndExtractResponse } from './responses.js';\n\ninterface PathItem {\n get?: OperationObject;\n post?: OperationObject;\n put?: OperationObject;\n patch?: OperationObject;\n delete?: OperationObject;\n head?: OperationObject;\n options?: OperationObject;\n trace?: OperationObject;\n parameters?: RawParameterObject[];\n}\n\ninterface ParameterGroupExtension {\n optional: boolean;\n variants: Record<string, string[]>;\n /** Per-variant names that may be omitted when the variant is used. */\n optionalFields?: Record<string, string[]>;\n}\n\ninterface OperationObject {\n operationId?: string;\n summary?: string;\n description?: string;\n tags?: string[];\n parameters?: RawParameterObject[];\n requestBody?: RawRequestBodyObject;\n responses?: Record<string, ResponseObject>;\n deprecated?: boolean;\n 'x-oagen-async'?: boolean;\n security?: Array<Record<string, string[]>>;\n 'x-mutually-exclusive-parameter-groups'?: Record<string, ParameterGroupExtension>;\n 'x-mutually-exclusive-body-groups'?: Record<string, ParameterGroupExtension>;\n}\n\ninterface ParameterObject {\n name: string;\n in: 'path' | 'query' | 'header' | 'cookie';\n required?: boolean;\n description?: string;\n schema?: SchemaObject;\n deprecated?: boolean;\n example?: unknown;\n style?: string;\n explode?: boolean;\n}\n\n/**\n * A parameter entry as it appears in an operation's (or path item's) raw\n * `parameters` array: either an inline Parameter Object, or a Reference\n * Object (`{ $ref: '#/components/parameters/X' }`). The bundler\n * (`refs.ts`) runs with `dereference: false`, so refs to\n * `components/parameters` are never inlined — they arrive here exactly as\n * written in the spec and must be resolved before use.\n */\ntype RawParameterObject = ParameterObject | { $ref: string };\n\n/**\n * Resolve a raw parameter entry to a concrete Parameter Object, following\n * `$ref`s into `components/parameters` when present. Follows chains of refs\n * (a component that itself is a `$ref` to another component), with a cycle\n * guard for a spec that refs itself.\n *\n * Throws when a `$ref` can't be resolved so a malformed spec fails loudly at\n * parse time instead of silently losing the parameter (see `extractParams`,\n * which used to drop any entry with no `in` field — every `$ref` object has\n * none).\n */\nfunction resolveParameterRef(\n raw: RawParameterObject,\n componentParameters: Record<string, Record<string, unknown>> | undefined,\n operationContext: string,\n): ParameterObject {\n const seenRefs = new Set<string>();\n let current: RawParameterObject = raw;\n\n while ('$ref' in current) {\n if (seenRefs.has(current.$ref)) {\n throw new Error(`Circular parameter $ref chain starting at \"${current.$ref}\" in ${operationContext}.`);\n }\n seenRefs.add(current.$ref);\n\n // Match the whole pointer, not just its last token: a ref into any other\n // section must not resolve off a same-named parameter component.\n const match = /^#\\/components\\/parameters\\/(.+)$/.exec(current.$ref);\n // JSON Pointer escapes (RFC 6901 §4): `~1` -> `/`, then `~0` -> `~`, in that order.\n const refName = match?.[1].replace(/~1/g, '/').replace(/~0/g, '~');\n const resolved = refName ? componentParameters?.[refName] : undefined;\n if (!resolved) {\n throw new Error(\n `Unresolved parameter $ref \"${current.$ref}\" in ${operationContext}: no matching entry under components/parameters.`,\n );\n }\n current = resolved as unknown as RawParameterObject;\n }\n\n return current;\n}\n\ninterface RequestBodyObject {\n required?: boolean;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\n/**\n * A request body as written in the spec: an inline Request Body Object or a\n * Reference Object into `components/requestBodies`. The bundler never inlines\n * those refs (`dereference: false`), so they must be resolved before use.\n */\ntype RawRequestBodyObject = RequestBodyObject | { $ref: string };\n\n/**\n * Resolve a raw request body to a concrete Request Body Object, following\n * `$ref` chains into `components/requestBodies` with a cycle guard. Throws on\n * an unresolvable ref so a malformed spec fails at parse time instead of\n * silently losing the body — and with it the body-ownership rule that keeps\n * duplicated secrets out of the query string.\n */\nfunction resolveRequestBodyRef(\n raw: RawRequestBodyObject | undefined,\n componentRequestBodies: Record<string, Record<string, unknown>> | undefined,\n operationContext: string,\n): RequestBodyObject | undefined {\n if (!raw) return undefined;\n const seenRefs = new Set<string>();\n let current: RawRequestBodyObject = raw;\n\n while ('$ref' in current) {\n if (seenRefs.has(current.$ref)) {\n throw new Error(`Circular request body $ref chain starting at \"${current.$ref}\" in ${operationContext}.`);\n }\n seenRefs.add(current.$ref);\n\n const match = /^#\\/components\\/requestBodies\\/(.+)$/.exec(current.$ref);\n // JSON Pointer escapes (RFC 6901 §4): `~1` -> `/`, then `~0` -> `~`, in that order.\n const refName = match?.[1].replace(/~1/g, '/').replace(/~0/g, '~');\n const resolved = refName ? componentRequestBodies?.[refName] : undefined;\n if (!resolved) {\n throw new Error(\n `Unresolved request body $ref \"${current.$ref}\" in ${operationContext}: no matching entry under components/requestBodies.`,\n );\n }\n current = resolved as unknown as RawRequestBodyObject;\n }\n\n return current;\n}\n\ninterface ResponseObject {\n description?: string;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\nexport interface OperationExtractionResult {\n services: Service[];\n inlineModels: Model[];\n}\n\nexport function extractOperations(\n paths: Record<string, PathItem> | undefined,\n operationIdTransform?: (id: string) => string,\n componentSchemas?: Record<string, SchemaObject>,\n componentParameters?: Record<string, Record<string, unknown>>,\n componentRequestBodies?: Record<string, Record<string, unknown>>,\n): OperationExtractionResult {\n if (!paths) return { services: [], inlineModels: [] };\n\n const serviceMap = new Map<string, Operation[]>();\n const inlineModels: Model[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n const pathLevelParams = pathItem.parameters ?? [];\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const serviceName = inferServiceName(path, op.tags?.[0]);\n\n const { operation, inlineModels: opModels } = buildOperation(\n method,\n path,\n op,\n pathLevelParams,\n operationIdTransform,\n serviceName,\n componentSchemas,\n componentParameters,\n componentRequestBodies,\n );\n inlineModels.push(...opModels);\n const ops = serviceMap.get(serviceName) ?? [];\n ops.push(operation);\n serviceMap.set(serviceName, ops);\n }\n }\n\n // Split services when a single tag groups operations from multiple path prefixes.\n // Example: /organizations and /organization_domains both tagged \"organizations\"\n // should become separate services based on their first path segment.\n for (const [serviceName, operations] of serviceMap) {\n const pathGroups = new Map<string, Operation[]>();\n for (const op of operations) {\n const firstSeg = op.path.split('/').filter(Boolean)[0] ?? '';\n const groupKey = firstSeg.startsWith('{') ? serviceName : toPascalCase(firstSeg);\n const group = pathGroups.get(groupKey) ?? [];\n group.push(op);\n pathGroups.set(groupKey, group);\n }\n // Only split if there are multiple distinct path-prefix groups AND\n // at least one group name differs from the current service name\n if (pathGroups.size > 1) {\n const needsSplit = [...pathGroups.keys()].some((k) => k !== serviceName);\n if (needsSplit) {\n serviceMap.delete(serviceName);\n for (const [groupName, groupOps] of pathGroups) {\n const existing = serviceMap.get(groupName) ?? [];\n existing.push(...groupOps);\n serviceMap.set(groupName, existing);\n }\n }\n }\n }\n\n // Disambiguate operation names within each service.\n // Multiple operations can get the same name (e.g., several \"list\" endpoints\n // in UserManagement for users, invitations, auth factors, etc.).\n for (const [, operations] of serviceMap) {\n disambiguateOperationNames(operations);\n }\n\n const services = Array.from(serviceMap.entries()).map(([name, operations]) => ({\n name,\n operations,\n }));\n\n return { services, inlineModels };\n}\n\nfunction inferServiceName(path: string, tag?: string): string {\n // Prefer OpenAPI tag when available — tags represent the logical grouping\n // (e.g., \"multi-factor-auth\" for /auth/factors/* endpoints).\n if (tag) {\n return toPascalCase(tag);\n }\n // Fallback: extract first meaningful path segment: /widgets/{id}/sub → \"Widgets\"\n const segments = path.split('/').filter(Boolean);\n const first = segments[0] ?? 'Default';\n // Skip path params\n if (first.startsWith('{')) return 'Default';\n return toPascalCase(first);\n}\n\n/**\n * Strip overload indices (e.g. NestJS emits `Foo_bar[0]` when a controller\n * method handles multiple routes) from an operationId so derived names never\n * leak the bracketed digit. Without this, `authenticate[0]` would surface as\n * `authenticate0` in method names and `Authenticate0Request` in body model\n * names. Brackets at the end (or with trailing whitespace) are common in\n * NestJS-style backends; this regex is intentionally narrow to avoid eating\n * legitimate digits like `oauth2`.\n */\nfunction normalizeOperationIdForNaming(operationId: string): string {\n return operationId.replace(/\\[\\d+\\]\\s*$/, '');\n}\n\nfunction inferOperationName(\n method: HttpMethod,\n path: string,\n operationId?: string,\n operationIdTransform?: (id: string) => string,\n): string {\n if (operationId) {\n const normalized = normalizeOperationIdForNaming(operationId);\n if (operationIdTransform) {\n return operationIdTransform(normalized);\n }\n return toCamelCase(normalized);\n }\n\n // Fallback when no operationId is available — use method + path to build\n // a descriptive name like \"listUsers\", \"getOrganization\", \"deleteAuthFactor\"\n const verb = inferVerb(method, path);\n const resource = inferResourceFromPath(path);\n return resource ? toCamelCase(`${verb}_${resource}`) : verb;\n}\n\n/**\n * Infer the CRUD verb from HTTP method and path shape.\n */\nfunction inferVerb(method: HttpMethod, path: string): string {\n const segments = path.split('/').filter(Boolean);\n const hasTrailingParam = segments.length > 0 && segments[segments.length - 1].startsWith('{');\n\n switch (method) {\n case 'get':\n return hasTrailingParam ? 'get' : 'list';\n case 'post':\n return 'create';\n case 'put':\n case 'patch':\n return 'update';\n case 'delete':\n return 'delete';\n case 'head':\n return 'check';\n case 'options':\n return 'options';\n case 'trace':\n return 'trace';\n default:\n return method;\n }\n}\n\n/**\n * Extract a resource noun from the path for operation naming.\n * Uses the last non-param segment (the resource being operated on).\n *\n * Examples:\n * /accounts/users → \"Users\"\n * /accounts/users/{id} → \"User\" (singular for item operations)\n * /accounts/users/{id}/auth_factors → \"AuthFactors\"\n * /organizations/{id}/api_keys → \"ApiKeys\"\n * /auth/authorize → \"Authorize\" (action endpoint)\n */\nfunction inferResourceFromPath(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n if (segments.length <= 1) return null;\n\n // Find the last meaningful (non-param) segment\n let resourceSegment: string | null = null;\n for (let i = segments.length - 1; i >= 0; i--) {\n if (!segments[i].startsWith('{')) {\n resourceSegment = segments[i];\n break;\n }\n }\n\n if (!resourceSegment) return null;\n // Skip the service name (first segment) — it would be redundant\n if (resourceSegment === segments[0]) return null;\n\n return toPascalCase(resourceSegment);\n}\n\n/**\n * Detect and resolve name collisions within a service's operations.\n *\n * When multiple operations share the same name (e.g., several \"list\" from\n * different sub-resources), disambiguate by appending the resource noun\n * from the path. Only renames operations on DIFFERENT paths — same-name\n * operations on the same path (e.g., PUT + PATCH both \"update\") are left as-is\n * since they represent the same logical resource.\n */\nfunction disambiguateOperationNames(operations: Operation[]): void {\n // Group by name\n const byName = new Map<string, Operation[]>();\n for (const op of operations) {\n const group = byName.get(op.name) ?? [];\n group.push(op);\n byName.set(op.name, group);\n }\n\n for (const [name, group] of byName) {\n if (group.length <= 1) continue;\n\n // Check if these are genuinely different resources (different paths)\n // vs the same resource with different methods (PUT + PATCH)\n const uniquePaths = new Set(group.map((op) => op.path));\n if (uniquePaths.size <= 1) continue; // same path, different methods — no disambiguation needed\n\n for (const op of group) {\n const resource = inferResourceFromPath(op.path);\n if (resource) {\n const newName = toCamelCase(`${name}_${resource}`);\n (op as { name: string }).name = newName;\n }\n }\n\n // If disambiguation still left collisions (same sub-resource),\n // use the full distinguishing path segment chain\n const renamed = new Map<string, Operation[]>();\n for (const op of group) {\n const rGroup = renamed.get(op.name) ?? [];\n rGroup.push(op);\n renamed.set(op.name, rGroup);\n }\n for (const [, rGroup] of renamed) {\n if (rGroup.length <= 1) continue;\n // Still colliding — different paths map to same resource name.\n // Use deeper path context to disambiguate.\n for (const op of rGroup) {\n const deeper = inferDeeperContext(op.path);\n if (deeper) {\n (op as { name: string }).name = toCamelCase(`${op.name}_${deeper}`);\n }\n }\n }\n }\n}\n\n/**\n * Extract a deeper disambiguation context from the path when the last\n * segment isn't unique enough. Uses the second-to-last non-param segment.\n *\n * /users/{id}/auth_factors → already captured as \"AuthFactors\"\n * /users/external_id/{external_id} → \"ExternalId\" (special path, not a sub-resource)\n */\nfunction inferDeeperContext(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n const nonParams = segments.filter((s) => !s.startsWith('{'));\n // Skip first (service) and last (already used) — use the middle ones\n if (nonParams.length >= 3) {\n return toPascalCase(nonParams.slice(1, -1).join('_'));\n }\n return null;\n}\n\n/**\n * Extract mutually-exclusive parameter groups from the `x-mutually-exclusive-parameter-groups`\n * operation extension. Cross-references grouped parameter names against the already-extracted\n * IR parameter arrays so emitters get object-identity references.\n */\nfunction extractParameterGroups(\n op: OperationObject,\n allIRParams: Parameter[],\n operationContext: string,\n): ParameterGroup[] | undefined {\n const raw = op['x-mutually-exclusive-parameter-groups'];\n if (!raw || typeof raw !== 'object') return undefined;\n\n const paramByName = new Map<string, Parameter>();\n for (const p of allIRParams) {\n paramByName.set(p.name, p);\n }\n\n const groups: ParameterGroup[] = [];\n\n for (const [groupName, groupDef] of Object.entries(raw)) {\n if (!groupDef || typeof groupDef !== 'object') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: expected an object with \"optional\" and \"variants\".`,\n );\n }\n\n if (typeof groupDef.optional !== 'boolean') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.optional in ${operationContext}: expected a boolean.`,\n );\n }\n\n if (!groupDef.variants || typeof groupDef.variants !== 'object') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants in ${operationContext}: expected an object mapping variant names to parameter name arrays.`,\n );\n }\n\n if (Object.keys(groupDef.variants).length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: group has zero variants.`,\n );\n }\n\n const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n if (!Array.isArray(paramNames) || paramNames.length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n );\n }\n const parameters: Parameter[] = paramNames.map((pName) => {\n const irParam = paramByName.get(pName);\n if (!irParam) {\n throw new Error(\n `x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} references parameter \"${pName}\" which does not exist in the operation's parameters[] (${operationContext}).`,\n );\n }\n return irParam;\n });\n return { name: variantName, parameters };\n });\n\n groups.push({\n name: groupName,\n optional: groupDef.optional,\n variants,\n });\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\n/**\n * Extract mutually-exclusive body parameter groups from the\n * `x-mutually-exclusive-body-groups` operation extension. Unlike query\n * parameter groups (whose parameters live in operation.queryParams), body\n * group parameters are synthetic — built from the oneOf variant schemas in\n * the request body. Emitters use the group's presence to generate sum-type\n * interfaces and custom JSON marshalling instead of flat optional fields.\n */\nfunction extractBodyParameterGroups(\n op: OperationObject,\n requestBody: RequestBodyObject | undefined,\n operationContext: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ParameterGroup[] | undefined {\n const raw = op['x-mutually-exclusive-body-groups'];\n if (!raw || typeof raw !== 'object') return undefined;\n\n // Collect the body schema's oneOf variant fields so we can resolve types.\n // The body schema has been structurally rewritten to allOf: [base, { oneOf: [...] }]\n // by the spec generator; the variant properties live inside oneOf branches.\n const bodySchema = requestBody?.content?.['application/json']?.schema;\n const variantFieldSchemas = collectVariantFieldSchemas(bodySchema, componentSchemas);\n\n const groups: ParameterGroup[] = [];\n\n for (const [groupName, groupDef] of Object.entries(raw)) {\n if (!groupDef || typeof groupDef !== 'object') continue;\n if (typeof groupDef.optional !== 'boolean') continue;\n if (!groupDef.variants || typeof groupDef.variants !== 'object') continue;\n if (Object.keys(groupDef.variants).length === 0) continue;\n\n const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n if (!Array.isArray(paramNames) || paramNames.length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n );\n }\n const parameters: Parameter[] = paramNames.map((pName) => {\n const entry = variantFieldSchemas.get(pName);\n const fieldSchema = entry?.schema;\n // No schema found means the body's oneOf branches don't declare this\n // member. Falling back to `string` silently produces an SDK that\n // type-checks against itself but misrepresents the wire contract\n // (object-valued members become plain strings), so say so loudly.\n if (!fieldSchema) {\n console.warn(\n `[oagen] Warning: x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} ` +\n `references \"${pName}\" in ${operationContext}, but no oneOf branch of the request body ` +\n `declares that property. Falling back to type: string.`,\n );\n }\n const fieldType: TypeRef = fieldSchema\n ? schemaToTypeRef(fieldSchema, toPascalCase(pName), entry?.owner)\n : { kind: 'primitive', type: 'string' };\n return {\n name: pName,\n type: fieldType,\n required: false, // group variant fields are always optional at the struct level\n description: fieldSchema?.description,\n };\n });\n\n // Optional variant membership: fields the caller may omit when using\n // this variant. Only names that actually belong to the variant count —\n // anything else in the extension is ignored rather than fatal.\n const rawOptionalFields =\n groupDef.optionalFields && typeof groupDef.optionalFields === 'object'\n ? groupDef.optionalFields[variantName]\n : undefined;\n const optionalParameters = Array.isArray(rawOptionalFields)\n ? rawOptionalFields.filter((name): name is string => typeof name === 'string' && paramNames.includes(name))\n : [];\n\n return {\n name: variantName,\n parameters,\n ...(optionalParameters.length > 0 ? { optionalParameters } : {}),\n };\n });\n\n groups.push({\n name: groupName,\n optional: groupDef.optional,\n variants,\n });\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\nfunction buildOperation(\n method: HttpMethod,\n path: string,\n op: OperationObject,\n pathLevelParams: RawParameterObject[],\n operationIdTransform?: (id: string) => string,\n serviceName?: string,\n componentSchemas?: Record<string, SchemaObject>,\n componentParameters?: Record<string, Record<string, unknown>>,\n componentRequestBodies?: Record<string, Record<string, unknown>>,\n): { operation: Operation; inlineModels: Model[] } {\n const opLabel = op.operationId ?? `${method.toUpperCase()} ${path}`;\n // Resolve a `components/requestBodies` ref up front so body extraction, body\n // parameter groups, and the body-ownership rule below all read one object.\n const requestBodyObject = resolveRequestBodyRef(op.requestBody, componentRequestBodies, opLabel);\n // An operation-level parameter overrides a path-level one with the same\n // (name, in) identity rather than adding a second entry. Operation params come\n // last, so last-write-wins; Map.set keeps the original insertion position, so\n // path-level parameter ordering is preserved.\n const paramsByIdentity = new Map<string, ParameterObject>();\n for (const raw of [...pathLevelParams, ...(op.parameters ?? [])]) {\n const param = resolveParameterRef(raw, componentParameters, opLabel);\n paramsByIdentity.set(`${param.in}:${param.name}`, param);\n }\n const allParams = [...paramsByIdentity.values()];\n\n const hasIdempotencyHeader = allParams.some((p) => p.in === 'header' && p.name.toLowerCase() === 'idempotency-key');\n\n // A parameter the spec declares both as `in: query` and as a request-body\n // property is one value with two wire locations. On a body-carrying method\n // it travels in the body only: duplicating it into the URL puts body-grade\n // material (OAuth codes, client secrets) into access logs and exception\n // traces, and emitters that surface both copies grow a second public\n // parameter for the same field. RFC 6749 §4.1.3 puts token-request\n // parameters in the body for the same reason. GET/DELETE keep every\n // declared query parameter — they have no body to prefer.\n //\n // One carve-out: a query parameter named by `x-mutually-exclusive-parameter-groups`\n // stays a parameter. The extension models it as one, the group resolver\n // below looks it up in the parameter arrays, and emitters already route\n // groups into the body on body-carrying methods, so nothing reaches the URL.\n const groupedQueryNames = collectParameterGroupMemberNames(op);\n const bodyOwnedNames = new Set<string>();\n if (BODY_CARRYING_METHODS.has(method)) {\n const bodySchema = selectRequestBodyContent(requestBodyObject).schema;\n for (const name of collectBodyPropertyNames(bodySchema, componentSchemas)) {\n if (!groupedQueryNames.has(name)) bodyOwnedNames.add(name);\n }\n }\n const wireParams =\n bodyOwnedNames.size > 0 ? allParams.filter((p) => !(p.in === 'query' && bodyOwnedNames.has(p.name))) : allParams;\n\n // Use the service name as context so inline parameter enums get qualified\n // names. e.g., service \"Auth\" + param \"provider\" → \"AuthProvider\".\n const opContext = serviceName;\n const pathParams = extractParams(wireParams, 'path', opContext, componentSchemas);\n const queryParams = extractParams(wireParams, 'query', opContext, componentSchemas);\n const headerParams = extractParams(wireParams, 'header', opContext, componentSchemas).filter(\n (p) => p.name.toLowerCase() !== 'idempotency-key',\n );\n const cookieParams = extractParams(wireParams, 'cookie', opContext, componentSchemas);\n // Keep the body-owned declarations on the operation so downstream passes\n // (inline-enum collection, the compat surface) still see what the spec\n // declared, even though no emitter serializes them to the URL.\n const bodyOwnedQueryParams =\n bodyOwnedNames.size > 0\n ? extractParams(\n allParams.filter((p) => p.in === 'query' && bodyOwnedNames.has(p.name)),\n 'query',\n opContext,\n componentSchemas,\n )\n : [];\n\n const reqBodyModels: Model[] = [];\n const { body: requestBody, encoding: requestBodyEncoding } = extractRequestBody(requestBodyObject, op, reqBodyModels);\n const {\n response,\n successResponses,\n errors,\n inlineModels,\n isPaginated,\n dataPath: responseDataPath,\n itemType: responseItemType,\n } = extractResponses(op.responses, op, path, method, componentSchemas);\n inlineModels.push(...reqBodyModels);\n\n // Build structured pagination metadata from response classification and query param detection\n const paginationFromParams = detectPagination(response, queryParams, responseDataPath);\n let pagination: PaginationMeta | undefined;\n if (isPaginated) {\n const itemType = responseItemType ?? (response.kind === 'array' ? response.items : response);\n pagination = {\n strategy: paginationFromParams?.strategy ?? 'cursor',\n param: paginationFromParams?.param ?? 'after',\n limitParam: paginationFromParams?.limitParam,\n dataPath: responseDataPath ?? paginationFromParams?.dataPath,\n itemType,\n };\n } else if (paginationFromParams) {\n pagination = paginationFromParams;\n }\n\n // Extract per-operation security overrides\n const security = extractOperationSecurity(op.security);\n\n // Extract mutually-exclusive parameter groups (query/path/header/cookie)\n const allIRParams = [...pathParams, ...queryParams, ...headerParams, ...cookieParams];\n const queryParamGroups = extractParameterGroups(op, allIRParams, opLabel);\n\n // Extract mutually-exclusive body parameter groups\n const bodyParamGroups = extractBodyParameterGroups(op, requestBodyObject, opLabel, componentSchemas);\n\n // Merge both sources into a single parameterGroups array\n const parameterGroups =\n queryParamGroups || bodyParamGroups ? [...(queryParamGroups ?? []), ...(bodyParamGroups ?? [])] : undefined;\n\n return {\n operation: {\n name: inferOperationName(method, path, op.operationId, operationIdTransform),\n description: buildDescription(op.summary, op.description),\n httpMethod: method,\n path,\n pathParams,\n queryParams,\n bodyOwnedQueryParams: bodyOwnedQueryParams.length > 0 ? bodyOwnedQueryParams : undefined,\n headerParams,\n cookieParams: cookieParams.length > 0 ? cookieParams : undefined,\n requestBody,\n requestBodyEncoding,\n response,\n successResponses,\n errors,\n pagination,\n injectIdempotencyKey: hasIdempotencyHeader,\n deprecated: op.deprecated || undefined,\n async: op['x-oagen-async'],\n security,\n parameterGroups,\n },\n inlineModels,\n };\n}\n\n/**\n * Extract per-operation security requirements from an OpenAPI security directive.\n * Returns undefined when the operation uses the spec-level default security.\n *\n * OpenAPI security format: `security: [{ schemeName: [scope1, scope2] }]`\n */\nfunction extractOperationSecurity(\n security: Array<Record<string, string[]>> | undefined,\n): SecurityRequirement[] | undefined {\n if (!security || security.length === 0) return undefined;\n\n const requirements: SecurityRequirement[] = [];\n for (const entry of security) {\n for (const [schemeName, scopes] of Object.entries(entry)) {\n requirements.push({ schemeName, scopes: scopes ?? [] });\n }\n }\n return requirements.length > 0 ? requirements : undefined;\n}\n\nfunction buildDescription(summary: string | undefined, description: string | undefined): string | undefined {\n if (summary && description && summary !== description) {\n return `${summary}\\n\\n${description}`;\n }\n return description ?? summary;\n}\n\nfunction extractParams(\n params: ParameterObject[],\n location: 'path' | 'query' | 'header' | 'cookie',\n operationContext?: string,\n componentSchemas?: Record<string, SchemaObject>,\n): Parameter[] {\n return params\n .filter((p) => p.in === location)\n .map((p) => {\n const refTarget = resolveParamSchemaRef(p.schema, componentSchemas);\n return {\n name: p.name,\n type: p.schema\n ? schemaToTypeRef(p.schema, p.name, operationContext ? toPascalCase(operationContext) : undefined)\n : ({ kind: 'primitive', type: 'string' } as TypeRef),\n required: p.required ?? false,\n description: p.description,\n deprecated: p.deprecated || p.schema?.deprecated || refTarget?.deprecated || undefined,\n default: p.schema?.default ?? refTarget?.default,\n example: p.example ?? p.schema?.example ?? refTarget?.example,\n style: p.style as Parameter['style'],\n explode: p.explode,\n };\n });\n}\n\n/**\n * If a parameter's schema is a `$ref` to `#/components/schemas/X`, return the\n * referenced component schema. Used to surface schema-level metadata (default,\n * example, deprecated) that wouldn't otherwise be visible at the param level.\n *\n * Refs are not pre-resolved by the bundler (`dereference: false` in refs.ts),\n * so without this, a param like `schema: { $ref: '.../PaginationOrder' }`\n * silently loses the target's `default: desc` and the SDK stops emitting the\n * spec-mandated default value in generated method signatures.\n */\nfunction resolveParamSchemaRef(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n): SchemaObject | undefined {\n if (!schema || !componentSchemas) return undefined;\n const ref = (schema as { $ref?: string }).$ref;\n if (!ref) return undefined;\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n if (!match) return undefined;\n return componentSchemas[match[1]];\n}\n\n/**\n * Collect the property schemas of every `oneOf` branch reachable from a request\n * body schema, keyed by property name. These are the candidate members of a\n * mutually-exclusive body group.\n *\n * The bundler runs with `dereference: false`, so the body schema is very often\n * a bare `{ $ref: '#/components/schemas/XDto' }` and the `allOf`/`oneOf`\n * composition that actually declares the variant properties lives on the\n * component. Walking without resolving refs finds nothing, and every group\n * member then falls back to `string` — an SDK that compiles but types\n * object-valued members (e.g. a connection's `saml_options`) as plain strings.\n *\n * Composition keywords nest and may themselves be refs, so resolve and recurse\n * at each level. `seen` guards against a schema that (directly or transitively)\n * refs itself.\n */\nfunction collectVariantFieldSchemas(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n owner: string | undefined = undefined,\n out: Map<string, VariantFieldSchema> = new Map(),\n seen: Set<string> = new Set(),\n): Map<string, VariantFieldSchema> {\n if (!schema) return out;\n\n const ref = (schema as { $ref?: string }).$ref;\n if (ref) {\n if (seen.has(ref)) return out;\n seen.add(ref);\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n const target = match && componentSchemas ? componentSchemas[match[1]] : undefined;\n // Descending into a component makes it the owner of everything below, so\n // inline members get the same synthesized names the model emitter gives\n // them (`CreateUser` + `password_hash_type` -> CreateUserPasswordHashType).\n const nextOwner = match ? resolveSchemaName(match[1]) : owner;\n return collectVariantFieldSchemas(target, componentSchemas, nextOwner, out, seen);\n }\n\n // A `oneOf` branch is the group-variant carrier: its properties are the\n // members. Record them, then keep descending — branches nest in real specs.\n for (const variant of schema.oneOf ?? []) {\n const variantRef = (variant as { $ref?: string }).$ref;\n const refMatch = variantRef ? /^#\\/components\\/schemas\\/(.+)$/.exec(variantRef) : null;\n const resolved = resolveSchemaRefObject(variant, componentSchemas) ?? variant;\n const variantOwner = refMatch ? resolveSchemaName(refMatch[1]) : owner;\n for (const [name, fieldSchema] of Object.entries(resolved.properties ?? {})) {\n if (fieldSchema) out.set(name, { schema: fieldSchema, owner: variantOwner });\n }\n collectVariantFieldSchemas(variant, componentSchemas, owner, out, seen);\n }\n\n for (const sub of schema.allOf ?? []) collectVariantFieldSchemas(sub, componentSchemas, owner, out, seen);\n for (const sub of schema.anyOf ?? []) collectVariantFieldSchemas(sub, componentSchemas, owner, out, seen);\n\n return out;\n}\n\n/** A group member's schema plus the component that owns it, for inline naming. */\ninterface VariantFieldSchema {\n schema: SchemaObject;\n owner: string | undefined;\n}\n\n/** Resolve `{ $ref: '#/components/schemas/X' }` to its component, else undefined. */\nfunction resolveSchemaRefObject(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n): SchemaObject | undefined {\n if (!schema || !componentSchemas) return undefined;\n const ref = (schema as { $ref?: string }).$ref;\n if (!ref) return undefined;\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n if (!match) return undefined;\n return componentSchemas[match[1]];\n}\n\ntype RequestBodyEncoding = 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n\n/** HTTP methods whose request body is the primary parameter carrier. */\nconst BODY_CARRYING_METHODS: ReadonlySet<HttpMethod> = new Set<HttpMethod>(['post', 'put', 'patch']);\n\n/**\n * Pick the request body's schema and wire encoding from its content map, in\n * priority order. JSON wins over form encodings; binary and text bodies may\n * legitimately carry no schema at all.\n */\nfunction selectRequestBodyContent(body: RequestBodyObject | undefined): {\n encoding: RequestBodyEncoding;\n schema?: SchemaObject;\n} {\n const content = body?.content;\n if (!content) return { encoding: 'json' };\n if (content['application/json']?.schema) {\n return { encoding: 'json', schema: content['application/json'].schema };\n }\n if (content['multipart/form-data']?.schema) {\n return { encoding: 'form-data', schema: content['multipart/form-data'].schema };\n }\n if (content['application/x-www-form-urlencoded']?.schema) {\n return { encoding: 'form-urlencoded', schema: content['application/x-www-form-urlencoded'].schema };\n }\n if (content['application/octet-stream']) {\n return { encoding: 'binary', schema: content['application/octet-stream'].schema };\n }\n if (content['text/plain']) {\n return { encoding: 'text', schema: content['text/plain'].schema };\n }\n return { encoding: 'json' };\n}\n\n/** Parameter names referenced by any `x-mutually-exclusive-parameter-groups` variant. */\nfunction collectParameterGroupMemberNames(op: OperationObject): Set<string> {\n const names = new Set<string>();\n const raw = op['x-mutually-exclusive-parameter-groups'];\n if (!raw || typeof raw !== 'object') return names;\n // Malformed shapes are left for extractParameterGroups to report.\n for (const groupDef of Object.values(raw)) {\n const variants = groupDef && typeof groupDef === 'object' ? groupDef.variants : undefined;\n if (!variants || typeof variants !== 'object') continue;\n for (const members of Object.values(variants)) {\n if (!Array.isArray(members)) continue;\n for (const member of members) if (typeof member === 'string') names.add(member);\n }\n }\n return names;\n}\n\n/**\n * Every property name a request body is guaranteed to accept, following\n * `$ref`s and descending through composition. `allOf` members all apply, so\n * their properties union. `oneOf` / `anyOf` alternatives are choices, so only\n * a property every non-null alternative declares counts — otherwise a caller\n * on another branch would have no slot for the value in either the body or\n * the query. Used to decide which `in: query` declarations are body-owned.\n */\nfunction collectBodyPropertyNames(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n seen: ReadonlySet<string> = new Set(),\n): Set<string> {\n if (!schema) return new Set();\n\n const ref = (schema as { $ref?: string }).$ref;\n if (ref) {\n // Cycle guard is per path: the same component may legitimately appear in\n // sibling branches and must count for each of them.\n if (seen.has(ref)) return new Set();\n return collectBodyPropertyNames(\n resolveSchemaRefObject(schema, componentSchemas),\n componentSchemas,\n new Set([...seen, ref]),\n );\n }\n\n const names = new Set(Object.keys(schema.properties ?? {}));\n for (const sub of schema.allOf ?? []) {\n for (const name of collectBodyPropertyNames(sub, componentSchemas, seen)) names.add(name);\n }\n for (const alternatives of [schema.oneOf, schema.anyOf]) {\n const branches = (alternatives ?? []).filter((alt) => alt.type !== 'null');\n if (branches.length === 0) continue;\n let common: Set<string> | undefined;\n for (const branch of branches) {\n const branchNames = collectBodyPropertyNames(branch, componentSchemas, seen);\n common = common ? new Set([...common].filter((name) => branchNames.has(name))) : branchNames;\n }\n for (const name of common ?? []) names.add(name);\n }\n return names;\n}\n\nfunction extractRequestBody(\n body: RequestBodyObject | undefined,\n op: OperationObject | undefined,\n inlineModels: Model[],\n): { body?: TypeRef; encoding?: RequestBodyEncoding } {\n if (!body?.content) return {};\n\n const selected = selectRequestBodyContent(body);\n const encoding = selected.encoding;\n let schema = selected.schema;\n\n if (!schema) {\n // For binary/text, a schema is optional — produce a primitive TypeRef\n if (encoding === 'binary') {\n return { body: { kind: 'primitive', type: 'string', format: 'binary' }, encoding };\n }\n if (encoding === 'text') {\n return { body: { kind: 'primitive', type: 'string' }, encoding };\n }\n return {};\n }\n\n const rawName = op?.operationId\n ? toPascalCase(normalizeOperationIdForNaming(op.operationId)) + 'Request'\n : 'RequestBody';\n const contextName = cleanSchemaName(rawName);\n\n // A discriminated-union request body (`oneOf` + an explicit `discriminator`)\n // compiles to a `oneOf` that code generators can't spread into named method\n // arguments — the caller is handed an opaque union and the generated snippets\n // carry no body fields. When every variant is an inline object pinned by a\n // string-const discriminator, the union is equivalent to a single object, so\n // fold it into that object and let the normal object path below emit\n // ergonomic, spread-able arguments. See flattenDiscriminatedUnionBody.\n if (schema.oneOf && schema.discriminator) {\n const merged = flattenDiscriminatedUnionBody(schema);\n if (merged) schema = merged;\n }\n\n // If the request body is an inline object with properties, extract it as a model\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, contextName, requiredSet));\n }\n inlineModels.push({ name: contextName, description: undefined, fields });\n // Nested inline objects (e.g. a `user` property that is itself an inline\n // object) are referenced by name from the fields above but are not emitted\n // by this branch. Recurse to materialize them, matching how component\n // schemas are handled in extractInlineModelsFromSchemas — otherwise the\n // generated body model references a model that never gets generated.\n extractInlineModelsFromProperties(schema, inlineModels, contextName);\n return { body: { kind: 'model', name: contextName }, encoding };\n }\n\n // If the request body is a oneOf, extract each variant as an inline model\n // and build a union type pointing to them by name.\n if (schema.oneOf) {\n const variants: TypeRef[] = [];\n\n for (const variant of schema.oneOf) {\n if (variant.$ref) {\n const ref = schemaToTypeRef(variant, contextName);\n variants.push(ref);\n } else if (variant.type === 'null') {\n // skip null variant in union, handle separately\n } else if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const variantName = deriveOneOfVariantName(variant, contextName, inlineModels);\n const requiredSet = new Set(variant.required ?? []);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, variantName, requiredSet));\n }\n inlineModels.push({ name: variantName, description: variant.description, fields });\n extractInlineModelsFromProperties(variant, inlineModels, variantName);\n variants.push({ kind: 'model', name: variantName });\n } else {\n variants.push(schemaToTypeRef(variant, contextName));\n }\n }\n\n const hasNull = schema.oneOf.some(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n const union: TypeRef = {\n kind: 'union',\n variants,\n ...(schema.discriminator\n ? {\n discriminator: { property: schema.discriminator.propertyName, mapping: schema.discriminator.mapping ?? {} },\n }\n : {}),\n };\n const body = hasNull ? ({ kind: 'nullable', inner: union } as TypeRef) : union;\n return { body, encoding };\n }\n\n return { body: schemaToTypeRef(schema, contextName), encoding };\n}\n\n/**\n * Fold a discriminated-union request body into the equivalent single object so\n * its fields can be spread into method arguments instead of forcing callers to\n * construct an opaque union.\n *\n * The result is the union of every variant's properties: the discriminator is\n * collapsed to an enum of the pinned const values, and any field that isn't\n * present-and-required in *every* variant becomes optional (it varies by\n * branch, so it can't be unconditionally required). The discriminator itself is\n * always required. This mirrors what a spec author would write by hand to model\n * the same shape as a flat object.\n *\n * Returns null — leaving the union intact — unless the body is a clean\n * inline-object discriminated union: a variant that is a `$ref`, a non-object,\n * or that doesn't pin the discriminator to a string const can't be safely\n * merged. Gating on an *explicit* `discriminator` keeps undiscriminated `oneOf`\n * bodies untouched.\n */\nfunction flattenDiscriminatedUnionBody(schema: SchemaObject): SchemaObject | null {\n const discProp = schema.discriminator?.propertyName;\n if (!discProp || !Array.isArray(schema.oneOf) || schema.oneOf.length === 0) return null;\n\n const variants = schema.oneOf as SchemaObject[];\n const discValues: string[] = [];\n let discPropSchema: SchemaObject | undefined;\n\n for (const variant of variants) {\n // Every variant must be an inline object that pins the discriminator to a\n // string const (or single-value enum); anything else can't be merged.\n if (variant.$ref || !variant.properties || !(variant.type === 'object' || variant.type === undefined)) {\n return null;\n }\n const dp = variant.properties[discProp] as SchemaObject | undefined;\n const constVal =\n typeof dp?.const === 'string'\n ? dp.const\n : Array.isArray(dp?.enum) && dp.enum.length === 1 && typeof dp.enum[0] === 'string'\n ? dp.enum[0]\n : undefined;\n if (constVal === undefined) return null;\n if (!discValues.includes(constVal)) discValues.push(constVal);\n if (!discPropSchema) discPropSchema = dp;\n }\n\n const variantCount = variants.length;\n const mergedProps: Record<string, SchemaObject> = {};\n const requiredCounts: Record<string, number> = {};\n const order: string[] = [discProp]; // discriminator leads the merged object\n\n for (const variant of variants) {\n const required = new Set(variant.required ?? []);\n for (const [name, propSchema] of Object.entries(variant.properties!)) {\n if (name === discProp || !propSchema) continue;\n if (!(name in mergedProps)) {\n mergedProps[name] = propSchema as SchemaObject;\n order.push(name);\n }\n if (required.has(name)) requiredCounts[name] = (requiredCounts[name] ?? 0) + 1;\n }\n }\n\n // The discriminator collapses to an enum of the pinned values.\n mergedProps[discProp] = {\n type: 'string',\n enum: discValues,\n ...(discPropSchema?.description ? { description: discPropSchema.description } : {}),\n };\n\n const properties: Record<string, SchemaObject> = {};\n for (const name of order) properties[name] = mergedProps[name];\n\n // Required only when required in every variant; the discriminator is always\n // required.\n const requiredFields = order.filter((name) => name === discProp || requiredCounts[name] === variantCount);\n\n return {\n type: 'object',\n properties,\n required: requiredFields,\n ...(schema.description ? { description: schema.description } : {}),\n };\n}\n\n/** Derive a unique variant name for a oneOf inline model. */\nfunction deriveOneOfVariantName(variant: SchemaObject, baseName: string, existingModels: Model[]): string {\n // Try to use a distinguishing property (e.g., \"grant_type\" field's const/enum value)\n if (variant.properties) {\n for (const [, propSchema] of Object.entries(variant.properties)) {\n if (propSchema?.const && typeof propSchema.const === 'string') {\n const derivedName = toPascalCase(propSchema.const) + baseName.replace(/Request$/, '') + 'Request';\n // Const-derived request variants are IR models too, so they must use\n // the same project-level naming policy as component schemas.\n return resolveSchemaName(derivedName);\n }\n }\n }\n // Fallback: append a numeric suffix\n const existingNames = new Set(existingModels.map((m) => m.name));\n // Apply the transform before suffixing so every fallback candidate stays in\n // the same post-schemaNameTransform namespace as the rest of the IR.\n const transformedBaseName = resolveSchemaName(baseName);\n let name = transformedBaseName;\n let suffix = 2;\n while (existingNames.has(name)) {\n name = `${transformedBaseName}${suffix}`;\n suffix++;\n }\n return name;\n}\n\nfunction deriveResponseName(op: OperationObject | undefined, path: string, method: HttpMethod): string {\n if (op?.operationId) {\n return cleanSchemaName(toPascalCase(normalizeOperationIdForNaming(op.operationId)) + 'Response');\n }\n const segments = path.split('/').filter(Boolean);\n const resource = segments[0] ?? 'Unknown';\n return toPascalCase(resource) + toPascalCase(method) + 'Response';\n}\n\nfunction extractResponses(\n responses?: Record<string, ResponseObject>,\n op?: OperationObject,\n path?: string,\n method?: HttpMethod,\n componentSchemas?: Record<string, SchemaObject>,\n): {\n response: TypeRef;\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n inlineModels: Model[];\n isPaginated: boolean;\n dataPath?: string;\n itemType?: TypeRef;\n} {\n const errors: ErrorResponse[] = [];\n let response: TypeRef = { kind: 'primitive', type: 'string' };\n let inlineModels: Model[] = [];\n let isPaginated = false;\n let dataPath: string | undefined;\n let itemType: TypeRef | undefined;\n\n if (!responses) return { response, errors, inlineModels, isPaginated };\n\n const allSuccessResponses: SuccessResponse[] = [];\n\n for (const [statusCode, resp] of Object.entries(responses)) {\n const code = parseInt(statusCode, 10);\n\n if (code >= 200 && code < 300) {\n let extractedType: TypeRef = { kind: 'primitive', type: 'unknown' };\n const jsonContent = resp.content?.['application/json'];\n if (jsonContent?.schema) {\n const contextName = deriveResponseName(op, path ?? '/', method ?? 'get');\n const result = classifyAndExtractResponse(jsonContent.schema, contextName, componentSchemas);\n extractedType = result.response;\n // Keep track of inline models and pagination from the latest 2xx with a schema\n inlineModels = result.inlineModels;\n isPaginated = result.isPaginated;\n dataPath = result.dataPath;\n itemType = result.itemType;\n } else if (resp.content) {\n // Handle non-JSON response content types (text/plain, binary, XML, etc.)\n if (resp.content['application/octet-stream'] || resp.content['application/pdf']) {\n extractedType = { kind: 'primitive', type: 'string', format: 'binary' };\n } else if (\n resp.content['text/plain'] ||\n resp.content['text/html'] ||\n resp.content['text/xml'] ||\n resp.content['application/xml']\n ) {\n extractedType = { kind: 'primitive', type: 'string' };\n } else {\n // Try the first available content type's schema\n const firstKey = Object.keys(resp.content)[0];\n if (firstKey) {\n const firstContent = resp.content[firstKey];\n if (firstContent?.schema) {\n extractedType = schemaToTypeRef(\n firstContent.schema,\n deriveResponseName(op, path ?? '/', method ?? 'get'),\n );\n }\n }\n }\n }\n allSuccessResponses.push({ statusCode: code, type: extractedType });\n } else if (code >= 300 && code < 400) {\n // 3xx redirects — include so emitter can detect redirect endpoints\n allSuccessResponses.push({ statusCode: code, type: { kind: 'primitive', type: 'unknown' } });\n } else if (code >= 400) {\n const jsonContent = resp.content?.['application/json'];\n const type = jsonContent?.schema ? schemaToTypeRef(jsonContent.schema, `Error${code}`) : undefined;\n errors.push({ statusCode: code, type });\n }\n }\n\n // Primary response = lowest 2xx with a body schema, falling back to first 2xx\n if (allSuccessResponses.length > 0) {\n const sorted = [...allSuccessResponses].sort((a, b) => a.statusCode - b.statusCode);\n const primary =\n sorted.find((r) => r.type.kind !== 'primitive' || (r.type as { type: string }).type !== 'unknown') ?? sorted[0];\n response = primary.type;\n }\n\n const successResponses = allSuccessResponses.length > 1 ? allSuccessResponses : undefined;\n\n return { response, successResponses, errors, inlineModels, isPaginated, dataPath, itemType };\n}\n","import type { Model, Service, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nfunction keepLargestByName(models: Model[]): Model[] {\n const byName = new Map<string, Model>();\n for (const model of models) {\n const existing = byName.get(model.name);\n if (!existing || model.fields.length > existing.fields.length) {\n byName.set(model.name, model);\n }\n }\n return [...byName.values()];\n}\n\nfunction rewriteModelRef(ref: TypeRef, oldName: string, newName: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (r.name === oldName) (r as { name: string }).name = newName;\n },\n });\n}\n\nfunction rewriteModelRefs(models: Model[], services: Service[], oldName: string, newName: string): void {\n for (const model of models) {\n for (const field of model.fields) {\n rewriteModelRef(field.type, oldName, newName);\n }\n }\n for (const service of services) {\n for (const op of service.operations) {\n rewriteModelRef(op.response, oldName, newName);\n if (op.requestBody) {\n rewriteModelRef(op.requestBody, oldName, newName);\n }\n }\n }\n}\n\nexport function mergeInlineResponseModels(schemaModels: Model[], inlineModels: Model[]): Model[] {\n const mergedSchemaModels = [...schemaModels];\n const schemaModelNames = new Set(mergedSchemaModels.map((m) => m.name));\n const schemaModelsByName = new Map(mergedSchemaModels.map((m) => [m.name, m]));\n\n const deduplicatedInlineModels = inlineModels.filter((model) => {\n if (!schemaModelNames.has(model.name)) return true;\n\n const existing = schemaModelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference && model.fields.length > existing.fields.length) {\n const idx = mergedSchemaModels.indexOf(existing);\n if (idx !== -1) mergedSchemaModels[idx] = model;\n schemaModelsByName.set(model.name, model);\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has more fields than component schema (${model.fields.length} vs ${existing.fields.length}) — using inline response model`,\n );\n } else if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...mergedSchemaModels, ...keepLargestByName(deduplicatedInlineModels)];\n}\n\nexport function mergeFieldInlineModels(existingModels: Model[], fieldInlineModels: Model[]): Model[] {\n const modelNames = new Set(existingModels.map((m) => m.name));\n const modelsByName = new Map(existingModels.map((m) => [m.name, m]));\n\n const deduplicatedFieldModels = fieldInlineModels.filter((model) => {\n if (!modelNames.has(model.name)) return true;\n\n const existing = modelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...existingModels, ...keepLargestByName(deduplicatedFieldModels)];\n}\n\nfunction hasModelConstDiscriminant(model: Model): boolean {\n return model.fields.some(\n (f) => (f.name === 'object' || f.name === 'type') && f.type.kind === 'literal' && typeof f.type.value === 'string',\n );\n}\n\nfunction isModelReferencedByOthers(name: string, models: Model[], excludeNames: Set<string>): boolean {\n for (const model of models) {\n if (excludeNames.has(model.name)) continue;\n for (const field of model.fields) {\n let found = false;\n walkTypeRef(field.type, {\n model: (r) => {\n if (r.name === name) found = true;\n },\n });\n if (found) return true;\n }\n }\n return false;\n}\n\nexport function collapseJsonSuffixModels(models: Model[], services: Service[]): Model[] {\n const normalizedModels = [...models];\n const byName = new Map(normalizedModels.map((m) => [m.name, m]));\n\n // Pass 1: collect merge candidates\n const mergeCandidates: Array<{ jsonModel: Model; baseModel: Model }> = [];\n for (const model of normalizedModels) {\n if (!model.name.endsWith('Json')) continue;\n\n const baseName = model.name.slice(0, -4);\n const baseModel = byName.get(baseName);\n if (!baseModel || model.fields.length <= baseModel.fields.length) continue;\n\n const isSuperset = baseModel.fields.every((f) => model.fields.some((mf) => mf.name === f.name));\n if (!isSuperset) continue;\n\n // Guard: both models have a const discriminant — they are distinct entities\n if (hasModelConstDiscriminant(model) && hasModelConstDiscriminant(baseModel)) continue;\n\n // Guard: a third model explicitly references the Json-suffix model\n if (isModelReferencedByOthers(model.name, normalizedModels, new Set([model.name, baseName]))) continue;\n\n mergeCandidates.push({ jsonModel: model, baseModel });\n }\n\n // Pass 2: apply merges\n const toRemove = new Set<string>();\n for (const { jsonModel, baseModel } of mergeCandidates) {\n baseModel.fields = jsonModel.fields;\n toRemove.add(jsonModel.name);\n rewriteModelRefs(normalizedModels, services, jsonModel.name, baseModel.name);\n console.warn(\n `[oagen] Merged \"${jsonModel.name}\" into \"${baseModel.name}\" (${jsonModel.fields.length} fields, superset)`,\n );\n }\n\n // Pass 3: cascade renames to inline children of collapsed Json-suffix models.\n // e.g. when AuditLogSchemaJson → AuditLogSchema, also rename\n // AuditLogSchemaJsonTarget → AuditLogSchemaTarget.\n for (const { jsonModel, baseModel } of mergeCandidates) {\n const jsonPrefix = jsonModel.name;\n const basePrefix = baseModel.name;\n\n for (const model of normalizedModels) {\n if (toRemove.has(model.name)) continue;\n if (model.name.length <= jsonPrefix.length) continue;\n if (!model.name.startsWith(jsonPrefix)) continue;\n\n const newName = basePrefix + model.name.slice(jsonPrefix.length);\n const existing = byName.get(newName);\n\n if (existing && !toRemove.has(existing.name)) {\n toRemove.add(model.name);\n rewriteModelRefs(normalizedModels, services, model.name, newName);\n console.warn(`[oagen] Collapsed child \"${model.name}\" into existing \"${newName}\"`);\n } else {\n rewriteModelRefs(normalizedModels, services, model.name, newName);\n model.name = newName;\n byName.set(newName, model);\n console.warn(`[oagen] Renamed child \"${jsonPrefix}…\" → \"${newName}\"`);\n }\n }\n }\n\n return normalizedModels.filter((m) => !toRemove.has(m.name));\n}\n","import type { Enum, Model, Service } from '../ir/types.js';\nimport { collectInlineEnumFromRef } from './schemas.js';\n\nexport function collectInlineEnumsFromModels(models: Model[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const model of models) {\n for (const field of model.fields) {\n collectInlineEnumFromRef(field.type, enums, enumNames);\n }\n }\n}\n\n/**\n * Collect inline enum definitions from operation parameters (query, path, header)\n * and promote them to top-level enums so emitters can generate typed enum files.\n */\nexport function collectInlineEnumsFromOperations(services: Service[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const service of services) {\n for (const op of service.operations) {\n for (const param of [\n ...op.pathParams,\n ...op.queryParams,\n ...(op.bodyOwnedQueryParams ?? []),\n ...op.headerParams,\n ...(op.cookieParams ?? []),\n ]) {\n collectInlineEnumFromRef(param.type, enums, enumNames);\n }\n }\n }\n}\n","import type {\n ApiSpec,\n Enum,\n Model,\n Operation,\n Parameter,\n ParameterGroup,\n ParameterGroupVariant,\n Service,\n TypeRef,\n} from '../ir/types.js';\n\n/**\n * Assign `ParameterGroup.wrapperName` across the whole spec.\n *\n * Emitters derive a group's generated wrapper type name from the group name\n * alone, so two operations sharing a group name (create and update both\n * declare `protocol_options`) collapse onto a single type. That is only sound\n * while the two declarations carry the same members. Where they differ, one\n * operation ends up typed with the other's member — e.g. a connection update\n * forced to pass `CreateConnectionSAMLOptions`, which accepts three fields the\n * PATCH endpoint rejects.\n *\n * This pass fingerprints every group's members structurally and qualifies the\n * wrapper name with the operation name only for groups that genuinely diverge.\n * Groups whose declarations agree keep the bare group name, so wrapper types\n * already published in the SDKs are never renamed.\n */\nexport function assignParameterGroupWrapperNames(spec: ApiSpec): void {\n const modelMap = new Map(spec.models.map((m) => [m.name, m]));\n const enumMap = new Map(spec.enums.map((e) => [e.name, e]));\n\n // group name -> the distinct structural fingerprints seen for it\n const fingerprints = new Map<string, Set<string>>();\n const occurrences: Occurrence[] = [];\n\n for (const service of spec.services) {\n for (const op of service.operations) {\n for (const group of op.parameterGroups ?? []) {\n const fp = fingerprintGroup(group, modelMap, enumMap);\n let seen = fingerprints.get(group.name);\n if (!seen) {\n seen = new Set();\n fingerprints.set(group.name, seen);\n }\n seen.add(fp);\n occurrences.push({ service, op, group, fingerprint: fp });\n }\n }\n }\n\n for (const { op, group } of occurrences) {\n const diverges = (fingerprints.get(group.name)?.size ?? 0) > 1;\n group.wrapperName = diverges ? `${op.name}_${group.name}` : group.name;\n }\n\n qualifyResidualCollisions(occurrences);\n reconcileSharedGroups(occurrences.map((o) => o.group));\n}\n\ninterface Occurrence {\n service: Service;\n op: Operation;\n group: ParameterGroup;\n fingerprint: string;\n}\n\n/**\n * Break the collisions the operation-qualified name can still leave behind.\n *\n * `${op.name}_${group.name}` is not a unique key, for two separate reasons:\n *\n * - `disambiguateOperationNames` makes operation names unique only *within* a\n * service, so two services that each own an operation named `create`, both\n * declaring a `password` group with different members, both land on\n * `create_password`.\n * - Within one service it deliberately leaves same-name operations alone when\n * they share a path (see the `uniquePaths.size <= 1` guard — \"same path,\n * different methods\"), so `PUT` and `PATCH` on one path both stay `update`\n * and a service prefix alone still produces one name for both.\n *\n * Either way `reconcileSharedGroups` would then fuse two incompatible\n * declarations into a single type — the exact failure this pass exists to\n * prevent — and it does not drop the surplus member, so the wrapper would\n * expose a field one of the operations rejects.\n *\n * So escalate in rounds, adding a qualifier at a time and re-testing what still\n * collides. `(service, path, method)` identifies an operation uniquely, and a\n * same-name collision within a service implies a shared path, so service then\n * method is sufficient to separate every case.\n *\n * Each round only touches names that *still* group differing fingerprints, so a\n * name whose sharers agree is never renamed: sharing one wrapper is exactly what\n * should happen there, and renaming it would move a type the SDKs already\n * publish. On a spec where no qualified name collides — the WorkOS spec today —\n * the whole pass is a no-op.\n */\nfunction qualifyResidualCollisions(occurrences: Occurrence[]): void {\n // Prepended in order, matching how the operation and group names already\n // compose, so a fully-escalated name reads `<method>_<service>_<op>_<group>`.\n const qualifiers: ((o: Occurrence) => string)[] = [(o) => o.service.name, (o) => o.op.httpMethod];\n\n for (const qualify of qualifiers) {\n for (const sharers of collidingCandidates(occurrences)) {\n // A declaration still holding its group's own bare name owns that name.\n // A qualified name can land on some *other* group's literal name — an\n // `update` operation's `parent` group qualifies to `update_parent`, which\n // may already be a group called `update_parent` — and that group is\n // internally consistent, never diverged, and already published under it.\n // Move only the declarations that have already been escalated; anything\n // left fused falls through to the terminal round.\n //\n // This cannot strand a collision. Two groups sharing a literal name with\n // differing structures always diverge on that name and are both qualified\n // in the first assignment, so at most one member of a colliding set can\n // still be bare. When one is, moving the rest separates them; in the\n // degenerate case where none are movable, nothing moves here and the\n // terminal round separates by structure regardless.\n const movable = sharers.filter((o) => o.group.wrapperName !== o.group.name);\n for (const o of movable) {\n o.group.wrapperName = `${qualify(o)}_${o.group.wrapperName ?? o.group.name}`;\n }\n }\n }\n\n separateRemainingByStructure(occurrences);\n}\n\n/**\n * Terminal round: separate whatever the operation attributes could not.\n *\n * No combination of operation attributes is unique by construction. Two\n * operations in one service can share a name, a method *and* differ only by\n * path — `normalizeOperationIdForNaming` strips the `[N]` suffix, so a NestJS\n * controller method bound to several routes derives one name for all of them.\n * The WorkOS spec already contains such a pair (`Authorization`'s\n * `listRoleAssignments` on two paths); it declares no parameter groups today,\n * so nothing is wrong in the SDKs, but the shape is present rather than\n * hypothetical. Adding `path` as a fourth qualifier would only move the\n * boundary again.\n *\n * So stop enumerating attributes and separate by the thing that actually\n * matters: a name still fusing distinct structures gets one wrapper per\n * distinct fingerprint. That makes \"same `wrapperName` implies same structure\"\n * hold unconditionally, which is the invariant every emitter relies on.\n *\n * Suffixes are keyed on the fingerprint, not on a per-occurrence counter, so\n * declarations that agree keep sharing a wrapper.\n *\n * Ordering is by first appearance, not by sorted fingerprint: the structure\n * declared first keeps the unsuffixed name. Sorting by fingerprint would be\n * equally deterministic but less stable in the way that matters — adding a\n * member to one operation changes its fingerprint and could swap which of two\n * published wrappers holds the bare name. Under first-appearance order only\n * reordering the operations themselves can shift a name, which is both rarer\n * and visible in the spec diff.\n *\n * Either way this is a no-op wherever an earlier round already sufficed —\n * including the WorkOS spec, which never reaches this round at all.\n */\nfunction separateRemainingByStructure(occurrences: Occurrence[]): void {\n const taken = new Set(occurrences.map((o) => o.group.wrapperName ?? o.group.name));\n\n for (const sharers of collidingCandidates(occurrences)) {\n const base = sharers[0].group.wrapperName ?? sharers[0].group.name;\n\n // First fingerprint seen keeps `base`; each new one takes the next free\n // `base_N`, skipping any name already spoken for elsewhere in the spec.\n const nameFor = new Map<string, string>();\n let n = 2;\n for (const o of sharers) {\n if (nameFor.has(o.fingerprint)) continue;\n if (nameFor.size === 0) {\n nameFor.set(o.fingerprint, base);\n continue;\n }\n while (taken.has(`${base}_${n}`)) n++;\n const name = `${base}_${n}`;\n taken.add(name);\n nameFor.set(o.fingerprint, name);\n n++;\n }\n\n for (const o of sharers) o.group.wrapperName = nameFor.get(o.fingerprint)!;\n }\n}\n\n/**\n * Candidate wrapper names shared by declarations that do not agree — the only\n * ones an escalation round may rename.\n */\nfunction collidingCandidates(occurrences: Occurrence[]): Occurrence[][] {\n const byCandidate = new Map<string, Occurrence[]>();\n for (const o of occurrences) {\n const key = o.group.wrapperName ?? o.group.name;\n const list = byCandidate.get(key);\n if (list) list.push(o);\n else byCandidate.set(key, [o]);\n }\n return [...byCandidate.values()].filter(\n (sharers) => sharers.length > 1 && new Set(sharers.map((o) => o.fingerprint)).size > 1,\n );\n}\n\n/**\n * Make every group that shares a `wrapperName` describe literally the same\n * type.\n *\n * Deciding two declarations may share one wrapper is only half the job. The\n * fingerprint deliberately ignores nullability and member order, so sharers can\n * still disagree on both — and each emitter renders the wrapper from whichever\n * operation it happens to reach first while rendering call sites from their own\n * operation. Kotlin showed the consequence: `ParentResource.ById.id` emitted as\n * `String` from one operation, while the Java-friendly overload built from\n * another passed a `String?` into it, and the SDK stopped compiling.\n *\n * So normalize the two axes the fingerprint waived:\n * - a member the sharers disagree on settles as non-nullable. Widening to\n * nullable instead reads as the friendlier choice, but the nullable form\n * doesn't survive every emitter's group paths (Kotlin's query dispatch\n * builds a `Pair<String, String>` from the member, which a `String?` can't\n * satisfy), and non-nullable is what all sharers carried before group\n * member types were resolved at all — so it changes no published surface.\n * A member every sharer agrees is nullable stays nullable.\n *\n * The cost: an operation whose spec really does accept null for a member\n * (`PATCH` on a resource may clear `parent_resource_id`) can't express that\n * through the shared wrapper. It never could — the member used to be a flat\n * `string` everywhere — so nothing regresses, but the limitation is real and\n * removing it means letting that group's wrapper split per operation.\n * - member order follows the first sharer, so positional constructors and\n * their call sites agree.\n */\nfunction reconcileSharedGroups(groups: ParameterGroup[]): void {\n const byWrapper = new Map<string, ParameterGroup[]>();\n for (const group of groups) {\n const key = group.wrapperName ?? group.name;\n const list = byWrapper.get(key);\n if (list) list.push(group);\n else byWrapper.set(key, [group]);\n }\n\n for (const sharers of byWrapper.values()) {\n if (sharers.length < 2) continue;\n\n for (const variant of sharers[0].variants) {\n const peers = sharers\n .slice(1)\n .map((g) => g.variants.find((v) => v.name === variant.name))\n .filter((v): v is ParameterGroupVariant => v !== undefined);\n if (peers.length === 0) continue;\n\n // Settle nullability: unanimously-nullable members stay nullable, and any\n // member the sharers disagree on drops to non-nullable in all of them.\n for (const member of variant.parameters) {\n const all = [member, ...peers.map((p) => p.parameters.find((q) => q.name === member.name)).filter(isParameter)];\n if (all.every((p) => p.type.kind === 'nullable')) continue;\n for (const p of all) {\n if (p.type.kind === 'nullable') p.type = p.type.inner;\n }\n }\n\n // Align order on the first sharer's, leaving any member it doesn't\n // declare in place at the end rather than dropping it.\n const canonical = variant.parameters.map((p) => p.name);\n for (const peer of peers) {\n peer.parameters.sort((a, b) => {\n const ia = canonical.indexOf(a.name);\n const ib = canonical.indexOf(b.name);\n if (ia === -1 && ib === -1) return 0;\n if (ia === -1) return 1;\n if (ib === -1) return -1;\n return ia - ib;\n });\n }\n }\n }\n}\n\nfunction isParameter(p: Parameter | undefined): p is Parameter {\n return p !== undefined;\n}\n\n/**\n * Structural fingerprint of a group: its variants, their members, and each\n * member's resolved shape. Two declarations with the same fingerprint can\n * safely share one generated wrapper type.\n */\nfunction fingerprintGroup(group: ParameterGroup, modelMap: Map<string, Model>, enumMap: Map<string, Enum>): string {\n const variants = group.variants.map((v) => {\n // Members are sorted by name: every emitter renders the wrapper as a\n // named-field type (dataclass, data class, readonly promoted properties,\n // struct variant), so two operations listing the same members in a\n // different order still describe the same type and must keep sharing one\n // wrapper rather than being renamed apart.\n const members = [...v.parameters]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((p) => `${p.name}:${fingerprintType(p.type, modelMap, enumMap, new Set())}`);\n const optional = [...(v.optionalParameters ?? [])].sort();\n return `${v.name}(${members.join(',')})[${optional.join(',')}]`;\n });\n // `optional` is deliberately excluded: whether the group as a whole may be\n // omitted is a property of the operation's signature, not of the wrapper\n // type, and create/update legitimately differ there (required vs optional)\n // while sharing an identical wrapper.\n return variants.join('|');\n}\n\n/**\n * Fingerprint a type by shape rather than by name.\n *\n * Names cannot be compared directly because the parser synthesizes a separate\n * name per declaration site for inline schemas: `create_user` and `update_user`\n * each get their own `PasswordHashType` enum, spelled `CreateUserPasswordHashType`\n * and `UpdateUserPasswordHashType`, though their values are identical. Comparing\n * names would report divergence and rename a wrapper for no reason.\n *\n * Nullability is also stripped: an update declaring a member nullable while\n * create declares it plain is not a reason to split the wrapper type.\n */\nfunction fingerprintType(\n ref: TypeRef,\n modelMap: Map<string, Model>,\n enumMap: Map<string, Enum>,\n visiting: Set<string>,\n): string {\n switch (ref.kind) {\n case 'nullable':\n // Widening only — a nullable and a non-nullable member are compatible.\n return fingerprintType(ref.inner, modelMap, enumMap, visiting);\n case 'primitive':\n return `p:${ref.type}`;\n case 'literal':\n return `l:${typeof ref.value}:${String(ref.value)}`;\n case 'array':\n return `a<${fingerprintType(ref.items, modelMap, enumMap, visiting)}>`;\n case 'map':\n return `m<${fingerprintType(ref.valueType, modelMap, enumMap, visiting)}>`;\n case 'union':\n // Sorted, like enum values and model fields: a union accepts the same set\n // of types whichever order the branches are written in, so two operations\n // listing equivalent branches differently describe the same type and must\n // keep sharing a wrapper rather than renaming a published one apart.\n return `u<${ref.variants\n .map((v) => fingerprintType(v, modelMap, enumMap, visiting))\n .sort()\n .join(',')}>`;\n case 'enum': {\n const e = enumMap.get(ref.name);\n if (!e) return `e:${ref.name}`;\n // Values, not the synthesized name — two inline copies of one enum are\n // the same type for wrapper-sharing purposes. The value's primitive type\n // is part of the fingerprint (as it is for `literal`): the IR keeps\n // numeric `5` and string `\"5\"` distinct, and so do the emitters, so two\n // enums that stringify alike are still different types.\n //\n // Sorted, like model fields and group members above: declaration order of\n // enum values does not change which values the member accepts, so two\n // inline enums listing one set in different orders must keep sharing a\n // wrapper rather than renaming an already-published type apart.\n return `e<${e.values\n .map((v) => `${typeof v.value}:${String(v.value)}`)\n .sort()\n .join(',')}>`;\n }\n case 'model': {\n const m = modelMap.get(ref.name);\n if (!m) return `M:${ref.name}`;\n // Recursion guard: a model reachable from itself fingerprints by name at\n // the point of recurrence, which is enough to distinguish shapes.\n if (visiting.has(ref.name)) return `M:${ref.name}`;\n const next = new Set(visiting).add(ref.name);\n const fields = [...m.fields]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((f) => `${f.name}${f.required ? '!' : '?'}:${fingerprintType(f.type, modelMap, enumMap, next)}`);\n return `M<${fields.join(',')}>`;\n }\n default:\n return 'unknown';\n }\n}\n","import type { ApiSpec, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nexport function validateModelRefs(spec: ApiSpec): void {\n const knownNames = new Set<string>();\n for (const m of spec.models) knownNames.add(m.name);\n for (const e of spec.enums) knownNames.add(e.name);\n\n function walkRef(ref: TypeRef, context: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (!knownNames.has(r.name)) {\n console.warn(`[oagen] Warning: Unresolved model reference \"${r.name}\" (context: ${context})`);\n }\n },\n });\n }\n\n for (const model of spec.models) {\n for (const field of model.fields) {\n walkRef(field.type, `${model.name}.${field.name}`);\n }\n }\n\n for (const service of spec.services) {\n for (const op of service.operations) {\n for (const p of [...op.pathParams, ...op.queryParams, ...(op.bodyOwnedQueryParams ?? []), ...op.headerParams]) {\n walkRef(p.type, `${service.name}.${op.name}.${p.name}`);\n }\n if (op.requestBody) walkRef(op.requestBody, `${service.name}.${op.name}.requestBody`);\n walkRef(op.response, `${service.name}.${op.name}.response`);\n }\n }\n}\n","import type { ApiSpec, AuthScheme, ServerEntry } from '../ir/types.js';\nimport { defaultSdkBehavior } from '../ir/sdk-behavior.js';\nimport { SpecParseError } from '../errors.js';\nimport { loadAndBundleSpec } from './refs.js';\nimport { extractSchemas, extractInlineModelsFromSchemas, clearSchemaNameTransform } from './schemas.js';\nimport { extractOperations } from './operations.js';\nimport {\n mergeInlineResponseModels,\n collapseJsonSuffixModels,\n mergeFieldInlineModels,\n} from './normalize-inline-models.js';\nimport { collectInlineEnumsFromModels, collectInlineEnumsFromOperations } from './collect-inline-enums.js';\nimport { assignParameterGroupWrapperNames } from './parameter-group-names.js';\nimport { validateModelRefs } from './normalize-model-refs.js';\n\n/**\n * A bundled OpenAPI document, post-`$ref` resolution but pre-IR extraction.\n *\n * This is the shape the spec author wrote, with external refs inlined and\n * internal refs left intact. It is intentionally loose (`Record<string,\n * unknown>`) so `transformSpec` can reach arbitrary spec extensions without\n * fighting types — narrow with `as` at use sites.\n */\nexport type OpenApiDocument = Record<string, unknown>;\n\nexport interface ParseOptions {\n operationIdTransform?: (id: string) => string;\n schemaNameTransform?: (name: string) => string;\n /**\n * Domain-facing field-name overrides, keyed by IR model name then wire field\n * name: `{ Connection: { connection_type: 'type' } }`. Sets `Field.domainName`\n * so emitters expose the field under the friendlier name while keeping the\n * wire key. Language-agnostic — honored by any emitter that reads `domainName`.\n */\n fieldHints?: Record<string, Record<string, string>>;\n /**\n * Pre-IR overlay applied to the bundled OpenAPI document before any IR\n * extraction runs. Use this when the upstream spec can't be changed but you\n * need to patch around a spec quirk that would otherwise emit a breaking SDK\n * change — e.g. rewriting a path's response `$ref` back to its prior schema,\n * merging the new fields onto the prior schema, and dropping the fork.\n *\n * The function may mutate the document in place and return it, or return a\n * new object; the returned value is what the rest of oagen sees.\n *\n * Runs once, after `$ref` bundling and before schema/operation extraction.\n * If you need to inspect the resulting IR instead, post-process the\n * `ApiSpec` returned by `parseSpec`.\n */\n transformSpec?: (spec: OpenApiDocument) => OpenApiDocument;\n}\n\nexport async function parseSpec(specPath: string, options?: ParseOptions): Promise<ApiSpec> {\n const { parsed } = await loadAndBundleSpec(specPath);\n const transformed = options?.transformSpec ? options.transformSpec(parsed) : parsed;\n\n const spec = transformed as {\n openapi?: string;\n info?: { title?: string; version?: string; description?: string };\n servers?: Array<{ url?: string; description?: string }>;\n paths?: Record<string, unknown>;\n components?: {\n schemas?: Record<string, unknown>;\n parameters?: Record<string, unknown>;\n requestBodies?: Record<string, unknown>;\n securitySchemes?: Record<\n string,\n { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n >;\n };\n };\n\n // Validate OpenAPI version\n const version = spec.openapi ?? '';\n if (!version.startsWith('3.')) {\n throw new SpecParseError(\n `Unsupported OpenAPI version: ${version}. oagen requires OpenAPI 3.x`,\n `Update the spec to OpenAPI 3.0 or 3.1. If you are using Swagger 2.x, convert it first with \\`npx swagger2openapi ${specPath}\\`.`,\n );\n }\n\n const { models, enums } = extractSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n { schemaNameTransform: options?.schemaNameTransform },\n );\n\n const { services, inlineModels } = extractOperations(\n spec.paths as Record<string, Record<string, unknown>> | undefined,\n options?.operationIdTransform,\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n spec.components?.parameters as Record<string, Record<string, unknown>> | undefined,\n spec.components?.requestBodies as Record<string, Record<string, unknown>> | undefined,\n );\n\n const responseNormalizedModels = mergeInlineResponseModels(models, inlineModels);\n\n // Extract inline models from model field definitions (objects/arrays with properties).\n // schemaNameTransform is kept active so inline child names use the\n // transformed parent name (e.g. AuditLogSchemaJson→AuditLogSchema yields\n // AuditLogSchemaTarget, not AuditLogSchemaJsonTarget).\n const fieldInlineModels = extractInlineModelsFromSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n );\n clearSchemaNameTransform();\n const fieldMergedModels = mergeFieldInlineModels(responseNormalizedModels, fieldInlineModels);\n const finalModels = collapseJsonSuffixModels(fieldMergedModels, services);\n applyFieldHints(finalModels, options?.fieldHints);\n collectInlineEnumsFromModels(finalModels, enums);\n collectInlineEnumsFromOperations(services, enums);\n\n const auth = extractAuthSchemes(spec.components?.securitySchemes);\n\n const serverEntries: ServerEntry[] = (spec.servers ?? [])\n .map((s) => ({ url: s.url ?? '', description: s.description }))\n .filter((s) => s.url);\n\n const result: ApiSpec = {\n name: spec.info?.title ?? 'Unknown API',\n version: spec.info?.version ?? '0.0.0',\n description: spec.info?.description,\n baseUrl: serverEntries[0]?.url ?? '',\n servers: serverEntries.length > 0 ? serverEntries : undefined,\n services,\n models: finalModels,\n enums,\n auth,\n sdk: defaultSdkBehavior(),\n };\n\n // Needs the finished models and enums: divergence is decided on member\n // shape, so this can only run once every referenced type is resolvable.\n assignParameterGroupWrapperNames(result);\n\n validateModelRefs(result);\n\n return result;\n}\n/**\n * Apply `fieldHints` onto the built models, setting `Field.domainName` for each\n * matching (model name, wire field name) pair. Serialization still uses\n * `Field.name`; only the domain-facing identifier changes.\n */\nfunction applyFieldHints(\n models: import('../ir/types.js').Model[],\n fieldHints: Record<string, Record<string, string>> | undefined,\n): void {\n if (!fieldHints) return;\n for (const model of models) {\n const hints = fieldHints[model.name];\n if (!hints) continue;\n for (const field of model.fields) {\n const domainName = hints[field.name];\n if (domainName) field.domainName = domainName;\n }\n }\n}\n\n/** Extract authentication schemes from OpenAPI securitySchemes. */\nfunction extractAuthSchemes(\n securitySchemes?: Record<\n string,\n { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n >,\n): AuthScheme[] | undefined {\n if (!securitySchemes) return undefined;\n const schemes: AuthScheme[] = [];\n for (const [, scheme] of Object.entries(securitySchemes)) {\n if (scheme.type === 'http' && scheme.scheme === 'bearer') {\n schemes.push({ kind: 'bearer' });\n } else if (scheme.type === 'apiKey' && scheme.in && scheme.name) {\n schemes.push({ kind: 'apiKey', in: scheme.in as 'header' | 'query' | 'cookie', name: scheme.name });\n } else if (scheme.type === 'oauth2' && scheme.flows) {\n schemes.push({ kind: 'oauth2', flows: scheme.flows });\n }\n }\n return schemes.length > 0 ? schemes : undefined;\n}\n","/**\n * Shared infrastructure for smoke tests.\n *\n * Types, operation planning, payload generation, ID registry, and capture format\n * used by both raw HTTP and SDK smoke test scripts.\n */\n\nimport 'dotenv/config';\nimport { readFileSync } from 'node:fs';\nimport type { ApiSpec, Operation, Parameter, TypeRef } from '../../src/ir/types.js';\nimport { toSnakeCase, toCamelCase } from '../../src/utils/naming.js';\n\n// Re-export types and functions that external smoke runners need from oagen core.\n// External runners import from '@workos/oagen/smoke' which bundles this module.\nexport { parseSpec } from '../../src/parser/parse.js';\nexport { toCamelCase, toSnakeCase } from '../../src/utils/naming.js';\n\n// ---------------------------------------------------------------------------\n// Capture format\n// ---------------------------------------------------------------------------\n\nexport interface ExchangeProvenance {\n resolutionTier: 'exact' | 'crud-prefix' | 'fuzzy' | 'manifest';\n resolutionConfidence: number;\n sdkMethodName: string;\n captureIndex: number;\n totalCaptures: number;\n}\n\nexport interface CapturedExchange {\n operationId: string;\n service: string;\n operationName: string;\n request: {\n method: string;\n path: string;\n queryParams: Record<string, string>;\n body: unknown | null;\n };\n response: {\n status: number;\n body: unknown | null;\n };\n outcome: 'success' | 'api-error' | 'skipped';\n error?: string;\n /** True when the response status code is not declared in the OpenAPI spec for this operation */\n unexpectedStatus?: boolean;\n /** Status codes declared in the OpenAPI spec (success + error codes) */\n expectedStatusCodes?: number[];\n durationMs: number;\n /** How the SDK method was resolved and which capture was selected */\n provenance?: ExchangeProvenance;\n}\n\nexport interface SmokeResults {\n source: 'raw' | 'spec-baseline' | `sdk-${string}`;\n timestamp: string;\n specVersion: string;\n exchanges: CapturedExchange[];\n}\n\n// ---------------------------------------------------------------------------\n// Operation planning\n// ---------------------------------------------------------------------------\n\nexport interface PlannedOperation {\n service: string;\n operation: Operation;\n}\n\nexport interface PlannedGroup {\n service: string;\n operations: PlannedOperation[];\n}\n\n// ---------------------------------------------------------------------------\n// Smoke config — mutable state populated by loadSmokeConfig()\n// ---------------------------------------------------------------------------\n\n/** Operations that require complex preconditions and can't be auto-tested */\nexport let SKIP_OPERATIONS = new Set<string>();\n\n/** Services to skip entirely */\nexport let SKIP_SERVICES = new Set<string>();\n\n/**\n * Services that produce IDs other services depend on should run first.\n * Lower number = runs earlier. Unlisted services default to 50.\n */\nlet SERVICE_PRIORITY: Record<string, number> = {};\n\n/**\n * Map IR service names to SDK property names on the client object.\n * Empty = use toCamelCase(serviceName) as fallback.\n */\nexport let SERVICE_PROPERTY_MAP: Record<string, string> = {};\n\nexport interface SmokeConfig {\n skipOperations: string[];\n skipServices: string[];\n servicePriority: Record<string, number>;\n servicePropertyMap: Record<string, string>;\n}\n\n/** Load smoke test configuration from a JSON file */\nexport function loadSmokeConfig(configPath?: string): void {\n if (!configPath) return;\n const raw = readFileSync(configPath, 'utf-8');\n const config: SmokeConfig = JSON.parse(raw);\n\n if (config.skipOperations) SKIP_OPERATIONS = new Set(config.skipOperations);\n if (config.skipServices) SKIP_SERVICES = new Set(config.skipServices);\n if (config.servicePriority) SERVICE_PRIORITY = config.servicePriority;\n if (config.servicePropertyMap) SERVICE_PROPERTY_MAP = config.servicePropertyMap;\n}\n\n/** Return the current smoke config values (for diff.ts to consume) */\nexport function getSmokeConfig() {\n return {\n skipOperations: SKIP_OPERATIONS,\n skipServices: SKIP_SERVICES,\n servicePriority: SERVICE_PRIORITY,\n servicePropertyMap: SERVICE_PROPERTY_MAP,\n };\n}\n\n/**\n * Assign a numeric sort key to an operation so that ID-producing operations\n * (parameterless creates and lists) run before ID-consuming ones.\n */\nfunction operationSortKey(op: Operation): number {\n const hasParams = op.pathParams.length > 0;\n const method = op.httpMethod;\n\n if (method === 'post' && !hasParams) return 0; // top-level create\n if (method === 'get' && !hasParams && op.pagination) return 1; // top-level list\n if (method === 'get' && !hasParams) return 2; // top-level singular GET\n if (method === 'post' && hasParams) return 3; // sub-entity create\n if (method === 'get' && hasParams && op.pagination) return 4; // sub-entity list\n if (method === 'get' && hasParams) return 5; // singular GET by ID\n if (method === 'put' || method === 'patch') return 6; // update\n if (method === 'delete') return 7; // delete\n return 99;\n}\n\nexport function planOperations(spec: ApiSpec): PlannedGroup[] {\n const groups: PlannedGroup[] = [];\n\n for (const service of spec.services) {\n if (SKIP_SERVICES.has(service.name)) continue;\n\n const ops: PlannedOperation[] = [];\n for (const op of service.operations) {\n if (SKIP_OPERATIONS.has(op.name)) continue;\n\n ops.push({ service: service.name, operation: op });\n }\n\n if (ops.length === 0) continue;\n\n // Sort to maximize ID availability:\n // 1. Parameterless POSTs (create new top-level entities → produce IDs)\n // 2. Parameterless list GETs (discover existing IDs)\n // 3. Parameterized POSTs (create sub-entities, need parent IDs)\n // 4. Parameterized list GETs\n // 5. Parameterized singular GETs (retrieve by ID)\n // 6. PUT/PATCH (update)\n // 7. DELETE\n ops.sort((a, b) => {\n return operationSortKey(a.operation) - operationSortKey(b.operation);\n });\n\n groups.push({ service: service.name, operations: ops });\n }\n\n // Sort service groups so ID-producing services run first\n groups.sort((a, b) => {\n const aPri = SERVICE_PRIORITY[a.service] ?? 50;\n const bPri = SERVICE_PRIORITY[b.service] ?? 50;\n return aPri - bPri;\n });\n\n return groups;\n}\n\n// ---------------------------------------------------------------------------\n// Wave-based operation planning for batched runners\n// ---------------------------------------------------------------------------\n\n/**\n * A single wave of operations that can be planned and executed together.\n * Wave 0 contains parameterless operations. Subsequent waves contain\n * operations whose path params became resolvable after earlier waves ran.\n */\nexport interface OperationWave {\n /** Operations in this wave, with pre-resolved path params */\n calls: Array<{\n op: Operation;\n irService: string;\n pathParams: Record<string, string>;\n }>;\n}\n\n/**\n * Plan operations in waves so that batched runners can execute each wave,\n * extract IDs from responses, then plan the next wave.\n *\n * Returns an iterator that yields one wave at a time. The caller must\n * execute each wave and populate the IdRegistry before calling next().\n *\n * @param groups - service groups from planOperations()\n * @param ids - the IdRegistry (mutated by the caller between waves)\n * @param resolveMethod - optional filter; return null to skip an operation\n */\nexport function* planWaves(\n groups: PlannedGroup[],\n ids: IdRegistry,\n resolveMethod?: (op: Operation, irService: string) => boolean,\n): Generator<OperationWave, PlannedOperation[], void> {\n // Flatten all operations into a single ordered list\n const remaining: PlannedOperation[] = [];\n for (const group of groups) {\n for (const planned of group.operations) {\n remaining.push(planned);\n }\n }\n\n // Track which operations have been emitted\n const emitted = new Set<number>();\n const skipped: PlannedOperation[] = [];\n\n // Pre-filter: mark operations that fail the resolveMethod check as skipped\n for (let i = 0; i < remaining.length; i++) {\n const { operation: op, service: irService } = remaining[i];\n if (resolveMethod && !resolveMethod(op, irService)) {\n emitted.add(i);\n skipped.push(remaining[i]);\n }\n }\n\n // Wave 0: operations with no path params\n let wave: OperationWave = { calls: [] };\n for (let i = 0; i < remaining.length; i++) {\n if (emitted.has(i)) continue;\n const { operation: op, service: irService } = remaining[i];\n if (op.pathParams.length === 0) {\n wave.calls.push({ op, irService, pathParams: {} });\n emitted.add(i);\n }\n }\n\n if (wave.calls.length > 0) {\n yield wave;\n }\n\n // Subsequent waves: try to resolve remaining operations\n let madeProgress = true;\n while (madeProgress) {\n madeProgress = false;\n wave = { calls: [] };\n\n for (let i = 0; i < remaining.length; i++) {\n if (emitted.has(i)) continue;\n const { operation: op, service: irService } = remaining[i];\n\n const resolved = ids.resolvePathParams(op, irService);\n if (resolved) {\n wave.calls.push({ op, irService, pathParams: resolved });\n emitted.add(i);\n madeProgress = true;\n }\n }\n\n if (wave.calls.length > 0) {\n yield wave;\n }\n }\n\n // Collect truly unresolvable operations for the caller to mark as skipped\n const unresolved: PlannedOperation[] = [];\n for (let i = 0; i < remaining.length; i++) {\n if (!emitted.has(i)) {\n unresolved.push(remaining[i]);\n }\n }\n return unresolved;\n}\n\n// ---------------------------------------------------------------------------\n// Payload generation\n// ---------------------------------------------------------------------------\n\nexport function generateFixtureValue(typeRef: TypeRef, fieldName: string, spec: ApiSpec): unknown {\n switch (typeRef.kind) {\n case 'primitive':\n return generatePrimitiveFixture(typeRef.type, typeRef.format, fieldName);\n case 'array':\n return [generateFixtureValue(typeRef.items, fieldName, spec)];\n case 'model': {\n const model = spec.models.find((m) => m.name === typeRef.name);\n if (model) {\n const obj: Record<string, unknown> = {};\n for (const field of model.fields) {\n if (field.required) {\n obj[toSnakeCase(field.name)] = generateFixtureValue(field.type, field.name, spec);\n }\n }\n return obj;\n }\n return {};\n }\n case 'enum': {\n const e = spec.enums.find((en) => en.name === typeRef.name);\n return e?.values[0]?.value ?? 'unknown';\n }\n case 'nullable':\n return generateFixtureValue(typeRef.inner, fieldName, spec);\n case 'union':\n if (typeRef.variants.length > 0) {\n return generateFixtureValue(typeRef.variants[0], fieldName, spec);\n }\n return null;\n }\n}\n\nfunction generatePrimitiveFixture(type: string, format: string | undefined, fieldName: string): unknown {\n if (type === 'string') {\n if (format === 'uuid') return '550e8400-e29b-41d4-a716-446655440000';\n if (format === 'date') return '2024-01-01';\n if (format === 'date-time') return '2024-01-01T00:00:00Z';\n if (format === 'email') return 'test@example.com';\n if (format === 'uri' || format === 'url') return 'https://example.com';\n return `test_${toSnakeCase(fieldName)}`;\n }\n if (type === 'integer') return 1;\n if (type === 'number') return 1.0;\n if (type === 'boolean') return true;\n return null;\n}\n\n/** Generate a snake_case request body payload from an operation's requestBody type */\nexport function generatePayload(op: Operation, spec: ApiSpec): Record<string, unknown> | null {\n if (!op.requestBody) return null;\n\n const bodyType = op.requestBody;\n if (bodyType.kind === 'model') {\n const model = spec.models.find((m) => m.name === bodyType.name);\n if (!model) return {};\n\n const payload: Record<string, unknown> = {};\n for (const field of model.fields) {\n if (!field.required) continue;\n const key = toSnakeCase(field.name);\n let value = generateFixtureValue(field.type, field.name, spec);\n\n // Inject uniqueness markers for name/slug fields\n if ((key === 'name' || key === 'slug') && typeof value === 'string') {\n value = `smoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n payload[key] = value;\n }\n return payload;\n }\n\n // Fallback for non-model body types\n return {};\n}\n\n/** Generate a fixture value with SDK-friendly types (e.g. Date objects for date-time) */\nfunction generateSDKFixtureValue(typeRef: TypeRef, fieldName: string, spec: ApiSpec): unknown {\n const value = generateFixtureValue(typeRef, fieldName, spec);\n // SDK methods expect Date objects for date-time fields, not ISO strings\n if (typeRef.kind === 'primitive' && typeRef.format === 'date-time' && typeof value === 'string') {\n return new Date(value);\n }\n return value;\n}\n\n/** Generate a camelCase payload for SDK method calls */\nexport function generateCamelPayload(op: Operation, spec: ApiSpec): Record<string, unknown> | null {\n if (!op.requestBody) return null;\n\n const bodyType = op.requestBody;\n if (bodyType.kind === 'model') {\n const model = spec.models.find((m) => m.name === bodyType.name);\n if (!model) return {};\n\n const payload: Record<string, unknown> = {};\n for (const field of model.fields) {\n if (!field.required) continue;\n const key = toCamelCase(field.name);\n let value = generateSDKFixtureValue(field.type, field.name, spec);\n\n if ((field.name === 'name' || field.name === 'slug') && typeof value === 'string') {\n value = `smoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n payload[key] = value;\n }\n return payload;\n }\n\n return {};\n}\n\n/** Generate query params for an operation (required params only, plus limit=1 for lists) */\nexport function generateQueryParams(op: Operation, spec: ApiSpec): Record<string, string> {\n const params: Record<string, string> = {};\n\n if (op.pagination) {\n params['limit'] = '1';\n }\n\n for (const p of op.queryParams) {\n if (!p.required) continue;\n const value = generateFixtureValue(p.type, p.name, spec);\n params[toSnakeCase(p.name)] = String(value);\n }\n\n // Sort by key\n const sorted: Record<string, string> = {};\n for (const key of Object.keys(params).sort()) {\n sorted[key] = params[key];\n }\n return sorted;\n}\n\n/** Generate camelCase query params for SDK method calls */\nexport function generateCamelQueryParams(op: Operation, spec: ApiSpec): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (op.pagination) {\n params['limit'] = 1;\n }\n\n for (const p of op.queryParams) {\n if (!p.required) continue;\n const value = generateFixtureValue(p.type, p.name, spec);\n params[toCamelCase(p.name)] = value;\n }\n\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// ID Registry\n// ---------------------------------------------------------------------------\n\nexport class IdRegistry {\n private ids = new Map<string, string>();\n\n set(service: string, field: string, value: string): void {\n this.ids.set(`${service}.${field}`, value);\n }\n\n get(service: string, field: string): string | undefined {\n return this.ids.get(`${service}.${field}`);\n }\n\n /** Resolve path parameters for an operation using stored IDs */\n resolvePathParams(op: Operation, service: string): Record<string, string> | null {\n const resolved: Record<string, string> = {};\n for (const p of op.pathParams) {\n const value =\n this.get(service, p.name) ||\n this.get(service, 'id') ||\n this.findAcrossServices(p.name) ||\n this.resolveFromParamName(p.name) ||\n this.resolveFromExample(p);\n\n if (!value) return null;\n resolved[p.name] = value;\n }\n return resolved;\n }\n\n /** Try to find a param value across all services */\n private findAcrossServices(field: string): string | undefined {\n for (const [key, value] of this.ids.entries()) {\n if (key.endsWith(`.${field}`)) return value;\n }\n // Also try snake_case variant: \"organizationId\" → \"organization_id\"\n const snakeField = toSnakeCase(field);\n if (snakeField !== field) {\n for (const [key, value] of this.ids.entries()) {\n if (key.endsWith(`.${snakeField}`)) return value;\n }\n }\n return undefined;\n }\n\n /**\n * Resolve a path param like \"organizationId\" by mapping it to the\n * service that stores that entity's ID (e.g. Organizations.id).\n * Also handles snake_case suffixed with _id by stripping the suffix\n * and looking up the pluralized service name.\n */\n private resolveFromParamName(paramName: string): string | undefined {\n // Infer from param name: \"resource_id\" → \"Resources\", \"role_assignment_id\" → \"RoleAssignments\"\n // Handle snake_case: strip trailing _id, PascalCase+pluralize the rest\n if (paramName.endsWith('_id')) {\n const base = paramName.slice(0, -3); // e.g. \"resource_type\" from \"resource_type_id\"\n const pascal = base\n .split('_')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join('');\n const plural = pascal.endsWith('s') ? pascal : pascal + 's';\n const val = this.get(plural, 'id') || this.get(plural, 'slug');\n if (val) return val;\n\n // Fallback: find any service whose name ends with the plural suffix\n // e.g. \"user_id\" → \"Users\" not found → try \"UserManagementUsers\"\n const suffixVal = this.findByServiceSuffix(plural, 'id') || this.findByServiceSuffix(plural, 'slug');\n if (suffixVal) return suffixVal;\n }\n\n // Handle camelCase: \"resourceId\" → strip \"Id\", pluralize → \"Resources\"\n if (paramName.endsWith('Id') && paramName.length > 2) {\n const base = paramName.slice(0, -2); // e.g. \"organization\"\n const pascal = base.charAt(0).toUpperCase() + base.slice(1);\n const plural = pascal.endsWith('s') ? pascal : pascal + 's';\n const val = this.get(plural, 'id') || this.get(plural, 'slug');\n if (val) return val;\n\n // Fallback: find any service whose name ends with the plural suffix\n const suffixVal = this.findByServiceSuffix(plural, 'id') || this.findByServiceSuffix(plural, 'slug');\n if (suffixVal) return suffixVal;\n }\n\n return undefined;\n }\n\n /**\n * Find a value by looking for any service name that ends with the given suffix.\n * e.g. suffix \"Users\" matches \"UserManagementUsers.id\"\n */\n private findByServiceSuffix(suffix: string, field: string): string | undefined {\n for (const [key, value] of this.ids.entries()) {\n if (key.endsWith(`.${field}`)) {\n const servicePart = key.slice(0, -(field.length + 1));\n if (servicePart.endsWith(suffix)) {\n return value;\n }\n }\n }\n return undefined;\n }\n\n /**\n * Last-resort fallback: use the spec's example or default value for a parameter.\n * Many path params (e.g. actionName, slug, type) have example values in the spec.\n */\n private resolveFromExample(param: Parameter): string | undefined {\n const value = param.example ?? param.default;\n if (value !== undefined && value !== null) {\n return String(value);\n }\n return undefined;\n }\n\n /**\n * Extract IDs from a response body and store them.\n * @param isTopLevel - true for operations without path params (their `id` belongs to this service).\n * false for sub-resource operations (their `id` is a child entity, don't overwrite).\n */\n extractAndStore(service: string, responseBody: unknown, isTopLevel = true): void {\n if (!responseBody || typeof responseBody !== 'object') return;\n\n const body = responseBody as Record<string, unknown>;\n\n // Only store direct ID from top-level operations to avoid overwriting\n // e.g. Organizations.id with an API key ID from /organizations/{id}/api_keys\n if (isTopLevel) {\n if (typeof body.id === 'string') {\n this.set(service, 'id', body.id);\n }\n\n // List response: extract from first item\n if (Array.isArray(body.data) && body.data.length > 0) {\n const first = body.data[0] as Record<string, unknown> | undefined;\n if (first && typeof first === 'object') {\n if (typeof first.id === 'string') {\n this.set(service, 'id', first.id);\n }\n this.extractNestedIds(service, first);\n }\n }\n\n if (typeof body.slug === 'string') this.set(service, 'slug', body.slug);\n if (typeof body.key === 'string') this.set(service, 'key', body.key);\n }\n\n // Always extract nested reference IDs (e.g. organization_id, connection_id)\n this.extractNestedIds(service, body);\n if (Array.isArray(body.data) && body.data.length > 0) {\n const first = body.data[0] as Record<string, unknown> | undefined;\n if (first && typeof first === 'object') {\n this.extractNestedIds(service, first);\n }\n }\n }\n\n /** Extract fields ending in _id or Id and store them for cross-service resolution */\n private extractNestedIds(service: string, obj: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value !== 'string') continue;\n if (key === 'id') continue; // already handled\n // Store fields like \"organization_id\", \"connection_id\" directly\n if (key.endsWith('_id') || (key.endsWith('Id') && key.length > 2)) {\n this.set(service, key, value);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Status code checking\n// ---------------------------------------------------------------------------\n\n/** Get the set of status codes declared in the spec for an operation (success + errors) */\nexport function getExpectedStatusCodes(op: Operation): number[] {\n const codes: number[] = [];\n // The success response code is implied by HTTP method if not explicit in errors\n // Common defaults: POST→201, GET→200, PUT→200, PATCH→200, DELETE→204\n const defaultSuccess: Record<string, number> = {\n post: 201,\n get: 200,\n put: 200,\n patch: 200,\n delete: 204,\n };\n codes.push(defaultSuccess[op.httpMethod] ?? 200);\n // Add declared error codes from the spec\n for (const err of op.errors) {\n if (!codes.includes(err.statusCode)) {\n codes.push(err.statusCode);\n }\n }\n return codes.sort((a, b) => a - b);\n}\n\n/** Check if a status code is unexpected (not declared in the spec) */\nexport function isUnexpectedStatus(status: number, op: Operation): boolean {\n if (status === 0) return false; // skipped or network error, not a status mismatch\n const expected = getExpectedStatusCodes(op);\n return !expected.includes(status);\n}\n\n// ---------------------------------------------------------------------------\n// Path resolution\n// ---------------------------------------------------------------------------\n\nexport function resolvePath(op: Operation, pathParams: Record<string, string>): string {\n let path = op.path;\n for (const [name, value] of Object.entries(pathParams)) {\n path = path.replace(`{${name}}`, value);\n }\n return path;\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\nexport function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function parseCliArgs(): { spec: string; sdkPath?: string; smokeConfig?: string } {\n const args = process.argv.slice(2);\n const specIdx = args.indexOf('--spec');\n const spec = specIdx !== -1 && args[specIdx + 1] ? args[specIdx + 1] : process.env.OPENAPI_SPEC_PATH;\n if (!spec) {\n console.error('OpenAPI spec path is required. Set OPENAPI_SPEC_PATH env var or pass --spec <path>.');\n process.exit(1);\n }\n const sdkPathIdx = args.indexOf('--sdk-path');\n const sdkPath = sdkPathIdx !== -1 && args[sdkPathIdx + 1] ? args[sdkPathIdx + 1] : undefined;\n const configIdx = args.indexOf('--smoke-config');\n const smokeConfig = configIdx !== -1 && args[configIdx + 1] ? args[configIdx + 1] : process.env.SMOKE_CONFIG;\n return { spec, sdkPath, smokeConfig };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smoke.mjs","names":["isNullSchema","fingerprintType"],"sources":["../src/utils/naming.ts","../src/ir/sdk-behavior.ts","../src/errors.ts","../src/parser/refs.ts","../src/ir/types.ts","../src/parser/inline-models.ts","../src/parser/schemas.ts","../src/parser/pagination.ts","../src/parser/responses.ts","../src/parser/security.ts","../src/parser/envelope-companion-names.ts","../src/parser/operations.ts","../src/parser/normalize-inline-models.ts","../src/parser/collect-inline-enums.ts","../src/parser/parameter-group-names.ts","../src/parser/normalize-model-refs.ts","../src/parser/parse.ts","../scripts/smoke/shared.ts"],"sourcesContent":["/**\n * Known compound tokens that the regex-based splitter over-splits.\n * Each entry is [lowercase-word-sequence, canonical-form].\n * Sorted longest-first so greedy matching works correctly.\n */\nconst COMPOUND_WORDS: [string[], string][] = [\n [['m', '2', 'm'], 'M2M'],\n [['o', 'auth'], 'OAuth'],\n];\n\n/**\n * Recombine adjacent words that form a known compound token.\n */\nfunction recombineCompounds(words: string[]): string[] {\n const result: string[] = [];\n let i = 0;\n while (i < words.length) {\n let matched = false;\n for (const [pattern, canonical] of COMPOUND_WORDS) {\n if (i + pattern.length <= words.length) {\n const matches = pattern.every((p, j) => words[i + j].toLowerCase() === p);\n if (matches) {\n result.push(canonical);\n i += pattern.length;\n matched = true;\n break;\n }\n }\n }\n if (!matched) {\n result.push(words[i]);\n i++;\n }\n }\n return result;\n}\n\n/**\n * Split a string into words, handling:\n * - camelCase / PascalCase boundaries\n * - snake_case / kebab-case separators\n * - Consecutive capitals (e.g., \"HTTPClient\" → [\"HTTP\", \"Client\"])\n * - Numbers as word boundaries (e.g., \"OAuth2Token\" → [\"OAuth\", \"2\", \"Token\"])\n * - Known compounds are recombined (e.g., \"M2M\" stays as one word)\n */\nexport function splitWords(s: string): string[] {\n if (!s) return [];\n\n const words = s\n .replace(/[^a-zA-Z0-9_\\-\\s.]/g, '_') // replace non-alphanumeric chars with separator\n .replace(/([a-z])([A-Z])/g, '$1\\0$2') // camelCase boundary\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1\\0$2') // consecutive caps boundary\n .replace(/([a-zA-Z])(\\d)/g, '$1\\0$2') // letter to number\n .replace(/(\\d)([a-zA-Z])/g, '$1\\0$2') // number to letter\n .split(/[\\0_\\-\\s.]+/)\n .filter((w) => w.length > 0);\n\n return recombineCompounds(words);\n}\n\nexport const ACRONYM_SET = new Set(['SSO', 'FGA', 'SAML', 'SCIM', 'JWT', 'HMAC', 'M2M']);\n\nexport function toPascalCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n return splitWords(s)\n .map((w) => {\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n // Special case: OAuth should stay as OAuth, not OAUTH\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toCamelCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n const words = splitWords(s);\n if (words.length === 0) return '';\n return words\n .map((w, i) => {\n if (i === 0) return w.toLowerCase();\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('_');\n}\n\nexport function toKebabCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('-');\n}\n\nexport function toUpperSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toUpperCase())\n .join('_');\n}\n\nconst BACKEND_SUFFIXES = ['Controller'];\n\nexport function stripBackendSuffixes(name: string): string {\n for (const suffix of BACKEND_SUFFIXES) {\n if (name.endsWith(suffix) && name.length > suffix.length) {\n return name.slice(0, -suffix.length);\n }\n }\n return name;\n}\n\nexport function stripBackendPrefixes(name: string): string {\n return name.replace(/Userland/g, '').replace(/Controller/g, '');\n}\n\n/**\n * Remove ListItem / ByExternalId / ByResourceId / ForResource markers from PascalCase names.\n * E.g. \"DirectoriesListItemState\" → \"DirectoriesState\"\n */\nexport function stripListItemMarkers(name: string): string {\n return name\n .replace(/ListItem/g, '')\n .replace(/ByExternalId/g, '')\n .replace(/ByResourceId/g, '')\n .replace(/ForResource/g, '');\n}\n\n/** Words that look plural but must NOT be singularized. */\nconst SINGULAR_SAFE_LIST = new Set([\n 'Status',\n 'Address',\n 'Access',\n 'Process',\n 'Progress',\n 'Success',\n 'Radius',\n 'Canvas',\n 'Alias',\n 'Basis',\n 'Bus',\n 'Species',\n 'Series',\n]);\n\n/**\n * Conservative singularize for the leading PascalCase word.\n * Only applied to the first word of a PascalCase name (the resource word).\n * - `ies` → `y` (e.g. Directories → Directory)\n * - trailing `s` for words >4 chars (e.g. Organizations → Organization)\n * Safe-listed words are never singularized.\n */\nexport function singularize(word: string): string {\n if (SINGULAR_SAFE_LIST.has(word)) return word;\n if (word.endsWith('ies') && word.length > 4) {\n return word.slice(0, -3) + 'y';\n }\n if (word.endsWith('ses') && word.length > 4) {\n // e.g. \"Processes\" — but \"Process\" is safe-listed, this handles non-safe ones\n return word.slice(0, -2);\n }\n if (word.endsWith('s') && !word.endsWith('ss') && word.length > 4) {\n return word.slice(0, -1);\n }\n return word;\n}\n\n/**\n * Compose all backend name cleaning transforms in order:\n * 1. Strip backend prefixes (Userland, Controller)\n * 2. Strip backend suffixes (Dto, DTO, Controller)\n * 3. Strip ListItem / ByExternalId markers\n * 4. Singularize leading resource word\n *\n * Must be idempotent: `cleanSchemaName(cleanSchemaName(x)) === cleanSchemaName(x)`\n */\n/** Strip `.js` extensions from import/export specifiers for dedup comparison. */\nexport function normalizeJsExtension(text: string): string {\n return text.replace(/\\.js(['\"])/g, '$1');\n}\n\nexport function cleanSchemaName(name: string): string {\n let result = stripBackendPrefixes(stripBackendSuffixes(name));\n result = stripListItemMarkers(result);\n\n // Singularize the leading PascalCase word\n const match = result.match(/^([A-Z][a-z]*)/);\n if (match) {\n const leadWord = match[1];\n const singular = singularize(leadWord);\n if (singular !== leadWord) {\n result = singular + result.slice(leadWord.length);\n }\n }\n\n return result;\n}\n","/**\n * SDK Behavior IR — language-agnostic runtime policies for generated SDKs.\n *\n * These types capture the \"what\" of SDK behavior (retry, telemetry, errors, etc.)\n * while emitters provide the \"how\" (language-specific mechanism).\n *\n * Emitters access these via `ctx.spec.sdk` — always populated, never undefined.\n */\n\n// ── Retry ──────────────────────────────────────────────────────────\n\n/** Retry policy — when and how to retry failed requests. */\nexport interface RetryPolicy {\n /** HTTP status codes that trigger a retry. */\n retryableStatusCodes: number[];\n /** Maximum number of retry attempts (0 = no retries). */\n maxRetries: number;\n /** Whether to retry on connection errors (DNS failure, TCP reset). */\n retryOnConnectionError: boolean;\n /** Whether to retry on timeout errors. */\n retryOnTimeout: boolean;\n /** Backoff strategy between retries. */\n backoff: BackoffStrategy;\n}\n\n/** Exponential backoff configuration.\n *\n * Formula: `delay = min(initialDelay * multiplier^attempt, maxDelay)`\n * With jitter: `delay += delay * jitterFactor * random(0, 1)`\n */\nexport interface BackoffStrategy {\n /** Initial delay in seconds before the first retry. */\n initialDelay: number;\n /** Multiplier applied to the delay on each subsequent retry. */\n multiplier: number;\n /** Maximum delay in seconds (cap). */\n maxDelay: number;\n /** Jitter factor (0..1). 0.5 means up to 50% random jitter added. */\n jitterFactor: number;\n}\n\n// ── Errors ─────────────────────────────────────────────────────────\n\n/** Error mapping — status codes to named exception kinds. */\nexport interface ErrorPolicy {\n /** Map from HTTP status code to a logical error kind name (e.g. 400 → 'BadRequest').\n * Emitters append language-specific suffixes (e.g. 'BadRequestException'). */\n statusCodeMap: Record<number, string>;\n /** Catch-all error kind for 5xx status codes not in the map. */\n serverErrorKind: string;\n /** Catch-all error kind for unrecognized status codes. */\n clientErrorKind: string;\n /** URL template for error documentation. Use {code} as placeholder for the API error code. */\n errorDocUrlTemplate?: string;\n}\n\n// ── Telemetry ──────────────────────────────────────────────────────\n\n/** Telemetry — what request metrics to track and send. */\nexport interface TelemetryPolicy {\n /** Whether telemetry is enabled by default. Users can opt out via constructor param. */\n enabledByDefault: boolean;\n /** Header name for client telemetry data (previous request's ID + latency). */\n headerName: string;\n /** Response header name for the request ID. */\n requestIdHeader: string;\n}\n\n// ── Pagination ─────────────────────────────────────────────────────\n\n/** Pagination behavior defaults. */\nexport interface PaginationPolicy {\n /** Delay in milliseconds between pages during auto-pagination. 0 = no delay. */\n autoPageDelayMs: number;\n}\n\n// ── Idempotency ────────────────────────────────────────────────────\n\n/** Idempotency auto-generation rules. */\nexport interface IdempotencyPolicy {\n /** Header name for the idempotency key. */\n headerName: string;\n /** Whether to auto-generate a UUID v4 idempotency key for POST requests when retries > 0. */\n autoGenerateForPost: boolean;\n}\n\n// ── Logging ────────────────────────────────────────────────────────\n\n/** Logging contract — what to log at which level. */\nexport interface LoggingPolicy {\n /** Whether structured logging hooks are generated. */\n enabled: boolean;\n /** Log events that the generated client emits. */\n events: LogEvent[];\n}\n\n/** A discrete loggable event in the request lifecycle. */\nexport type LogEvent =\n | 'request.start'\n | 'request.success'\n | 'request.retry'\n | 'request.rate_limited'\n | 'request.error'\n | 'request.connection_error';\n\n// ── User-Agent ─────────────────────────────────────────────────────\n\n/** User-Agent construction rules. */\nexport interface UserAgentPolicy {\n /** Template for the SDK identifier string.\n * Placeholders: {name} = spec name, {lang} = emitter language, {version} = SDK version.\n * Each emitter interpolates with its own language string and casing conventions.\n * Example: '{name} {lang}/{version}' → 'Acme PHP/4.32.0' */\n sdkIdentifierTemplate: string;\n /** Whether to append the runtime/language version (e.g. PHP 8.2, Python 3.12). */\n includeRuntimeVersion: boolean;\n /** Whether to allow app info enrichment via setAppInfo(name, version, url). */\n allowAppInfo: boolean;\n /** AI agent environment variable detection entries. */\n aiAgentEnvVars: AiAgentEnvVar[];\n}\n\n/** Maps an environment variable to an AI agent slug for User-Agent enrichment. */\nexport interface AiAgentEnvVar {\n /** Environment variable to check (e.g. 'CLAUDE_CODE'). */\n envVar: string;\n /** Agent name to append to User-Agent (e.g. 'ClaudeCode'). */\n agentName: string;\n}\n\n// ── Request Guards ─────────────────────────────────────────────────\n\n/** Guards that validate request params before sending. */\nexport interface RequestGuardPolicy {\n /** Keys that should be in RequestOptions, not in params.\n * If detected in the body or query params, the SDK throws an error. */\n optionKeys: string[];\n}\n\n// ── Timeouts ───────────────────────────────────────────────────────\n\n/** Timeout configuration. */\nexport interface TimeoutPolicy {\n /** Default HTTP request timeout in seconds. */\n defaultTimeoutSeconds: number;\n /** Environment variable name to override the timeout (e.g. 'SDK_REQUEST_TIMEOUT'). */\n timeoutEnvVar?: string;\n}\n\n// ── Root ───────────────────────────────────────────────────────────\n\n/** Language-agnostic runtime policies for generated SDKs.\n * Attached to `ApiSpec.sdk` and consumed by emitters via `ctx.spec.sdk`. */\nexport interface SdkBehavior {\n retry: RetryPolicy;\n errors: ErrorPolicy;\n telemetry: TelemetryPolicy;\n pagination: PaginationPolicy;\n idempotency: IdempotencyPolicy;\n logging: LoggingPolicy;\n userAgent: UserAgentPolicy;\n requestGuard: RequestGuardPolicy;\n timeout: TimeoutPolicy;\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\n/**\n * Canonical SDK behavior defaults. Per-language or per-project overrides can\n * be applied via `mergeSdkBehavior()` in each SDK's `oagen.config.ts`.\n *\n * - Retry: exponential backoff with jitter, retries on 429/5xx\n * - Errors: standard HTTP status → exception kind mapping\n * - Telemetry: enabled by default, tracks request ID + latency\n * - Pagination: no inter-page delay (Node overrides to 350ms)\n * - Idempotency: auto-generate UUID v4 for retryable POSTs\n * - Logging: all lifecycle events enabled\n * - User-Agent: SDK identifier + runtime version + app info + AI agent detection\n * - Request guards: detect misplaced RequestOptions keys in params\n * - Timeout: 60s default (Python overrides to 30s)\n */\nexport function defaultSdkBehavior(): SdkBehavior {\n return {\n retry: {\n retryableStatusCodes: [429, 500, 502, 503, 504],\n maxRetries: 3,\n retryOnConnectionError: true,\n retryOnTimeout: true,\n backoff: {\n initialDelay: 1.0,\n multiplier: 2.0,\n maxDelay: 30.0,\n jitterFactor: 0.5,\n },\n },\n errors: {\n statusCodeMap: {\n 400: 'BadRequest',\n 401: 'Authentication',\n 403: 'Authorization',\n 404: 'NotFound',\n 409: 'Conflict',\n 422: 'UnprocessableEntity',\n 429: 'RateLimitExceeded',\n },\n serverErrorKind: 'Server',\n clientErrorKind: 'Api',\n },\n telemetry: {\n enabledByDefault: true,\n headerName: 'X-Client-Telemetry',\n requestIdHeader: 'X-Request-ID',\n },\n pagination: {\n autoPageDelayMs: 0,\n },\n idempotency: {\n headerName: 'Idempotency-Key',\n autoGenerateForPost: true,\n },\n logging: {\n enabled: true,\n events: [\n 'request.start',\n 'request.success',\n 'request.retry',\n 'request.rate_limited',\n 'request.error',\n 'request.connection_error',\n ],\n },\n userAgent: {\n sdkIdentifierTemplate: '{name} {lang}/{version}',\n includeRuntimeVersion: true,\n allowAppInfo: true,\n aiAgentEnvVars: [\n { envVar: 'CLAUDE_CODE', agentName: 'ClaudeCode' },\n { envVar: 'CURSOR_AGENT', agentName: 'Cursor' },\n { envVar: 'CLINE_ACTIVE', agentName: 'Cline' },\n { envVar: 'WINDSURF_ACTIVE', agentName: 'Windsurf' },\n { envVar: 'COPILOT_AGENT', agentName: 'Copilot' },\n ],\n },\n requestGuard: {\n optionKeys: [\n 'api_key',\n 'apiKey',\n 'idempotency_key',\n 'idempotencyKey',\n 'extra_headers',\n 'extraHeaders',\n 'max_retries',\n 'maxRetries',\n 'base_url',\n 'baseUrl',\n ],\n },\n timeout: {\n defaultTimeoutSeconds: 60,\n },\n };\n}\n\n// ── Merge ──────────────────────────────────────────────────────────\n\n/** Recursive partial type for deep overrides. */\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends (infer U)[]\n ? U[] // Arrays replace entirely (don't concat)\n : T[K] extends object\n ? DeepPartial<T[K]>\n : T[K];\n};\n\n/**\n * Deep-merge partial overrides into the canonical defaults.\n * Arrays replace entirely (so `retryableStatusCodes: [429]` replaces the full list,\n * rather than appending). Object properties are merged recursively.\n */\nexport function mergeSdkBehavior(overrides: DeepPartial<SdkBehavior>): SdkBehavior {\n return deepMerge(\n defaultSdkBehavior() as unknown as Record<string, unknown>,\n overrides as unknown as Record<string, unknown>,\n ) as unknown as SdkBehavior;\n}\n\n/**\n * Self-contained deep merge (no external imports — ir/ is layer 0).\n * Arrays and primitives from `source` replace those in `target`.\n * Objects are merged recursively.\n */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (sourceVal === undefined) continue;\n if (\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n targetVal !== null &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal as Record<string, unknown>, sourceVal as Record<string, unknown>);\n } else {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n","/**\n * Structured error hierarchy for oagen.\n *\n * Every error carries a human-readable `hint` that suggests a recovery action.\n * The hint is appended to the `message` so it appears in stack traces and logs.\n */\n\n/** Base class for all oagen errors. */\nexport class OagenError extends Error {\n readonly hint: string;\n\n constructor(message: string, hint: string) {\n const fullMessage = hint ? `${message}\\nHint: ${hint}` : message;\n super(fullMessage);\n this.name = 'OagenError';\n this.hint = hint;\n }\n}\n\n/** Thrown when a command should terminate with a specific exit code. */\nexport class CommandError extends OagenError {\n readonly exitCode: number;\n\n constructor(message: string, hint: string, exitCode: number) {\n super(message, hint);\n this.name = 'CommandError';\n this.exitCode = exitCode;\n }\n}\n\n/** Thrown when an OpenAPI spec cannot be parsed or has an unsupported version. */\nexport class SpecParseError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'SpecParseError';\n }\n}\n\n/** Thrown when configuration files (manifests, API surfaces, overlays) are missing or malformed. */\nexport class ConfigError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigError';\n }\n}\n\n/** Thrown when a config file exists but cannot be loaded or evaluated. */\nexport class ConfigLoadError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigLoadError';\n }\n}\n\n/** Thrown when a config targets a different IR version than the installed package. */\nexport class ConfigVersionMismatchError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigVersionMismatchError';\n }\n}\n\n/** Thrown when an API surface extractor encounters a problem. */\nexport class ExtractorError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ExtractorError';\n }\n}\n\n/** Thrown when a requested language or extractor is not found in a registry. */\nexport class RegistryError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'RegistryError';\n }\n}\n\n/** Thrown for internal invariant violations that indicate a bug. */\nexport class InternalError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'InternalError';\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { makeDocumentFromString, bundleDocument, createConfig, BaseResolver, Oas3_1Types } from '@redocly/openapi-core';\nimport { SpecParseError } from '../errors.js';\n\nexport interface BundledSpec {\n parsed: Record<string, unknown>;\n specPath: string;\n}\n\nexport async function loadAndBundleSpec(specPath: string): Promise<BundledSpec> {\n const absolutePath = resolve(specPath);\n const content = await readFile(absolutePath, 'utf-8');\n const document = makeDocumentFromString(content, pathToFileURL(absolutePath).href);\n\n const config = await createConfig({});\n const resolver = new BaseResolver();\n\n const result = await bundleDocument({\n document,\n config,\n types: Oas3_1Types,\n externalRefResolver: resolver,\n dereference: false,\n });\n\n if (result.problems.some((p) => p.severity === 'error')) {\n const errors = result.problems\n .filter((p) => p.severity === 'error')\n .map((p) => p.message)\n .join('\\n');\n throw new SpecParseError(\n `Failed to parse spec: ${errors}`,\n `Check the OpenAPI spec at \"${absolutePath}\" for syntax errors. Run a linter such as \\`npx @redocly/cli lint ${specPath}\\` to identify issues.`,\n );\n }\n\n return {\n parsed: result.bundle.parsed as Record<string, unknown>,\n specPath: absolutePath,\n };\n}\n","import type { SdkBehavior } from './sdk-behavior.js';\n\n/**\n * Authentication scheme extracted from OpenAPI `components.securitySchemes`.\n *\n * `schemeName` is the key under `components.securitySchemes`, spelled exactly as\n * in the document. The requirements under `ApiSpec.security` and\n * `Operation.security` refer to the same key, so emitters join a requirement to\n * its scheme on that field. `description` is present only when the document\n * declares one.\n */\nexport type AuthScheme = { description?: string; schemeName: string } & (\n | { kind: 'basic' }\n | { kind: 'bearer' }\n | { kind: 'apiKey'; in: 'header' | 'query' | 'cookie'; name: string }\n | { kind: 'oauth2'; flows: Record<string, unknown> }\n);\n\n/** Root IR node representing the full API surface */\n/** A server entry from the OpenAPI servers array */\nexport interface ServerEntry {\n url: string;\n description?: string;\n}\n\n/** Root IR node representing the full API surface */\nexport interface ApiSpec {\n name: string;\n version: string;\n description?: string;\n baseUrl: string;\n servers?: ServerEntry[];\n services: Service[];\n models: Model[];\n enums: Enum[];\n auth?: AuthScheme[];\n /**\n * Document-level security requirements: the default every operation uses\n * unless it declares its own `Operation.security`. Same shape and semantics\n * as that field. `undefined` when the document declares none.\n */\n security?: SecurityRequirementSet[];\n /** Language-agnostic runtime policies (retry, errors, telemetry, etc.). */\n sdk: SdkBehavior;\n}\n\n/** A service groups related operations (maps to an SDK resource class) */\nexport interface Service {\n name: string;\n description?: string;\n operations: Operation[];\n}\n\n/** One scheme a request must satisfy, with the scopes it needs. */\nexport interface SecurityRequirement {\n /** Key under `components.securitySchemes`; joins to `AuthScheme.schemeName`. */\n schemeName: string;\n scopes: string[];\n}\n\n/**\n * One alternative from an OpenAPI security requirement list: a request must\n * satisfy *every* scheme in the set together (\"all of\"). A list of sets is\n * satisfied by *any one* of them (\"either of\"). An empty set is an alternative\n * that needs no credentials at all, which is how a document makes\n * authentication optional (`security: [{ userToken: [] }, {}]`).\n */\nexport type SecurityRequirementSet = SecurityRequirement[];\n\n/** A single API operation (maps to an SDK method) */\nexport interface Operation {\n name: string;\n /**\n * The document's `summary` alone. Present only when the OpenAPI operation\n * declares one with non-whitespace content; an empty or whitespace-only\n * summary is treated as absent. Read this to use the summary as a one-line\n * label; `description` below still carries the combined form, so emitters\n * that only print `description` are unchanged.\n */\n summary?: string;\n /**\n * Doc text for the operation. When the document declares both a `summary`\n * and a `description` with content, this is `summary + \"\\n\\n\" + description`;\n * when only one has content (or both are identical), this is that one. An\n * empty or whitespace-only value is treated as absent, and text with content\n * is kept verbatim. The parts are not separable from this field alone — use\n * `summary` for that.\n */\n description?: string;\n httpMethod: HttpMethod;\n path: string;\n pathParams: Parameter[];\n queryParams: Parameter[];\n /**\n * Query parameters the spec also declares as request-body properties on a\n * body-carrying method (POST/PUT/PATCH). They travel in the body only, so\n * they are excluded from `queryParams`; they are kept here so inline enums\n * they declare stay reachable and the compat surface still sees them.\n * Emitters never serialize these to the URL.\n */\n bodyOwnedQueryParams?: Parameter[];\n headerParams: Parameter[];\n cookieParams?: Parameter[];\n requestBody?: TypeRef;\n requestBodyEncoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n response: TypeRef;\n /**\n * Headers the primary success response declares (the one `response` is the\n * body of). Present only when the spec declares at least one. Each entry of\n * `successResponses` carries its own `headers`, but that list only exists\n * when an operation has more than one 2xx, so the primary response's headers\n * need a home of their own.\n */\n responseHeaders?: ResponseHeader[];\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n pagination?: PaginationMeta;\n injectIdempotencyKey: boolean;\n deprecated?: boolean;\n async?: boolean;\n /**\n * Per-operation security requirements, mirroring the OpenAPI document:\n * - `undefined` — the operation declares nothing and inherits\n * `ApiSpec.security` (which may itself be `undefined`).\n * - `[]` — `security: []`: the operation needs no authentication.\n * - otherwise one `SecurityRequirementSet` per requirement object; the\n * request must satisfy any one set, and every scheme within it.\n */\n security?: SecurityRequirementSet[];\n /**\n * Mutually-exclusive parameter groups parsed from `x-mutually-exclusive-parameter-groups`.\n * Each group represents a logical choice the caller must (or may) make between\n * several subsets of query/path/header parameters. The grouped parameters remain\n * in their original arrays (queryParams, pathParams, etc.) for wire-format purposes;\n * this field adds the grouping metadata so emitters can render sum types.\n */\n parameterGroups?: ParameterGroup[];\n}\n\n/**\n * A mutually-exclusive parameter group. The caller must supply exactly one\n * variant (when `optional` is false) or may omit the group entirely (when true).\n */\nexport interface ParameterGroup {\n /** Group name from the extension (e.g. \"parent_resource\"). */\n name: string;\n /** True when the whole group may be omitted. */\n optional: boolean;\n /** Ordered variants (insertion order matches the spec). */\n variants: ParameterGroupVariant[];\n /**\n * Base name emitters must use for this group's generated wrapper type, in\n * place of `name`.\n *\n * Two operations commonly share one group name — create and update both\n * declare `protocol_options` — and emitters name the wrapper from the group\n * name alone, so both operations collapse onto one type. That is correct\n * only while their members agree. When they disagree (create's\n * `saml_options` is a `CreateConnectionSAMLOptions`, update's is a\n * `PatchConnectionSAMLOptions`) one wrapper silently forces one operation to\n * use the other operation's type.\n *\n * The parser therefore fingerprints each group's members across every\n * operation declaring it and qualifies this with the operation name\n * (`update_connection_protocol_options`) only where they genuinely diverge.\n * Groups that agree — including ones differing only by nullability, or by\n * duplicate inline enums carrying identical values — keep the bare group\n * name, so already-published wrapper types are never renamed.\n */\n wrapperName?: string;\n}\n\n/**\n * One variant within a mutually-exclusive parameter group.\n */\nexport interface ParameterGroupVariant {\n /** Variant name from the extension (e.g. \"by_id\", \"by_external_id\"). */\n name: string;\n /**\n * References to the actual parameter IR nodes. These are the same\n * objects that live in operation.queryParams / .pathParams / .headerParams --\n * shared by identity, not duplicated.\n */\n parameters: Parameter[];\n /**\n * Names of parameters that may be omitted when this variant is used —\n * optional modifiers of the variant's required fields, from the\n * extension's `optionalFields`. Absent means every parameter in the\n * variant is required with it.\n */\n optionalParameters?: string[];\n}\n\n/** Structured pagination metadata for auto-paging iterator generation */\nexport interface PaginationMeta {\n strategy: 'cursor' | 'offset' | 'link-header';\n param: string;\n limitParam?: string;\n dataPath?: string;\n itemType: TypeRef;\n /**\n * Every property the list envelope carries besides the data array, in\n * document order: the pagination companion (`list_metadata`, `pagination`,\n * `has_more`, …) and any discriminant such as `object: \"list\"`. Together\n * with `dataPath` and `itemType` this is the envelope's full shape, so an\n * emitter can type what the endpoint returns and read the page details it\n * needs for the next request without parsing the document itself.\n *\n * An inline companion object is lifted to a model. Because the same envelope\n * recurs on every list endpoint of an API, copies that agree structurally\n * share one model named from the property alone (`list_metadata` →\n * `ListMetadata`, or the component schema of that name when one exists); a\n * copy whose shape differs keeps an operation-qualified name\n * (`ListUsersListMetadata`) so it can never change another type's shape.\n *\n * Absent when the response is a bare array, or when pagination was inferred\n * from query parameters alone and no envelope was detected.\n */\n envelopeFields?: Field[];\n}\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\n/**\n * JSON Schema validation keywords declared directly on a schema, carried so an\n * emitter can document a value's limits (\"at most 100\"), check a value before\n * sending it, or keep a generated example within range. Every member is\n * optional and present only when the document declares it; a schema with no\n * validation keyword has no `constraints` at all.\n *\n * Numeric bounds use the OpenAPI 3.1 / JSON Schema 2020-12 shape, where\n * `exclusiveMinimum` / `exclusiveMaximum` are the bound itself. OpenAPI 3.0\n * spells them as booleans that make `minimum` / `maximum` exclusive; the\n * parser normalizes that form, so `{ minimum: 0, exclusiveMinimum: true }`\n * arrives as `{ exclusiveMinimum: 0 }` with no `minimum`, and a `false` is\n * dropped. Emitters read one shape whichever version produced it.\n *\n * The keywords on the field, parameter or model schema itself are carried,\n * conjoined with those of its inline `allOf` members (a single-member\n * `allOf` is unwrapped by the parser, so its limit is the value's own; a\n * `$ref` member contributes the keywords written beside the reference while\n * the referenced model keeps its own). Limits nested inside array `items` or\n * map values are not carried. A nullable wrapper — `oneOf`/`anyOf` with a\n * single non-null, non-`$ref` branch — conjoins that branch's keywords with\n * its own; limits on a general multi-variant union are not carried.\n */\nexport interface Constraints {\n /** Inclusive lower bound (`minimum`). */\n minimum?: number;\n /** Inclusive upper bound (`maximum`). */\n maximum?: number;\n /** Exclusive lower bound as a number; the OAS 3.0 boolean form is normalized to this. */\n exclusiveMinimum?: number;\n /** Exclusive upper bound as a number; the OAS 3.0 boolean form is normalized to this. */\n exclusiveMaximum?: number;\n /** The value must be an integer multiple of this (`multipleOf`). */\n multipleOf?: number;\n /** Minimum string length in characters (`minLength`). */\n minLength?: number;\n /** Maximum string length in characters (`maxLength`). */\n maxLength?: number;\n /** ECMA-262 regular expression the string must match (`pattern`), verbatim from the document. */\n pattern?: string;\n /** Minimum number of array items (`minItems`). */\n minItems?: number;\n /** Maximum number of array items (`maxItems`). */\n maxItems?: number;\n /** Present, and `true`, when array items must be unique; `uniqueItems: false` restates the default and is dropped. */\n uniqueItems?: boolean;\n /** Minimum number of items matching the schema's `contains` (`minContains`). */\n minContains?: number;\n /** Maximum number of items matching the schema's `contains` (`maxContains`). */\n maxContains?: number;\n /** Minimum number of object properties (`minProperties`). */\n minProperties?: number;\n /** Maximum number of object properties (`maxProperties`). */\n maxProperties?: number;\n /** Property name → properties that must also be present when it is (`dependentRequired`). */\n dependentRequired?: Record<string, string[]>;\n}\n\nexport interface Parameter {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n deprecated?: boolean;\n default?: unknown;\n /**\n * A single illustrative value, resolved level by level: the parameter's own\n * `example` (else the first entry of its `examples` map), then its inline\n * schema's `example` (else the first of its `examples` list), then the same\n * on the component schema its `$ref` points at. A level with neither falls\n * through; an explicit `null` is kept. Absent when no level gives one.\n */\n example?: unknown;\n /**\n * Every example value the document gives, in document order: the\n * parameter's `examples` map of Example Objects (each entry's `value`, with\n * `$ref`s resolved against `components.examples`), else the JSON Schema\n * `examples` list on its inline schema, else the list on the component\n * schema its `$ref` points at. Present only when at least one value exists.\n */\n examples?: unknown[];\n style?: 'form' | 'simple' | 'label' | 'matrix';\n explode?: boolean;\n /**\n * Validation keywords from the parameter's schema. When that schema is a\n * `$ref`, the target's keywords are merged underneath the parameter's own\n * — the per-value fallback `default` and `example` use — so a parameter\n * can be read on its own without chasing the fieldless alias model the\n * target also becomes. Absent when neither declares any.\n */\n constraints?: Constraints;\n}\n\n/** Type reference — the core type system of the IR */\nexport type TypeRef = PrimitiveType | ArrayType | ModelRef | EnumRef | UnionType | NullableType | LiteralType | MapType;\n\nexport interface PrimitiveType {\n kind: 'primitive';\n type: 'string' | 'integer' | 'number' | 'boolean' | 'unknown';\n format?: string;\n}\n\nexport interface ArrayType {\n kind: 'array';\n items: TypeRef;\n}\n\nexport interface ModelRef {\n kind: 'model';\n name: string;\n}\n\nexport interface EnumRef {\n kind: 'enum';\n name: string;\n values?: (string | number)[];\n}\n\nexport interface LiteralType {\n kind: 'literal';\n value: string | number | boolean | null;\n}\n\nexport interface UnionType {\n kind: 'union';\n variants: TypeRef[];\n discriminator?: { property: string; mapping: Record<string, string> };\n /** Which OAS composition keyword produced this union. Emitters can use this to\n * distinguish inheritance (allOf) from exclusive union (oneOf) from open union (anyOf). */\n compositionKind?: 'allOf' | 'oneOf' | 'anyOf';\n}\n\nexport interface NullableType {\n kind: 'nullable';\n inner: TypeRef;\n}\n\nexport interface MapType {\n kind: 'map';\n valueType: TypeRef;\n keyType?: TypeRef;\n}\n\n/**\n * A generic type parameter on a model.\n * Example: `DirectoryUser<TCustomAttributes = Record<string, unknown>>`\n * → `{ name: 'TCustomAttributes', default: { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } } }`\n */\nexport interface TypeParam {\n name: string;\n /** Default type when the param is not specified. */\n default?: TypeRef;\n}\n\n/** Model definition (maps to an SDK model/data class) */\nexport interface Model {\n name: string;\n description?: string;\n fields: Field[];\n /** Generic type parameters. Empty/undefined for non-generic models. */\n typeParams?: TypeParam[];\n /**\n * When set, this model is a discriminated union over allOf+oneOf variants.\n * Emitters should generate a dispatcher (factory) instead of a regular dataclass.\n * The `property` field is the discriminator key (e.g. \"event\"), and `mapping`\n * maps each discriminator value to the concrete variant model name.\n */\n discriminator?: {\n property: string;\n mapping: Record<string, string>;\n };\n /**\n * Validation keywords declared on the model's own schema — for an object\n * schema, `minProperties`, `maxProperties` and `dependentRequired`. Absent\n * when the schema declares none.\n */\n constraints?: Constraints;\n}\n\nexport interface Field {\n name: string;\n /**\n * Optional domain-facing name override. When set, emitters derive the\n * domain-side identifier (in their own casing) from this instead of `name`,\n * while serialization still uses `name` for the wire key. Lets an SDK expose\n * a wire field under a friendlier name (e.g. `connection_type` → `type`)\n * without changing the API contract. Set via the `fieldHints` config and\n * honored by any emitter that reads it.\n */\n domainName?: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n readOnly?: boolean;\n writeOnly?: boolean;\n deprecated?: boolean;\n default?: unknown;\n /**\n * A single illustrative value. The field schema's `example` when present,\n * otherwise the first entry of its `examples`; when the schema is a `$ref`\n * with neither, the same taken from the component it points at. An\n * explicit `null` is kept. Absent when no level gives one.\n */\n example?: unknown;\n /**\n * Every example value the schema gives, in document order, from the JSON\n * Schema `examples` list (OAS 3.1 deprecates `example` in its favour) —\n * on the field schema, else on the component its `$ref` points at.\n * Present only when the list has at least one entry.\n */\n examples?: unknown[];\n /**\n * Validation keywords declared on the field's schema, including any\n * written beside a `$ref` (OpenAPI 3.1 allows siblings). Absent when the\n * schema declares none; a bare `$ref` yields none, since the referenced\n * model carries its own limits.\n */\n constraints?: Constraints;\n}\n\n/** Enum definition */\nexport interface Enum {\n name: string;\n values: EnumValue[];\n /** Spec-level default value (the value of `default:` on the schema). Optional. */\n default?: string | number;\n}\n\nexport interface EnumValue {\n name: string;\n value: string | number;\n description?: string;\n deprecated?: boolean;\n}\n\n/**\n * Exhaustive check helper for TypeRef switches.\n * If a new kind is added to TypeRef, any switch that doesn't handle it\n * will fail to compile because `never` won't accept the unhandled variant.\n *\n * Usage:\n * switch (ref.kind) {\n * case 'primitive': ...\n * case 'array': ...\n * // If you forget 'literal', TypeScript errors here:\n * default: assertNever(ref);\n * }\n */\nexport function assertNever(x: never): never {\n // Inline to avoid importing from ../errors.js (ir/ is layer 0, must not import upward)\n const kind = (x as TypeRef).kind;\n const err = new Error(\n `Unexpected TypeRef kind: ${kind}\\nHint: If you added a new TypeRef variant, handle it in every switch/case that calls assertNever.`,\n );\n err.name = 'InternalError';\n throw err;\n}\n\n/**\n * Generic depth-first walker for TypeRef trees.\n * Handles recursion into array/nullable/union/map children and provides\n * an exhaustive `assertNever` check so callers don't need to repeat the\n * switch boilerplate. Supply callbacks only for the leaf kinds you care about.\n */\nexport function walkTypeRef(\n ref: TypeRef,\n visitor: {\n model?: (ref: ModelRef) => void;\n enum?: (ref: EnumRef) => void;\n primitive?: (ref: PrimitiveType) => void;\n literal?: (ref: LiteralType) => void;\n },\n): void {\n switch (ref.kind) {\n case 'model':\n visitor.model?.(ref);\n break;\n case 'enum':\n visitor.enum?.(ref);\n break;\n case 'array':\n walkTypeRef(ref.items, visitor);\n break;\n case 'nullable':\n walkTypeRef(ref.inner, visitor);\n break;\n case 'union':\n for (const v of ref.variants) walkTypeRef(v, visitor);\n break;\n case 'map':\n if (ref.keyType) walkTypeRef(ref.keyType, visitor);\n walkTypeRef(ref.valueType, visitor);\n break;\n case 'literal':\n visitor.literal?.(ref);\n break;\n case 'primitive':\n visitor.primitive?.(ref);\n break;\n default:\n assertNever(ref);\n }\n}\n\n/**\n * Generic depth-first mapper for TypeRef trees.\n * Like walkTypeRef but returns a transformed value instead of void.\n * Handles recursion into array/nullable/union/map children, passing\n * already-mapped child values to the parent callback.\n */\nexport function mapTypeRef<T>(\n ref: TypeRef,\n mapper: {\n primitive: (ref: PrimitiveType) => T;\n array: (ref: ArrayType, mappedItems: T) => T;\n model: (ref: ModelRef) => T;\n enum: (ref: EnumRef) => T;\n union: (ref: UnionType, mappedVariants: T[]) => T;\n nullable: (ref: NullableType, mappedInner: T) => T;\n literal: (ref: LiteralType) => T;\n map: (ref: MapType, mappedValue: T, mappedKey?: T) => T;\n },\n): T {\n switch (ref.kind) {\n case 'primitive':\n return mapper.primitive(ref);\n case 'array':\n return mapper.array(ref, mapTypeRef(ref.items, mapper));\n case 'model':\n return mapper.model(ref);\n case 'enum':\n return mapper.enum(ref);\n case 'union':\n return mapper.union(\n ref,\n ref.variants.map((v) => mapTypeRef(v, mapper)),\n );\n case 'nullable':\n return mapper.nullable(ref, mapTypeRef(ref.inner, mapper));\n case 'literal':\n return mapper.literal(ref);\n case 'map':\n return mapper.map(\n ref,\n mapTypeRef(ref.valueType, mapper),\n ref.keyType ? mapTypeRef(ref.keyType, mapper) : undefined,\n );\n default:\n return assertNever(ref);\n }\n}\n\n// --- IR traversal utilities ---\n\n/**\n * Collect all model names referenced (directly or transitively) by a TypeRef.\n */\nexport function collectModelRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { model: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all enum names referenced by a TypeRef.\n */\nexport function collectEnumRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { enum: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all TypeRef-referenced model and enum names from a model's fields.\n * Returns { models, enums } sets for generating import statements.\n */\nexport function collectFieldDependencies(model: Model): {\n models: Set<string>;\n enums: Set<string>;\n} {\n const models = new Set<string>();\n const enums = new Set<string>();\n\n for (const field of model.fields) {\n for (const name of collectModelRefs(field.type)) {\n if (name !== model.name) models.add(name);\n }\n for (const name of collectEnumRefs(field.type)) {\n enums.add(name);\n }\n }\n\n return { models, enums };\n}\n\n/**\n * Assign each model to the service that first references it.\n * Models referenced by multiple services are assigned to the first.\n * Models not referenced by any service are unassigned (absent from the map).\n *\n * @param hints - Optional pin overrides keyed by IR model name → IR service\n * name. Applied after the natural assignment loop. A hint only pins a model\n * present in THIS `models` slice; the target service is resolved by name\n * downstream, so a hint pointing at a service outside `services` still lands\n * the model in the right directory. Callers may pass a PARTIAL slice (e.g.\n * discriminated-union planning, per-service barrels, or a `--services`-scoped\n * run), so this function never rejects a hint — typo validation lives in\n * {@link validateModelHints}, which runs once against the full spec.\n */\nexport function assignModelsToServices(\n models: Model[],\n services: Service[],\n hints?: Record<string, string>,\n): Map<string, string> {\n const modelToService = new Map<string, string>();\n const modelNames = new Set(models.map((m) => m.name));\n\n for (const service of services) {\n const referencedModels = new Set<string>();\n\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n referencedModels.add(name);\n }\n }\n for (const name of collectModelRefs(op.response)) {\n referencedModels.add(name);\n }\n for (const param of [\n ...op.pathParams,\n ...op.queryParams,\n ...(op.bodyOwnedQueryParams ?? []),\n ...op.headerParams,\n ...(op.cookieParams ?? []),\n ]) {\n for (const name of collectModelRefs(param.type)) {\n referencedModels.add(name);\n }\n }\n if (op.pagination) {\n for (const name of collectModelRefs(op.pagination.itemType)) {\n referencedModels.add(name);\n }\n for (const field of op.pagination.envelopeFields ?? []) {\n for (const name of collectModelRefs(field.type)) {\n referencedModels.add(name);\n }\n }\n }\n for (const header of collectResponseHeaders(op)) {\n for (const name of collectModelRefs(header.type)) {\n referencedModels.add(name);\n }\n }\n }\n\n // Transitively collect models referenced by the directly-referenced models\n const toVisit = [...referencedModels];\n while (toVisit.length > 0) {\n const name = toVisit.pop()!;\n const model = models.find((m) => m.name === name);\n if (!model) continue;\n for (const field of model.fields) {\n for (const ref of collectModelRefs(field.type)) {\n if (!referencedModels.has(ref) && modelNames.has(ref)) {\n referencedModels.add(ref);\n toVisit.push(ref);\n }\n }\n }\n }\n\n for (const name of referencedModels) {\n if (!modelToService.has(name)) {\n modelToService.set(name, service.name);\n }\n }\n }\n\n if (hints) {\n for (const [modelName, serviceName] of Object.entries(hints)) {\n // Only pin models present in THIS slice; an out-of-slice hint is applied\n // where its own slice is processed. The target service resolves by name\n // downstream, so it need not appear in this slice's `services`. Genuine\n // typos are caught up front by validateModelHints against the full spec.\n if (!modelNames.has(modelName)) continue;\n modelToService.set(modelName, serviceName);\n }\n }\n\n return modelToService;\n}\n\n/**\n * Validate model-placement hints against the FULL spec. Run once at the start of\n * generation — where the complete model/service universe is known — so typos in\n * `modelHints` fail loud even though {@link assignModelsToServices} is\n * intentionally lenient about the partial slices it may be handed.\n */\nexport function validateModelHints(models: Model[], services: Service[], hints: Record<string, string>): void {\n const modelNames = new Set(models.map((m) => m.name));\n const serviceNames = new Set(services.map((s) => s.name));\n for (const [modelName, serviceName] of Object.entries(hints)) {\n if (!modelNames.has(modelName)) {\n const err = new Error(\n `modelHints: unknown model \"${modelName}\". Hint keys must match an IR model name (post-cleanSchemaName/schemaNameTransform).`,\n );\n err.name = 'ConfigError';\n throw err;\n }\n if (!serviceNames.has(serviceName)) {\n const err = new Error(\n `modelHints: unknown service \"${serviceName}\" for model \"${modelName}\". Hint values must match an IR service name (PascalCase, derived from the operation's first tag).`,\n );\n err.name = 'ConfigError';\n throw err;\n }\n }\n}\n\n/**\n * Collect all model names referenced as request bodies across all services.\n */\nexport function collectRequestBodyModels(services: Service[]): Set<string> {\n const result = new Set<string>();\n for (const service of services) {\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n result.add(name);\n }\n }\n }\n }\n return result;\n}\n\n/**\n * Every response header an operation declares: the primary response's, each\n * alternate success entry's, and each error entry's. The primary list is the\n * same array as its `successResponses` entry when both exist, so it is yielded\n * once. Every pass that walks an operation's type refs (reachability, model\n * assignment, ref rewriting and validation, direction, compat filtering, enum\n * collection) goes through this so a type reached only through a header is\n * treated the way a body or parameter type is.\n */\nexport function collectResponseHeaders(op: Operation): ResponseHeader[] {\n const result: ResponseHeader[] = [];\n const seen = new Set<ResponseHeader[]>();\n const lists = [\n op.responseHeaders,\n ...(op.successResponses ?? []).map((r) => r.headers),\n ...op.errors.map((e) => e.headers),\n ];\n for (const list of lists) {\n if (!list || seen.has(list)) continue;\n seen.add(list);\n result.push(...list);\n }\n return result;\n}\n\n/**\n * A header a response declares, typed like a parameter. `name` is kept exactly\n * as written in the spec (e.g. `Content-Disposition`); emitters apply their\n * own casing.\n */\nexport interface ResponseHeader {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n deprecated?: boolean;\n}\n\nexport interface ErrorResponse {\n statusCode: number;\n type?: TypeRef;\n /** Declared response headers. Present only when the spec declares at least one. */\n headers?: ResponseHeader[];\n}\n\n/** A successful response entry from a 2xx status code */\nexport interface SuccessResponse {\n statusCode: number;\n type: TypeRef;\n /** Declared response headers. Present only when the spec declares at least one. */\n headers?: ResponseHeader[];\n}\n","import type { Constraints, Model, Field } from '../ir/types.js';\nimport { toPascalCase, stripListItemMarkers, singularize } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport {\n buildFieldFromSchema,\n constraintsEntry,\n extractConstraints,\n isInlineObjectSchema,\n nameInlineVariantEntries,\n nameInlineVariants,\n resolveSchemaName,\n variantMemberSchemas,\n} from './schemas.js';\n\n/**\n * Qualify an inline model name with the parent schema name.\n * If `parentName` is provided and the field name doesn't already start with\n * the parent, the result is `${parentName}${PascalField}` with the trailing\n * word singularized (e.g., Connection + Domains → ConnectionDomain).\n */\nexport function qualifyInlineModelName(baseName: string, parentName?: string): string {\n if (!parentName) return baseName;\n // Strip ListItem/ByExternalId markers from parent name so inline model names\n // are clean, for response models as much as component ones.\n // e.g., ConnectionListItem + Domains → Connection + Domain = ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n if (baseName.startsWith(cleanParent)) return baseName;\n // Singularize the trailing PascalCase word of the combined name.\n // Split baseName into leading words + trailing word, singularize trailing.\n const trailingMatch = baseName.match(/^(.*?)([A-Z][a-z]*)$/);\n if (trailingMatch) {\n const [, prefix, trailingWord] = trailingMatch;\n const singular = singularize(trailingWord);\n return `${cleanParent}${prefix}${singular}`;\n }\n return `${cleanParent}${baseName}`;\n}\n\n/**\n * The inline model or enum names `schemaToTypeRef` would mint for `schema`\n * typed under `contextName` with `parentModelName`; empty when it mints none\n * (a `$ref`, a primitive, an array or map of those). Mirrors the naming\n * branches of `schemaToTypeRef`: an inline object in any form it recognises\n * (`properties`, an `allOf` with object members) takes\n * `qualifyInlineModelName`; a `oneOf`/`anyOf` mints one model per inline\n * object variant, named exactly as the union references them\n * (`nameInlineVariants`: `DrawingLayer`, `DrawingLayerWithOpacity`, or\n * `CircleDrawingLayer` when every variant is titled); an inline enum, or a\n * `oneOf` of string consts that collapses into one, takes the parent-prefixed\n * enum name, which is never singularized; an array or map claims whatever its\n * items or values would.\n */\nexport function mintedInlineNames(\n contextName: string,\n schema: SchemaObject,\n parentModelName: string | undefined,\n): string[] {\n return mintedInlineNameEntries(contextName, schema, parentModelName).map((entry) => entry.name);\n}\n\n/**\n * An inline name a schema mints, and whether it is context-free: a\n * title-mapped variant's title (`nameInlineVariantEntries`) is the same\n * whatever field, array or map the union sits under, where every other\n * inline name embeds the context it is typed under.\n */\nexport interface MintedInlineName {\n name: string;\n contextFree: boolean;\n /** The variant schema a union variant's name was minted for; `reservedInlineNames` compares shapes through it. */\n schema?: SchemaObject;\n}\n\n/** `mintedInlineNames`, also telling for each name whether it is context-free. */\nexport function mintedInlineNameEntries(\n contextName: string,\n schema: SchemaObject,\n parentModelName: string | undefined,\n): MintedInlineName[] {\n const s = unwrapNullableSchema(schema);\n if (s.$ref) return [];\n const base = toPascalCase(contextName);\n const modelName = (): MintedInlineName[] => [\n { name: qualifyInlineModelName(base, parentModelName), contextFree: false },\n ];\n const enumName = (): MintedInlineName[] => {\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n return [\n { name: cleanParent && !base.startsWith(cleanParent) ? `${cleanParent}${base}` : base, contextFree: false },\n ];\n };\n if (s.allOf) {\n const only = s.allOf.length === 1 ? s.allOf[0] : undefined;\n if (only) return mintedInlineNameEntries(contextName, only, parentModelName);\n return s.allOf.some((m) => !m.$ref && (m.properties || m.type === 'object')) ? modelName() : [];\n }\n const variants = s.oneOf ?? s.anyOf;\n if (variants) {\n const nonNull = variants.filter((v) => !isNullSchema(v));\n if (nonNull.length >= 2 && nonNull.every((v) => typeof v.const === 'string')) return enumName();\n return [...nameInlineVariantEntries(s, modelName()[0]!.name)].map(([variant, entry]) => ({\n ...entry,\n schema: variant,\n }));\n }\n if (s.const !== undefined) return [];\n if ((s.enum ?? []).filter((v) => v !== null).length >= 2) return enumName();\n // A plain boolean: the type guard would otherwise narrow `s` to `never` below.\n const inlineObject: boolean = isInlineObjectSchema(s);\n if (inlineObject) return modelName();\n if (s.items && (s.type === 'array' || !s.type)) return mintedInlineNameEntries(contextName, s.items, parentModelName);\n if (s.type === 'object' && !s.properties) {\n const value = mapValueSchema(s);\n return value ? mintedInlineNameEntries(contextName, value, parentModelName) : [];\n }\n return [];\n}\n\n/**\n * The inline names the other properties of an object mint\n * (`mintedInlineNameEntries`) which a `oneOf`/`anyOf` under `fieldName` must\n * not give one of its variants (`nameInlineVariants`): beside a\n * `shape_with_side` object, the `{ side }` variant of `shape` cannot become\n * `DrawingShapeWithSide`. Every context-dependent sibling name is reserved.\n * A context-free name — a title-mapped variant's title — names one shape\n * wherever it appears, so it is shared, not reserved, when this field gives\n * the same title a variant of the identical shape (`schemaShapeKey`:\n * documentation keywords ignored, property names verbatim — the rule array\n * items already use to share a singular sibling's model); a sibling giving\n * the same title a different shape, or one this field does not use, reserves\n * it, so this union's variant falls back to its context-qualified name. Each\n * sibling's names are read in isolation, without the reservations that\n * sibling would itself apply, so the set depends on sibling names and content\n * only, two unions beside each other cannot chase each other's names, and\n * the shape test is symmetric: when `Circle` means `{ radius }` on one side\n * and `{ diameter }` on the other, both fall back (`CircleDrawingShape`,\n * `CircleDrawingMarker`) and neither keeps the bare `Circle`. Empty without a\n * sibling set, as for a request body or response that is itself a union.\n */\nexport function reservedInlineNames(\n fieldName: string,\n siblings: ReadonlyMap<string, SchemaObject> | undefined,\n parentModelName: string | undefined,\n): ReadonlySet<string> {\n const reserved = new Set<string>();\n if (!siblings) return reserved;\n\n // The shape this field gives each title it would keep, in isolation.\n const ownShapes = new Map<string, string[]>();\n const fieldSchema = siblings.get(fieldName);\n if (fieldSchema) {\n for (const own of mintedInlineNameEntries(fieldName, fieldSchema, parentModelName)) {\n if (!own.contextFree || !own.schema) continue;\n ownShapes.set(own.name, [...(ownShapes.get(own.name) ?? []), schemaShapeKey(own.schema)]);\n }\n }\n\n for (const [siblingName, siblingSchema] of siblings) {\n if (siblingName === fieldName) continue;\n for (const minted of mintedInlineNameEntries(siblingName, siblingSchema, parentModelName)) {\n if (!minted.contextFree) {\n reserved.add(minted.name);\n continue;\n }\n const shapes = ownShapes.get(minted.name);\n const siblingShape = minted.schema ? schemaShapeKey(minted.schema) : undefined;\n const identical = shapes !== undefined && siblingShape !== undefined && shapes.every((s) => s === siblingShape);\n if (!identical) reserved.add(minted.name);\n }\n }\n return reserved;\n}\n\n/** Documentation keywords that do not shape a model; ignored by `schemaShapeKey` at a schema's own level. */\nconst DOC_KEYWORDS = new Set(['description', 'title', 'example', 'examples', 'summary', 'externalDocs', 'deprecated']);\n/** Keywords whose value maps NAMES (not keywords) to schemas: names are kept verbatim, values recurse as schemas. */\nconst NAMED_SCHEMA_MAPS = new Set(['properties', 'patternProperties', 'dependentSchemas', '$defs', 'definitions']);\n/** Keywords whose value is a single schema. */\nconst SCHEMA_KEYWORDS = new Set([\n 'items',\n 'additionalProperties',\n 'additionalItems',\n 'contains',\n 'propertyNames',\n 'not',\n 'if',\n 'then',\n 'else',\n 'unevaluatedProperties',\n 'unevaluatedItems',\n]);\n/** Keywords whose value is an ordered list of schemas. */\nconst SCHEMA_LIST_KEYWORDS = new Set(['allOf', 'oneOf', 'anyOf', 'prefixItems']);\n/** Keywords whose list value is a set: compared order-insensitively. */\nconst UNORDERED_LIST_KEYWORDS = new Set(['required', 'type']);\n\n/**\n * A canonical rendering of a schema's shape, for deciding whether two inline\n * schemas describe the same model: every structural keyword (`type`,\n * `properties`, `required`, `items`, `additionalProperties`,\n * `patternProperties`, `allOf`/`oneOf`/`anyOf`, `enum`, `const`, `format`,\n * `nullable`, ...) recursively, with keywords sorted and the `required` and\n * `type` lists order-insensitive. Documentation keywords (`description`,\n * `title`, `example`, `examples`, `summary`, `externalDocs`, `deprecated`)\n * and vendor extensions (`x-*`) are ignored, and so is `nullable: false`,\n * which the nullable unwrap leaves behind — but only where they are a\n * schema's own keywords. Inside `properties`, `patternProperties`,\n * `dependentSchemas`, `dependentRequired` and `$defs` the keys are property\n * names, kept verbatim: a field named `description` or `title` is part of the\n * shape. Enum, const and default values are compared as plain data, in\n * order, as the IR keeps them.\n */\nexport function schemaShapeKey(schema: SchemaObject): string {\n const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n // Plain data (enum members, const, default): sorted keys, nothing stripped.\n const dataKey = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(dataKey);\n if (!isRecord(value)) return value;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value).sort()) out[key] = dataKey(value[key]);\n return out;\n };\n const schemaKey = (value: unknown): unknown => {\n if (!isRecord(value)) return value; // boolean schemas such as `additionalProperties: true`\n const out: Record<string, unknown> = {};\n for (const keyword of Object.keys(value).sort()) {\n const v = value[keyword];\n if (DOC_KEYWORDS.has(keyword) || keyword.startsWith('x-')) continue;\n if (keyword === 'nullable' && v === false) continue;\n if (NAMED_SCHEMA_MAPS.has(keyword) && isRecord(v)) {\n const named: Record<string, unknown> = {};\n for (const name of Object.keys(v).sort()) named[name] = schemaKey(v[name]);\n out[keyword] = named;\n } else if (keyword === 'dependentRequired' && isRecord(v)) {\n const named: Record<string, unknown> = {};\n for (const name of Object.keys(v).sort()) {\n const names = v[name];\n named[name] = Array.isArray(names) ? names.map(String).sort() : dataKey(names);\n }\n out[keyword] = named;\n } else if (SCHEMA_KEYWORDS.has(keyword)) {\n out[keyword] = schemaKey(v);\n } else if (SCHEMA_LIST_KEYWORDS.has(keyword) && Array.isArray(v)) {\n out[keyword] = v.map(schemaKey);\n } else if (UNORDERED_LIST_KEYWORDS.has(keyword) && Array.isArray(v)) {\n out[keyword] = v.map(String).sort();\n } else {\n out[keyword] = dataKey(v);\n }\n }\n return out;\n };\n return JSON.stringify(schemaKey(schema));\n}\n\n/**\n * The context name an array field's items (`kind: 'item'`) or a map field's\n * values (`kind: 'value'`) are typed and extracted under. By default it is\n * the field itself, so the inline model is the parent plus the singularized\n * field (`layers` on `Drawing` → `DrawingLayer`).\n *\n * When a sibling property of the same object would mint that very name —\n * `layer` as an inline object, an inline enum, an inline union with object\n * variants (any of whose variant names counts), or an array or map of such\n * (`mintedInlineNames`); a primitive `email` beside `emails` claims nothing\n * — the elements step aside to\n * `<field>_item` / `<field>_value`, which qualify to `<Parent><Field>Item` /\n * `<Parent><Field>Value` (`DrawingLayersItem`, `DrawingLayersValue`),\n * matching the `<Variant>Item` convention. Should a sibling mint that name\n * too (a property `layers_item`), the fallback keeps going the way\n * `variantMemberKeys` does for variants: `<field>_array_item`, then\n * `<field>_array_item2`, `<field>_array_item3`, ... for items\n * (`DrawingLayersArrayItem`, ...) and `<field>_member_value`,\n * `<field>_member_value2`, ... for values, taking the first candidate whose\n * minted name no sibling claims.\n *\n * Identical-shape sharing: when every sibling claiming the singular name is\n * an inline object whose shape is structurally identical to the items or\n * values (`schemaShapeKey`: same properties, required, types, nested inline\n * schemas and enum values; description, title and example ignored), the\n * fields share one model under the singular name. They are the same shape,\n * so one model is the right SDK type and a duplicate would only add noise;\n * should a later spec version make the shapes diverge, the split happens\n * then, which is the moment the item type genuinely changes. This\n * deliberately departs from a literal one-model-per-field reading for the\n * identical case.\n *\n * Only context-dependent names take part: a title-mapped variant's title\n * (`MintedInlineName.contextFree`) is the same under every context, so no\n * candidate could step away from it, and such a name is shared by design —\n * two sibling arrays whose items carry the same titled variants both\n * reference `Circle` and `Square` (`nameInlineVariants`). The search always\n * terminates: it stops as soon as a candidate changes nothing about the names\n * (`firstFreeElementContext`'s no-progress rule), and\n * `MAX_ELEMENT_CONTEXT_ATTEMPTS` caps it as a backstop; both return the last\n * candidate tried, deterministically.\n *\n * Decided from sibling names and schema content alone, so document order\n * plays no part. `schemaToTypeRef` and every extractor call this with the\n * same sibling set (`collectProperties`); otherwise the reference and the\n * model disagree.\n */\nexport function elementContextName(\n fieldName: string,\n kind: 'item' | 'value',\n siblings: ReadonlyMap<string, SchemaObject> | undefined,\n parentModelName: string | undefined,\n elementSchema: SchemaObject,\n): string {\n return elementContextDecision(fieldName, kind, siblings, parentModelName, elementSchema).context;\n}\n\n/** Why `elementContextDecision` settled on a context. */\nexport type ElementContextReason =\n /** No sibling set: nothing to decide. */\n | 'no-siblings'\n /** The elements mint no context-dependent name. */\n | 'nothing-minted'\n /** No sibling claims any name the elements mint. */\n | 'unclaimed'\n /** Every claimant is an inline object of the identical shape: one model is shared. */\n | 'shared-shape'\n /** A later candidate mints only unclaimed names. */\n | 'free'\n /** The names did not change from one candidate to the next, so no candidate can avoid the claim. */\n | 'no-progress'\n /** `MAX_ELEMENT_CONTEXT_ATTEMPTS` candidates were tried; the last one is kept. */\n | 'cap';\n\n/** Hard cap on the candidates `firstFreeElementContext` tries; the no-progress rule stops it long before in practice. */\nexport const MAX_ELEMENT_CONTEXT_ATTEMPTS = 256;\n\n/** `elementContextName`, with the reason it decided as it did (see `ElementContextReason`). */\nexport function elementContextDecision(\n fieldName: string,\n kind: 'item' | 'value',\n siblings: ReadonlyMap<string, SchemaObject> | undefined,\n parentModelName: string | undefined,\n elementSchema: SchemaObject,\n): { context: string; reason: ElementContextReason } {\n if (!siblings) return { context: fieldName, reason: 'no-siblings' };\n // The names the elements would mint under a context — the context-dependent\n // ones only, since a context-free name is shared rather than stepped from.\n const dependentNames = (candidate: string): string[] =>\n mintedInlineNameEntries(candidate, elementSchema, parentModelName)\n .filter((entry) => !entry.contextFree)\n .map((entry) => entry.name);\n const own = dependentNames(fieldName);\n if (own.length === 0) return { context: fieldName, reason: 'nothing-minted' };\n\n // Every inline name the other siblings mint, with the schemas minting it.\n const claimed = new Map<string, SchemaObject[]>();\n for (const [siblingName, siblingSchema] of siblings) {\n if (siblingName === fieldName) continue;\n for (const minted of mintedInlineNames(siblingName, siblingSchema, parentModelName)) {\n claimed.set(minted, [...(claimed.get(minted) ?? []), siblingSchema]);\n }\n }\n\n const rivals = [...new Set(own.flatMap((name) => claimed.get(name) ?? []))];\n if (rivals.length === 0) return { context: fieldName, reason: 'unclaimed' };\n const element = unwrapNullableSchema(elementSchema);\n const identical = (rival: SchemaObject): boolean => {\n const sibling = unwrapNullableSchema(rival);\n return (\n isInlineObjectSchema(sibling) &&\n isInlineObjectSchema(element) &&\n schemaShapeKey(sibling) === schemaShapeKey(element)\n );\n };\n if (rivals.every(identical)) return { context: fieldName, reason: 'shared-shape' };\n\n return firstFreeElementContext(fieldName, kind, new Set(claimed.keys()), dependentNames, own);\n}\n\n/**\n * The first fallback context under which the elements mint no claimed name:\n * `<field>_item` / `<field>_value`, then `<field>_array_item` /\n * `<field>_member_value`, then `<field>_array_item2`, `…3`, ... (the way\n * `variantMemberKeys` numbers a variant's members). `mint` gives the names\n * under a candidate and `previous` those under the context tried before the\n * first candidate. The search stops with `no-progress` as soon as a\n * candidate mints the same names as the one before it — the names do not\n * depend on the context, so no candidate can avoid the claim — and with\n * `cap` after `maxAttempts` candidates; both keep the last candidate tried.\n */\nexport function firstFreeElementContext(\n fieldName: string,\n kind: 'item' | 'value',\n claimed: ReadonlySet<string>,\n mint: (candidate: string) => string[],\n previous: readonly string[],\n maxAttempts: number = MAX_ELEMENT_CONTEXT_ATTEMPTS,\n): { context: string; reason: ElementContextReason } {\n const fallback = kind === 'item' ? 'array_item' : 'member_value';\n let last = previous;\n let candidate = fieldName;\n for (let i = 0; i < maxAttempts; i++) {\n candidate =\n i === 0 ? `${fieldName}_${kind}` : i === 1 ? `${fieldName}_${fallback}` : `${fieldName}_${fallback}${i}`;\n const minted = mint(candidate);\n if (minted.every((name) => !claimed.has(name))) return { context: candidate, reason: 'free' };\n if (sameNames(minted, last)) return { context: candidate, reason: 'no-progress' };\n last = minted;\n }\n return { context: candidate, reason: 'cap' };\n}\n\n/** The same names, in any order. */\nfunction sameNames(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false;\n const sortedB = [...b].sort();\n return [...a].sort().every((name, i) => name === sortedB[i]);\n}\n\n/**\n * Every property the object described by `schema` exposes, by name: its own\n * `properties`, those of its `allOf` members (following a member's `$ref`\n * into `schemas` when given, as `extractAllOfModel` does), and those of\n * inline `oneOf`/`anyOf` variants, whose fields the model extractors flatten\n * in; the first definition of a name wins. This is the sibling set\n * `elementContextName` decides from; the TypeRef builder and every extractor\n * derive it through this one function so they agree.\n */\nexport function collectProperties(\n schema: SchemaObject,\n schemas?: Record<string, SchemaObject>,\n): Map<string, SchemaObject> {\n const properties = new Map<string, SchemaObject>();\n const seen = new Set<SchemaObject>();\n const visit = (s: SchemaObject | undefined, followRef: boolean): void => {\n if (!s || seen.has(s)) return;\n seen.add(s);\n if (s.$ref) {\n if (followRef && schemas) visit(schemas[s.$ref.split('/').pop() ?? ''], true);\n return;\n }\n for (const [key, value] of Object.entries(s.properties ?? {})) {\n if (value && !properties.has(key)) properties.set(key, value);\n }\n for (const sub of s.allOf ?? []) visit(sub, true);\n for (const variant of [...(s.oneOf ?? []), ...(s.anyOf ?? [])]) visit(variant, false);\n };\n visit(schema, false);\n return properties;\n}\n\n/**\n * Walk all component schemas and extract inline Model definitions for fields\n * that are objects with properties, including objects reached through array\n * items, `oneOf` variants, and map (`additionalProperties` /\n * `patternProperties`) values.\n * These correspond to the ModelRef entries created by schemaToTypeRef.\n */\nexport function extractInlineModelsFromSchemas(schemas: Record<string, SchemaObject> | undefined): Model[] {\n if (!schemas) return [];\n\n const inlineModels: Model[] = [];\n\n for (const [schemaName, schema] of Object.entries(schemas)) {\n const parentName = resolveSchemaName(schemaName);\n // The same sibling set `extractModel` / `extractAllOfModel` type the\n // component's fields from, `$ref`'d allOf members included.\n extractInlineModelsFromProperties(schema, inlineModels, parentName, schemas, collectProperties(schema, schemas));\n }\n\n return inlineModels;\n}\n\n/**\n * Walk a schema's properties and materialise every inline object as a model.\n * `componentSchemas` is optional and only feeds `buildFieldFromSchema`, so a\n * field that `$ref`s a component can take its `example`/`examples` from it;\n * callers without the component map at hand simply omit it.\n * `siblingProperties` is the parent object's full property set, for callers\n * that see more of it than this schema shows (see `elementContextName`).\n * `reservedNames` is set only on the re-entry for a field's array items or\n * map values: the inline names that field's siblings mint, which a union\n * among the items or values must step around exactly as `schemaToTypeRef`\n * does when it hands the same set down (`reservedNamesFor`).\n *\n * The recursion follows the document's own inline structure only: a `$ref`\n * is resolved solely to read a component's property list for typing (an\n * augmentation's inherited fields, a sibling set), never descended into, so\n * the depth is bounded by the document's inline nesting and no component\n * graph — self-extending, mutually extending, or reused at several levels —\n * can make it run away.\n */\nexport function extractInlineModelsFromProperties(\n schema: SchemaObject,\n results: Model[],\n parentName?: string,\n componentSchemas?: Record<string, SchemaObject>,\n siblingProperties?: ReadonlyMap<string, SchemaObject>,\n reservedNames?: ReadonlySet<string>,\n): void {\n const properties = schema.properties ?? {};\n const allOfSchemas = schema.allOf ?? [];\n // Every property the parent object exposes, so array items and map values\n // can step aside from a sibling that would mint their name (see\n // `elementContextName`). A caller that sees more siblings than this schema\n // shows — an `allOf` member, an envelope field — passes them in.\n const siblings = siblingProperties ?? collectProperties(schema);\n // The names a union under `fieldName` must not take: the set handed down\n // for array items / map values, else what the field's siblings mint.\n const reservedFor = (fieldName: string): ReadonlySet<string> =>\n reservedNames ?? reservedInlineNames(fieldName, siblings, parentName);\n\n for (const sub of allOfSchemas) {\n if (sub.properties) {\n extractInlineModelsFromProperties(sub, results, parentName, componentSchemas, siblings, reservedNames);\n }\n }\n\n for (const [fieldName, rawFieldSchema] of Object.entries(properties)) {\n if (!rawFieldSchema) continue;\n // Dispatch on the shape `schemaToTypeRef` named: it strips nullable\n // wrappers before deciding whether a field is an object, array, or map,\n // so a nullable field must be unwrapped here the same way or its inline\n // object / array items / map values are referenced but never extracted.\n const fieldSchema = unwrapNullableField(rawFieldSchema);\n // Direct inline object with properties (with or without explicit type: 'object',\n // including the nullable `type: ['object', 'null']` form)\n if (isInlineObjectSchema(fieldSchema)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, fieldSchema, componentSchemas));\n extractInlineModelsFromProperties(fieldSchema, results, modelName, componentSchemas);\n }\n\n // Array: schemaToTypeRef types the items with the field's own context\n // name and parent, so every inline model reachable through the items — a\n // plain inline object, the variants of an `items.oneOf`, a nested array\n // or map — is named exactly as if the items schema were the field itself\n // (`shapes` → `CreateDrawingRequestShape`, `SquareCreateDrawingRequestShape`).\n // Re-enter with a synthetic property named by `elementContextName` — the\n // field itself, or `<field>_item` when a sibling would take the singular\n // name — so the branches in this function do the extraction with\n // byte-for-byte identical naming.\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const itemContext = elementContextName(fieldName, 'item', siblings, parentName, fieldSchema.items);\n extractInlineModelsFromProperties(\n { properties: { [itemContext]: fieldSchema.items } },\n results,\n parentName,\n componentSchemas,\n undefined,\n reservedFor(fieldName),\n );\n }\n\n // Map (`additionalProperties` / `patternProperties` on a property-less\n // object): schemaToTypeRef types the values the same way it types array\n // items, so a map of inline objects references `${Parent}${SingularField}`\n // (`layers` on `CreateDrawingRequest` → `CreateDrawingRequestLayer`), or\n // `<Parent><Field>Value` when a sibling takes the singular name. Re-enter\n // with the value schema as a synthetic property of that name.\n if (fieldSchema.type === 'object' && !fieldSchema.properties) {\n const valueSchema = mapValueSchema(fieldSchema);\n if (valueSchema) {\n const valueContext = elementContextName(fieldName, 'value', siblings, parentName, valueSchema);\n extractInlineModelsFromProperties(\n { properties: { [valueContext]: valueSchema } },\n results,\n parentName,\n componentSchemas,\n undefined,\n reservedFor(fieldName),\n );\n }\n }\n\n // A field expressed via `allOf`. Mirror the four outcomes of the allOf\n // branch in `schemaToTypeRef` exactly:\n // - a `$ref` member plus an inline object member: the field is typed as\n // the augmentation model `<Parent><Field>`; merge the referenced\n // component(s) and the inline members into that model\n // (`mergeAugmentation`), with every inherited property typed under\n // its component — `Base.meta` stays `BaseMeta`, a self-reference\n // `Base.child` stays `BaseChild` — and only the inline members' own\n // properties qualified under the merged model and recursed into. The\n // component pass already materialized whatever the inherited\n // properties reference, so nothing is duplicated; a component that\n // extends itself through a field simply points back at a model that\n // exists, and a component reused by several nested augmentations\n // hands each of them its full field list;\n // - `$ref` members only: a plain reference to the first component,\n // nothing to materialize;\n // - a single non-`$ref` member: unwrapped and typed as the field itself,\n // so re-enter with it as the field (same siblings);\n // - several inline members with properties: one merged model.\n if (fieldSchema.allOf) {\n const members = fieldSchema.allOf;\n const emitMerged = (): void => {\n const merged = mergeAugmentation(fieldSchema, componentSchemas);\n if (merged.properties.length === 0) return;\n const modelName = qualifyInlineModelName(toPascalCase(fieldName), parentName);\n results.push(buildMergedModel(modelName, merged, componentSchemas));\n const own: Record<string, SchemaObject> = {};\n for (const p of merged.properties) if (p.origin === null) own[p.name] = p.schema;\n const mergedSiblings = new Map(merged.properties.map((p) => [p.name, p.schema]));\n extractInlineModelsFromProperties({ properties: own }, results, modelName, componentSchemas, mergedSiblings);\n };\n const only = members.length === 1 ? members[0] : undefined;\n if (members.some((m) => m.$ref)) {\n if (members.some((m) => !m.$ref && (m.properties || m.type === 'object'))) emitMerged();\n } else if (only) {\n // The wrapper's own keywords, conjoined with the member's, are the\n // field's limits (see extractConstraints), so they ride along with the\n // unwrapped member and its model carries the same constraints.\n extractInlineModelsFromProperties(\n { properties: { [fieldName]: { ...only, ...extractConstraints(fieldSchema) } } },\n results,\n parentName,\n componentSchemas,\n siblings,\n reservedNames,\n );\n } else if (members.some((m) => m.properties)) {\n emitMerged();\n }\n }\n\n // oneOf/anyOf containing objects — extract every inline object variant as a\n // model so each gets its own typed class, under the names the union\n // TypeRef references them by (`nameInlineVariants`, the one place that\n // decides them): variant 0 keeps the bare qualified inline name\n // (`ApiKeyCreatedDataOwner`), later variants take their const-\n // discriminator value (`UserApiKeyCreatedDataOwner`), their title, a\n // distinguishing property (`DrawingShapeWithSide`) or, for identical\n // property sets, the position counter — never a name a sibling property\n // mints (`reservedInlineNames`), so no variant overwrites another\n // field's model.\n const unionVariants = fieldSchema.oneOf ?? fieldSchema.anyOf;\n if (unionVariants) {\n const inlineObjectVariants = unionVariants.filter((v) => isInlineObjectSchema(v));\n if (inlineObjectVariants.length > 0) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n const existingNames = new Set(results.map((r) => r.name));\n const variantNames = nameInlineVariants(fieldSchema, modelName, reservedFor(fieldName));\n for (const variant of inlineObjectVariants) {\n const variantName = variantNames.get(variant);\n if (variantName === undefined) continue;\n if (!existingNames.has(variantName)) {\n existingNames.add(variantName);\n results.push(buildInlineModel(variantName, variant, componentSchemas));\n extractInlineModelsFromProperties(variant, results, variantName, componentSchemas);\n // A multi-type variant (`type: ['object', 'array']`) types the\n // items of its array member under the variant's name\n // (`<Variant>Item`, see `variantMemberSchemas`); re-enter with\n // them as a same-named synthetic property so the models line up.\n extractInlineModelsFromProperties(\n { properties: variantMemberSchemas(variant, variantName) },\n results,\n variantName,\n componentSchemas,\n );\n }\n }\n }\n }\n }\n}\n\n/** One property of a merged `allOf` field and the component it is inherited from (null: an inline member's own). */\ninterface MergedProperty {\n name: string;\n schema: SchemaObject;\n origin: { name: string; schema: SchemaObject } | null;\n}\n\ninterface MergedAllOf {\n properties: MergedProperty[];\n required: string[];\n description: string | undefined;\n /** The wrapper's own limits conjoined with its inline members' (a `$ref` member contributes only its sibling keywords). */\n constraints: Constraints | undefined;\n}\n\n/**\n * Merge an `allOf` field into one object shape, remembering where each\n * property comes from. A `$ref` member is resolved against `componentSchemas`\n * by its component name, as `extractAllOfModel` does, and contributes its\n * properties — its own nested `allOf` chain included — tagged with that\n * component's model name, so the merged model can type them exactly as the\n * component's own model does; inline members contribute properties tagged as\n * the merged model's own. `required` is collected from every member. Earlier\n * members win on key conflicts, matching the merge order used elsewhere in\n * the parser; an unresolvable ref contributes nothing. The walk reads the\n * components' property lists only — it never descends into a property — so\n * it is finite for any component graph (the `seen` set only short-circuits a\n * component reached twice within one merge).\n */\nfunction mergeAugmentation(\n schema: SchemaObject,\n componentSchemas: Record<string, SchemaObject> | undefined,\n): MergedAllOf {\n const properties: MergedProperty[] = [];\n const seenNames = new Set<string>();\n const required: string[] = [];\n const seen = new Set<SchemaObject>();\n const visit = (s: SchemaObject, origin: MergedProperty['origin']): void => {\n if (seen.has(s)) return;\n seen.add(s);\n if (s.$ref) {\n const rawName = s.$ref.split('/').pop() ?? '';\n const target = componentSchemas?.[rawName];\n if (!target) return;\n // A ref inside a component's own allOf chain stays that component's;\n // a top-level ref member is the component the properties belong to.\n visit(target, origin ?? { name: resolveSchemaName(rawName), schema: target });\n return;\n }\n for (const [key, value] of Object.entries(s.properties ?? {})) {\n if (!value || seenNames.has(key)) continue;\n seenNames.add(key);\n properties.push({ name: key, schema: value, origin });\n }\n if (s.required) required.push(...s.required);\n for (const sub of s.allOf ?? []) visit(sub, origin);\n };\n visit(schema, null);\n // Limits conjoin the way properties merge, so the merged model declares what\n // an instance must satisfy; a `$ref` member's target keeps its own limits.\n return { properties, required, description: schema.description, constraints: extractConstraints(schema) };\n}\n\n/**\n * Build the model for a merged `allOf` field. An inherited property is typed\n * with its component as naming context and the component's own sibling set,\n * so it carries the same TypeRef as in the component's model (`BaseMeta`,\n * `BaseChild`, ...); the merged model's own properties are typed under its\n * name with the full merged property set as siblings.\n */\nfunction buildMergedModel(name: string, merged: MergedAllOf, componentSchemas?: Record<string, SchemaObject>): Model {\n const requiredSet = new Set(merged.required);\n const mergedSiblings = new Map(merged.properties.map((p) => [p.name, p.schema]));\n const componentSiblings = new Map<string, Map<string, SchemaObject>>();\n const fields = merged.properties.map((p) => {\n if (p.origin === null) {\n return buildFieldFromSchema(p.name, p.schema, name, requiredSet, componentSchemas, mergedSiblings);\n }\n let siblings = componentSiblings.get(p.origin.name);\n if (!siblings) {\n siblings = collectProperties(p.origin.schema, componentSchemas);\n componentSiblings.set(p.origin.name, siblings);\n }\n return buildFieldFromSchema(p.name, p.schema, p.origin.name, requiredSet, componentSchemas, siblings);\n });\n return {\n name,\n description: merged.description,\n fields,\n ...(merged.constraints ? { constraints: merged.constraints } : {}),\n };\n}\n\n/**\n * Strip the nullable wrappers `schemaToTypeRef` unwraps before it names\n * anything — the OAS 3.1 `type: [X, 'null']` array, the OAS 3.0\n * `nullable: true` flag, and a `oneOf`/`anyOf` with a single non-null\n * variant — so extraction dispatches on the same shape the TypeRef was built\n * from. The unwrap keeps `contextName`/`parentModelName` semantics intact:\n * `schemaToTypeRef` passes both through each of these wrappers unchanged.\n */\nfunction unwrapNullableSchema(schema: SchemaObject): SchemaObject {\n if (schema.$ref) return schema;\n if (Array.isArray(schema.type)) {\n const nonNullTypes = schema.type.filter((t) => t !== 'null');\n if (nonNullTypes.length !== 1) return schema;\n return unwrapNullableSchema({ ...schema, type: nonNullTypes[0], nullable: false });\n }\n if (schema.nullable && schema.type) {\n return unwrapNullableSchema({ ...schema, nullable: false });\n }\n // `allOf` takes precedence over `oneOf`/`anyOf` in schemaToTypeRef, so only\n // a bare union is a nullable wrapper candidate.\n const variants = schema.allOf ? undefined : (schema.oneOf ?? schema.anyOf);\n if (variants) {\n const nullVariant = variants.find(isNullSchema);\n const nonNullVariants = variants.filter((v) => v !== nullVariant);\n const only = nonNullVariants[0];\n if (nullVariant && nonNullVariants.length === 1 && only) {\n return unwrapNullableSchema(only);\n }\n }\n return schema;\n}\n\n/**\n * `unwrapNullableSchema` for a field, carrying the wrapper's limits onto the\n * branch it unwraps to. The type-array and `nullable: true` forms unwrap by\n * spreading, so every keyword survives; the union form swaps in the bare\n * branch, which would drop a `minProperties` written beside\n * `anyOf: [{ type: 'object', … }, { type: 'null' }]`. `extractConstraints`\n * conjoins that wrapper's own keywords with its branch's as the field's\n * limits, so the model built from the branch must carry the same ones or\n * `Model.constraints` would omit what the field declares.\n */\nfunction unwrapNullableField(schema: SchemaObject): SchemaObject {\n const inner = unwrapNullableSchema(schema);\n if (inner === schema || schema.allOf || !(schema.oneOf ?? schema.anyOf)) return inner;\n return { ...inner, ...extractConstraints(schema) };\n}\n\n/** The `{ type: 'null' }` member that marks a `oneOf`/`anyOf` as nullable — same test as schemaToTypeRef. */\nfunction isNullSchema(schema: SchemaObject): boolean {\n return (\n schema.type === 'null' || (Array.isArray(schema.type) && schema.type.length === 1 && schema.type[0] === 'null')\n );\n}\n\n/**\n * The schema that types a map's values, in the precedence `schemaToTypeRef`\n * uses: a non-empty `additionalProperties` object wins, otherwise the first\n * `patternProperties` entry. `additionalProperties: {}` means \"any value\"\n * (typed `unknown`, nothing to extract) and does not fall through to\n * `patternProperties`, matching the type-ref branch.\n */\nexport function mapValueSchema(schema: SchemaObject): SchemaObject | null {\n const additional = schema.additionalProperties;\n if (additional && typeof additional === 'object') {\n return Object.keys(additional).length > 0 ? additional : null;\n }\n const patterns = schema.patternProperties ? Object.values(schema.patternProperties) : [];\n return patterns[0] ?? null;\n}\n\nfunction buildInlineModel(name: string, schema: SchemaObject, componentSchemas?: Record<string, SchemaObject>): Model {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const siblings = collectProperties(schema);\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet, componentSchemas, siblings));\n }\n\n return { name, description: schema.description, fields, ...constraintsEntry(schema) };\n}\n","import type { Model, Enum, EnumValue, Field, TypeRef, Constraints } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport {\n toPascalCase,\n toUpperSnakeCase,\n cleanSchemaName,\n singularize,\n stripListItemMarkers,\n splitWords,\n} from '../utils/naming.js';\n\n/**\n * Module-level transform set during extractSchemas(). Used by schemaToTypeRef()\n * to apply the same name transform to $ref model/enum references.\n *\n * Receives the cleaned PascalCase name and, when the name is a\n * `components.schemas` key, the raw key exactly as spelled in the document.\n * Names oagen synthesises (inline enums, request-body variant models,\n * title-derived names) pass no second argument.\n */\nlet activeSchemaNameTransform: SchemaNameTransform | null = null;\n\n/**\n * Module-level set of raw `components.schemas` keys for the spec being\n * extracted. resolveSchemaName() consults it to decide whether the name it was\n * handed is a real component key (forwarded to the transform as\n * `originalName`) or a name oagen synthesised (no `originalName`).\n */\nlet activeComponentSchemaKeys: Set<string> = new Set();\n\n/**\n * Module-level set of resolved schema names whose components/schemas entry is\n * an enum (i.e. has `enum:`). Populated by extractSchemas() so schemaToTypeRef()\n * can classify a `$ref` to a top-level enum schema as `kind: 'enum'` instead of\n * `kind: 'model'`. Without this, every `$ref` was naively returned as a model\n * ref, even when the target was a shared enum like `PaginationOrder`.\n */\nlet activeEnumSchemaNames: Set<string> = new Set();\n\n/**\n * Subset of `activeEnumSchemaNames` whose component schema also admits\n * `null` — via an OAS 3.1 `type: [..., 'null']` array, the OAS 3.0\n * `nullable: true` flag, or a literal `null` member in `enum:`. A `$ref` to\n * one of these resolves to `nullable(enum)` so the component's own\n * nullability survives the reference, matching the shape an inline\n * `oneOf: [{ $ref }, { type: 'null' }]` already produces.\n */\nlet activeNullableEnumSchemaNames: Set<string> = new Set();\n\n/** Drop `null` from an `enum:` list — it marks nullability, it is not a member. */\nfunction nonNullEnumValues(values: SchemaObject['enum']): (string | number)[] {\n return (values ?? []).filter((v): v is string | number => v !== null);\n}\n\n/** True when an enum schema admits `null` by any OAS 3.0 / 3.1 spelling. */\nfunction isNullableEnumSchema(schema: SchemaObject): boolean {\n if (schema.nullable === true) return true;\n if (Array.isArray(schema.type) && schema.type.includes('null')) return true;\n return Array.isArray(schema.enum) && schema.enum.includes(null);\n}\n\n/** Wrap `ref` in `nullable` unless it already is one, so a nullable enum `$ref` is never double-wrapped. */\nfunction asNullable(ref: TypeRef): TypeRef {\n return ref.kind === 'nullable' ? ref : { kind: 'nullable', inner: ref };\n}\n\n/**\n * Apply cleanSchemaName + the active transform (if any) to a raw schema name.\n * When `rawName` is a `components.schemas` key the transform also receives it\n * as `originalName`, so a consumer can opt out of normalization by returning\n * the original spelling. Names oagen synthesises (request-body variant\n * models, title-derived names, ...) are not component keys and get no\n * `originalName`.\n */\nexport function resolveSchemaName(rawName: string): string {\n let name = cleanSchemaName(toPascalCase(rawName));\n if (activeSchemaNameTransform) {\n const originalName = activeComponentSchemaKeys.has(rawName) ? rawName : undefined;\n name = activeSchemaNameTransform(name, originalName);\n }\n return name;\n}\n\n/**\n * Signature of the `schemaNameTransform` hook. `name` is the cleaned\n * PascalCase name; `originalName` is the `components.schemas` key exactly\n * as spelled in the document, or `undefined` for names oagen synthesises.\n * See `SchemaExtractionOptions.schemaNameTransform`.\n */\nexport type SchemaNameTransform = (name: string, originalName?: string) => string;\n\nexport interface SchemaExtractionOptions {\n /**\n * Custom transform for schema (model/enum) names. Called with the cleaned\n * PascalCase name and, for component schemas, the original name as spelled\n * in the document (`originalName`). Returning `originalName` opts that\n * schema out of the built-in normalization; only do so when it is a valid\n * identifier, since keys like `user-profile` are otherwise fixed by\n * cleanSchemaName. `originalName` is undefined for\n * any name oagen synthesises (inline enums, request-body variant models,\n * title-derived names).\n */\n schemaNameTransform?: SchemaNameTransform;\n}\n\nexport interface SchemaObject {\n type?: string | string[];\n format?: string;\n description?: string;\n properties?: Record<string, SchemaObject | undefined>;\n required?: string[];\n items?: SchemaObject;\n /** OAS 3.1 allows a literal `null` member when `type` also admits null. */\n enum?: (string | number | null)[];\n allOf?: SchemaObject[];\n oneOf?: SchemaObject[];\n anyOf?: SchemaObject[];\n discriminator?: { propertyName: string; mapping?: Record<string, string> };\n readOnly?: boolean;\n writeOnly?: boolean;\n nullable?: boolean;\n $ref?: string;\n additionalProperties?: boolean | SchemaObject;\n const?: unknown;\n patternProperties?: Record<string, SchemaObject>;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n /** JSON Schema `examples` list; OAS 3.1 deprecates `example` in its favour. */\n examples?: unknown[];\n // JSON Schema validation vocabulary. An exclusive bound is the bound itself\n // in OAS 3.1 and, in OAS 3.0, a boolean that makes `minimum` / `maximum`\n // exclusive; extractConstraints() normalizes both to the 3.1 shape.\n minimum?: number;\n maximum?: number;\n exclusiveMinimum?: number | boolean;\n exclusiveMaximum?: number | boolean;\n multipleOf?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n minItems?: number;\n maxItems?: number;\n uniqueItems?: boolean;\n minContains?: number;\n maxContains?: number;\n minProperties?: number;\n maxProperties?: number;\n dependentRequired?: Record<string, string[]>;\n [key: string]: unknown;\n}\n\n/** Validation keywords copied through unchanged when they hold a number. */\nconst NUMERIC_CONSTRAINT_KEYS = [\n 'multipleOf',\n 'minLength',\n 'maxLength',\n 'minItems',\n 'maxItems',\n 'minContains',\n 'maxContains',\n 'minProperties',\n 'maxProperties',\n] as const;\n\n/**\n * Collect the JSON Schema validation keywords declared directly on `schema`\n * into a `Constraints` object, or `undefined` when it declares none — so a\n * schema without limits yields no `constraints` key on its IR node at all.\n *\n * Numeric bounds are normalized to the OAS 3.1 shape. OAS 3.0 spells an\n * exclusive bound as `exclusiveMinimum: true` beside `minimum: n`; that pair\n * becomes `exclusiveMinimum: n` with no `minimum`. A boolean `false`, or a\n * `true` with no bound to apply to, is dropped. The 3.1 numeric form passes\n * through, including the legal-but-unusual case of both an inclusive and an\n * exclusive bound on the same side. `uniqueItems: false` restates the default\n * and is dropped too.\n *\n * Only the schema's own keywords are read: limits nested inside array `items`\n * or map values are not collected. The one exception is a nullable wrapper —\n * a `oneOf`/`anyOf` with a single non-null, non-`$ref` branch — that declares\n * none itself: it takes that branch's keywords, since the IR collapses it to\n * `nullable<T>`. Values of the wrong type (a string `maxLength`, say) are\n * ignored rather than carried.\n */\nexport function extractConstraints(schema: SchemaObject): Constraints | undefined {\n // The schema's own keywords conjoined with its `allOf` members' (recursively;\n // a keyword declared at more than one level is combined by\n // combineConstraints, so the stricter bound wins). schemaToTypeRef unwraps a\n // single-member `allOf`, so `{ allOf: [{ type: 'string', maxLength: 3 }] }`\n // is a string whose limit is the value's own; a `$ref` member contributes\n // the keywords written beside the reference, but the target itself is not\n // followed — its limits stay on the referenced model.\n let out = ownConstraints(schema);\n for (const member of schema.allOf ?? []) out = combineConstraints(out, extractConstraints(member));\n // A nullable wrapper — `oneOf`/`anyOf` with exactly one non-null branch —\n // collapses to `nullable<T>` in the IR, so that branch's keywords are the\n // value's own too and conjoin with the rest. A `$ref` branch keeps its\n // limits on the referenced model, and a genuine multi-variant union carries\n // none.\n const branch = singleNonNullBranch(schema);\n return branch ? combineConstraints(out, extractConstraints(branch)) : out;\n}\n\n/** The keywords declared strictly on `schema`, normalized — without the nullable-branch fallback. */\nfunction ownConstraints(schema: SchemaObject): Constraints | undefined {\n const out: Constraints = {};\n\n const lower = normalizeBound(schema.minimum, schema.exclusiveMinimum);\n if (lower.inclusive !== undefined) out.minimum = lower.inclusive;\n if (lower.exclusive !== undefined) out.exclusiveMinimum = lower.exclusive;\n const upper = normalizeBound(schema.maximum, schema.exclusiveMaximum);\n if (upper.inclusive !== undefined) out.maximum = upper.inclusive;\n if (upper.exclusive !== undefined) out.exclusiveMaximum = upper.exclusive;\n\n for (const key of NUMERIC_CONSTRAINT_KEYS) {\n const value = schema[key];\n if (typeof value === 'number') out[key] = value;\n }\n if (typeof schema.pattern === 'string') out.pattern = schema.pattern;\n if (schema.uniqueItems === true) out.uniqueItems = true;\n\n const dependentRequired = readDependentRequired(schema.dependentRequired);\n if (dependentRequired) out.dependentRequired = dependentRequired;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** The one non-null, non-`$ref` branch of a `oneOf`/`anyOf`, or `undefined` for anything else. */\nfunction singleNonNullBranch(schema: SchemaObject): SchemaObject | undefined {\n const variants = schema.oneOf ?? schema.anyOf;\n if (!variants) return undefined;\n const nonNull = variants.filter((v) => !isNullSchema(v));\n return nonNull.length === 1 && !nonNull[0].$ref ? nonNull[0] : undefined;\n}\n\n/** True for the `{ type: 'null' }` / `{ type: ['null'] }` branch of a nullable wrapper. */\nfunction isNullSchema(schema: SchemaObject): boolean {\n return (\n schema.type === 'null' || (Array.isArray(schema.type) && schema.type.length === 1 && schema.type[0] === 'null')\n );\n}\n\n/**\n * `{ constraints }` when `schema` declares any validation keyword, `{}`\n * otherwise — spread into an IR node so the key stays absent rather than\n * present-but-undefined.\n */\nexport function constraintsEntry(schema: SchemaObject): { constraints?: Constraints } {\n const constraints = extractConstraints(schema);\n return constraints ? { constraints } : {};\n}\n\n/** Keywords where the stricter of two declarations is the larger value. */\nconst MIN_KEYS = ['minimum', 'exclusiveMinimum', 'minLength', 'minItems', 'minContains', 'minProperties'] as const;\n/** Keywords where the stricter of two declarations is the smaller value. */\nconst MAX_KEYS = ['maximum', 'exclusiveMaximum', 'maxLength', 'maxItems', 'maxContains', 'maxProperties'] as const;\n\n/**\n * Conjoin two constraint sets the way `allOf` conjoins schemas: an instance\n * must satisfy both, so every `min*` takes the larger value, every `max*` the\n * smaller, `uniqueItems` holds if either side demands it, and\n * `dependentRequired` merges per property with the union of its names\n * (deduplicated, `a`'s order first). A keyword declared on one side only is\n * kept as is, and an absent side yields the other unchanged.\n *\n * `multipleOf` and `pattern` keep `a`'s value when the two differ: a true\n * conjunction would need the least common multiple, or a lookahead regex\n * joining both patterns, and neither is worth carrying into the IR.\n *\n * Not for the parameter `$ref` fallback in extractParams: keywords written\n * beside a `$ref` override the target's there, which is a different operation.\n */\nexport function combineConstraints(a: Constraints | undefined, b: Constraints | undefined): Constraints | undefined {\n if (!a) return b;\n if (!b) return a;\n const out: Constraints = { ...a, ...b };\n for (const key of MIN_KEYS) {\n const [x, y] = [a[key], b[key]];\n if (x !== undefined && y !== undefined) out[key] = Math.max(x, y);\n }\n for (const key of MAX_KEYS) {\n const [x, y] = [a[key], b[key]];\n if (x !== undefined && y !== undefined) out[key] = Math.min(x, y);\n }\n if (a.uniqueItems || b.uniqueItems) out.uniqueItems = true;\n if (a.multipleOf !== undefined && b.multipleOf !== undefined) out.multipleOf = a.multipleOf;\n if (a.pattern !== undefined && b.pattern !== undefined) out.pattern = a.pattern;\n if (a.dependentRequired && b.dependentRequired) {\n out.dependentRequired = unionDependentRequired(a.dependentRequired, b.dependentRequired);\n }\n return out;\n}\n\n/** Per-property union of two `dependentRequired` maps, deduplicated and keeping `a`'s order first. */\nfunction unionDependentRequired(a: Record<string, string[]>, b: Record<string, string[]>): Record<string, string[]> {\n const merged = new Map<string, string[]>();\n for (const [property, names] of Object.entries(a)) merged.set(property, [...names]);\n for (const [property, names] of Object.entries(b)) {\n const existing = merged.get(property);\n if (!existing) {\n merged.set(property, [...names]);\n continue;\n }\n for (const name of names) if (!existing.includes(name)) existing.push(name);\n }\n return Object.fromEntries(merged);\n}\n\n/**\n * Resolve one side's bound from `minimum` / `maximum` plus its `exclusive*`\n * companion into the OAS 3.1 shape: a numeric companion is the exclusive\n * bound itself, `true` turns the inclusive bound into the exclusive one, and\n * `false` or absent leaves the inclusive bound as is.\n */\nfunction normalizeBound(inclusive: unknown, exclusive: unknown): { inclusive?: number; exclusive?: number } {\n const bound = typeof inclusive === 'number' ? inclusive : undefined;\n if (typeof exclusive === 'number') return { inclusive: bound, exclusive };\n if (exclusive === true) return { exclusive: bound };\n return { inclusive: bound };\n}\n\n/** Copy `dependentRequired` when it is an object whose values are string arrays; anything else is ignored. */\nfunction readDependentRequired(value: unknown): Record<string, string[]> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const entries: [string, string[]][] = [];\n for (const [property, deps] of Object.entries(value as Record<string, unknown>)) {\n if (Array.isArray(deps) && deps.every((d): d is string => typeof d === 'string'))\n entries.push([property, [...deps]]);\n }\n // Object.fromEntries creates an own property for every key. Assigning\n // `out[property]` on a literal would instead set the prototype for a\n // dependency named `__proto__` and silently drop it.\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\n/**\n * Narrow a raw `examples` value to a non-empty list, or undefined. Guards\n * against documents that put an OAS Example Object map (or anything else)\n * where JSON Schema expects an array, and against an empty list, so the IR\n * carries `examples` only when there is at least one value.\n */\nexport function nonEmptyExamples(value: unknown): unknown[] | undefined {\n return Array.isArray(value) && value.length > 0 ? value : undefined;\n}\n\n/**\n * Pick the single `example` the IR carries: the document's own `example`\n * when it is set (including an explicit `null`), otherwise the first entry\n * of the resolved `examples` list.\n */\nexport function pickExample(example: unknown, examples: unknown[] | undefined): unknown {\n return example !== undefined ? example : examples?.[0];\n}\n\n/** One source of example values, e.g. a parameter's own declaration or its schema. */\nexport interface ExampleSource {\n example: unknown;\n examples: unknown[] | undefined;\n}\n\n/**\n * Resolve `example` and `examples` across ordered precedence levels: for a\n * parameter its own declaration, its inline schema, then the component its\n * `$ref` points at; for a field its own schema, then its `$ref` target.\n *\n * Each value walks the levels independently. `examples` is the first\n * non-empty list. `example` comes from the first level that has either an\n * `example` or a list, preferring that level's own `example` over its first\n * list entry — so a schema-level `example` can never mask the parameter's\n * own `examples` map. A level with neither falls through; an explicit\n * `null` is a value and stops the walk.\n */\nexport function resolveExamples(levels: ExampleSource[]): ExampleSource {\n let example: unknown;\n let examples: unknown[] | undefined;\n for (const level of levels) {\n if (examples === undefined) examples = level.examples;\n if (example === undefined) example = pickExample(level.example, level.examples);\n }\n return { example, examples };\n}\n\n/**\n * If a schema is a `$ref` to `#/components/schemas/X`, return the referenced\n * component schema. Used to surface schema-level metadata (default, example,\n * examples, deprecated, description) that would otherwise be invisible at the\n * field or parameter level.\n *\n * Refs are not pre-resolved by the bundler (`dereference: false` in refs.ts),\n * so without this, a param like `schema: { $ref: '.../PaginationOrder' }`\n * silently loses the target's `default: desc` and the SDK stops emitting the\n * spec-mandated default value in generated method signatures.\n */\nexport function resolveComponentSchemaRef(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n): SchemaObject | undefined {\n if (!schema || !componentSchemas) return undefined;\n const ref = (schema as { $ref?: string }).$ref;\n if (!ref) return undefined;\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n if (!match) return undefined;\n return componentSchemas[match[1]];\n}\n\nexport interface ExtractedSchemas {\n models: Model[];\n enums: Enum[];\n}\n\nexport function extractSchemas(\n schemas: Record<string, SchemaObject> | undefined,\n options?: SchemaExtractionOptions,\n): ExtractedSchemas {\n const enums: Enum[] = [];\n\n if (!schemas) return { models: [], enums };\n\n // Record the raw component keys first so every resolveSchemaName() call\n // below (including the collision probe) can tell a real component key from\n // a name oagen synthesised.\n activeComponentSchemaKeys = new Set(Object.keys(schemas));\n\n // Build collision-safe transform if provided. The transform is probed with\n // the same (cleaned, raw) pair resolveSchemaName() will hand it, so a\n // transform that keys off the original spelling is collision-checked on the\n // names it will actually produce. Collisions are tracked by raw key: two raw\n // keys may clean to the same name yet transform to different ones (e.g.\n // `Users`/`User` with an originalName-based transform), and marking the\n // shared cleaned name unsafe would wrongly disable the transform for both.\n if (options?.schemaNameTransform) {\n const transform = options.schemaNameTransform;\n const transformedToRawKeys = new Map<string, string[]>();\n for (const raw of Object.keys(schemas)) {\n const transformed = transform(cleanSchemaName(toPascalCase(raw)), raw);\n if (!transformedToRawKeys.has(transformed)) transformedToRawKeys.set(transformed, []);\n transformedToRawKeys.get(transformed)!.push(raw);\n }\n // Raw keys whose transformed output is shared with another raw key, plus\n // their cleaned names. Component keys are guarded by raw key; synthesised\n // names (no originalName) keep the cleaned-name guard they always had.\n const unsafeRawKeys = new Set<string>();\n const unsafeCleanedNames = new Set<string>();\n for (const [, rawKeys] of transformedToRawKeys) {\n if (rawKeys.length > 1) {\n for (const raw of rawKeys) {\n unsafeRawKeys.add(raw);\n unsafeCleanedNames.add(cleanSchemaName(toPascalCase(raw)));\n }\n }\n }\n activeSchemaNameTransform = (name: string, originalName?: string) => {\n const unsafe = originalName !== undefined ? unsafeRawKeys.has(originalName) : unsafeCleanedNames.has(name);\n return unsafe ? name : transform(name, originalName);\n };\n } else {\n activeSchemaNameTransform = null;\n }\n\n // Pre-compute the set of resolved names whose component schema is an enum so\n // schemaToTypeRef() can classify `$ref` targets correctly. Built in a separate\n // pass because the per-schema loop mutates models/enums and we want this map\n // available before any TypeRef is resolved (operations + nested fields both\n // call schemaToTypeRef during extraction).\n activeEnumSchemaNames = new Set();\n activeNullableEnumSchemaNames = new Set();\n for (const [name, schema] of Object.entries(schemas)) {\n if (!schema.enum) continue;\n const resolved = resolveSchemaName(name);\n activeEnumSchemaNames.add(resolved);\n if (isNullableEnumSchema(schema)) activeNullableEnumSchemaNames.add(resolved);\n }\n\n const modelsByCleanName = new Map<string, Model>();\n\n for (const [name, schema] of Object.entries(schemas)) {\n const pascalName = resolveSchemaName(name);\n\n if (schema.enum) {\n enums.push(extractEnum(pascalName, schema));\n } else {\n const model = extractModel(pascalName, schema, schemas);\n const existing = modelsByCleanName.get(pascalName);\n if (existing) {\n // Keep the model with more fields when names collide after cleaning\n if (model.fields.length > existing.fields.length) {\n modelsByCleanName.set(pascalName, model);\n }\n } else {\n modelsByCleanName.set(pascalName, model);\n }\n\n for (const inlineModel of extractDiscriminatedAllOfVariantModels(schema, pascalName, schemas)) {\n const existingInline = modelsByCleanName.get(inlineModel.name);\n if (existingInline) {\n if (inlineModel.fields.length > existingInline.fields.length) {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n } else {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n }\n }\n }\n\n const models = [...modelsByCleanName.values()];\n\n // Collect inline models from nested object/oneOf properties\n // that schemaToTypeRef created model refs for but weren't extracted\n const modelNames = new Set(models.map((m) => m.name));\n const inlineQueue: Model[] = [...models];\n while (inlineQueue.length > 0) {\n const model = inlineQueue.pop()!;\n for (const field of model.fields) {\n collectNestedInlineModels(field.type, field.name, model.name, schemas ?? {}, models, modelNames, inlineQueue);\n }\n }\n\n // Collect inline enums from model fields\n for (const model of models) {\n collectInlineEnums(model.fields, enums);\n }\n\n // NOTE: activeSchemaNameTransform is intentionally NOT cleared here.\n // extractOperations() calls schemaToTypeRef() for $ref resolution and\n // needs the same transform active. parseSpec() calls clearSchemaNameTransform()\n // after all extraction is complete.\n return { models, enums };\n}\n\n/** Clear the module-level schemaNameTransform. Called by parseSpec() after all extraction phases. */\nexport function clearSchemaNameTransform(): void {\n activeSchemaNameTransform = null;\n activeEnumSchemaNames = new Set();\n activeNullableEnumSchemaNames = new Set();\n activeComponentSchemaKeys = new Set();\n}\n\n/**\n * Walk a single TypeRef and extract inline enum refs as top-level enum definitions.\n * Shared by both schemas.ts (field-level) and parse.ts (model-level) collection passes.\n */\nexport function collectInlineEnumFromRef(ref: TypeRef, enums: Enum[], seen: Set<string>): void {\n walkTypeRef(ref, {\n enum: (r) => {\n if (r.values && !seen.has(r.name)) {\n seen.add(r.name);\n enums.push({\n name: r.name,\n values: r.values.map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: v,\n description: undefined,\n })),\n });\n }\n },\n });\n}\n\n/**\n * Walk model fields and extract inline enum refs as top-level enum definitions.\n * This ensures type alias files are generated for inline enums.\n */\nfunction collectInlineEnums(fields: Field[], enums: Enum[]): void {\n const seen = new Set(enums.map((e) => e.name));\n for (const field of fields) {\n collectInlineEnumFromRef(field.type, enums, seen);\n }\n}\n\n/**\n * Walk a TypeRef tree and extract inline models for any model refs that point\n * to schemas with inline object properties (not in components/schemas).\n * This handles nested objects like `totp: { oneOf: [{ type: object, properties: {...} }] }`\n * that schemaToTypeRef turns into model refs but aren't extracted from components.\n */\nfunction collectNestedInlineModels(\n ref: TypeRef,\n fieldName: string,\n parentModelName: string,\n schemas: Record<string, SchemaObject>,\n models: Model[],\n modelNames: Set<string>,\n queue: Model[],\n): void {\n // `extractNestedSchema` names what it extracts from the ref it is handed, so\n // it is only right for refs the field schema produces directly — its own\n // object, its array items, or its union variants. A ref deeper in the tree\n // (the items of a variant's array member, a nested union) is named from its\n // enclosing variant; handing it over here would re-derive the variants'\n // names from it and register them under the wrong names. Those models come\n // from the field extractor, which names them by construction.\n const directRefs = directModelRefNames(ref);\n walkTypeRef(ref, {\n model: (modelRef) => {\n if (modelNames.has(modelRef.name)) return; // already extracted\n if (!directRefs.has(modelRef.name)) return; // nested under a variant — field extractor's\n // Check if this model name corresponds to a component schema\n // by checking all possible original names that would map to this PascalCase name\n const isComponent = Object.keys(schemas).some((k) => resolveSchemaName(k) === modelRef.name);\n if (isComponent) return; // will be extracted from components\n\n // This is a reference to a nested inline model that wasn't extracted.\n // Look up the field schema in the parent model's component schema to extract it.\n const parentSchema = findSchemaByName(parentModelName, schemas);\n if (!parentSchema) return;\n\n const fieldSchema = findNestedFieldSchema(fieldName, parentSchema, schemas);\n if (!fieldSchema) return;\n\n // Extract inline models from the field schema. A union's variants are\n // named from the field's own qualified name — `extractModel` and\n // `extractAllOfModel` type every field of a component, inherited ones\n // included, under the component — which is also variant 0's name\n // unless variant 0 took its title (`CircleDrawingShape`). Rebuild the\n // base from the field rather than reading it off the ref, and keep the\n // ref as the base only if the rebuilt one does not reproduce it. The\n // variants also step around the names the component's other properties\n // mint, as the field's TypeRef did, so derive that set from the same\n // sibling set `extractModel` typed the field with.\n const reserved = reservedInlineNames(fieldName, collectProperties(parentSchema, schemas), parentModelName);\n const extracted = extractNestedSchema(\n unionBaseName(modelRef.name, fieldName, fieldSchema, parentModelName, reserved),\n fieldSchema,\n schemas,\n reserved,\n );\n for (const m of extracted) {\n if (!modelNames.has(m.name)) {\n models.push(m);\n modelNames.add(m.name);\n queue.push(m); // re-scan for deeper nesting\n }\n }\n },\n });\n}\n\n/**\n * The base name `extractNestedSchema` should name a field's `oneOf` variants\n * from: the field's qualified inline name when naming the variants from it\n * yields `refName` (the ref the walk is resolving), else `refName` itself,\n * which is right for every non-union field and for a union whose variant 0 is\n * bare.\n */\nfunction unionBaseName(\n refName: string,\n fieldName: string,\n fieldSchema: SchemaObject,\n parentModelName: string,\n reserved: ReadonlySet<string>,\n): string {\n if (!fieldSchema.oneOf) return refName;\n const fromField = qualifyInlineModelName(toPascalCase(fieldName), parentModelName);\n const names = [...nameInlineVariants(fieldSchema, fromField, reserved).values()];\n return names.includes(refName) ? fromField : refName;\n}\n\n/**\n * The model refs a field's TypeRef produces directly: the ref itself, the\n * items of a (possibly nullable) array, or each (possibly nullable) variant of\n * a union — the shapes `extractNestedSchema` can name from a ref. Refs nested\n * any deeper are excluded.\n */\nfunction directModelRefNames(ref: TypeRef): Set<string> {\n const names = new Set<string>();\n let root = ref;\n while (root.kind === 'nullable' || root.kind === 'array') {\n root = root.kind === 'nullable' ? root.inner : root.items;\n }\n const leaves = root.kind === 'union' ? root.variants : [root];\n for (const leaf of leaves) {\n const inner = leaf.kind === 'nullable' ? leaf.inner : leaf;\n if (inner.kind === 'model') names.add(inner.name);\n }\n return names;\n}\n\n/** Find a component schema by PascalCase name. */\nfunction findSchemaByName(pascalName: string, schemas: Record<string, SchemaObject>): SchemaObject | null {\n for (const [k, v] of Object.entries(schemas)) {\n if (resolveSchemaName(k) === pascalName) return v;\n }\n return null;\n}\n\n/** Walk into a schema to find a field's sub-schema, resolving allOf and oneOf/anyOf. */\nfunction findNestedFieldSchema(\n fieldName: string,\n parentSchema: SchemaObject,\n schemas: Record<string, SchemaObject>,\n): SchemaObject | null {\n if (parentSchema.properties?.[fieldName]) {\n return parentSchema.properties[fieldName]!;\n }\n if (parentSchema.allOf) {\n for (const sub of parentSchema.allOf) {\n let resolved = sub;\n if (sub.$ref) {\n const segments = sub.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n }\n // Also check inside oneOf/anyOf variants (pure oneOf schemas flatten variant\n // properties into the model, so the field may live inside a variant).\n for (const variant of [...(parentSchema.oneOf ?? []), ...(parentSchema.anyOf ?? [])]) {\n let resolved = variant;\n if (variant.$ref) {\n const segments = variant.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n return null;\n}\n\n/**\n * Extract a model (and nested models) from an inline field schema. `reserved`\n * holds the inline names the field's sibling properties mint\n * (`reservedInlineNames`), which a `oneOf` variant must not take.\n */\nfunction extractNestedSchema(\n name: string,\n schema: SchemaObject,\n schemas?: Record<string, SchemaObject>,\n reserved: ReadonlySet<string> = NO_RESERVED,\n): Model[] {\n // Handle oneOf: extract each object variant as its own model. `name` is the\n // union's base name (the field's qualified inline name), and the variants\n // are named from it by `nameInlineVariants` — the one place that decides a\n // variant's name — so they match the union TypeRef and the field extractor\n // (`UserApiKeyOwner`, `CircleDrawingShape`, `DrawingShapeWithSide`, ...).\n // Same inline-object test as `schemaToTypeRef` and the field extractor, so\n // a `type: ['object', 'null']` variant is counted here too instead of\n // letting the next variant claim its name.\n if (schema.oneOf) {\n const models: Model[] = [];\n const variantNames = nameInlineVariants(schema, name, reserved);\n\n for (const variant of schema.oneOf) {\n const variantName = variantNames.get(variant);\n if (variantName === undefined) continue;\n // Build the variant's fields under its own name: an inline object\n // nested under variant N is then referenced as `<VariantN>Child`\n // (`ThingShapeWithSideCenter`), which is the name the field extractor\n // materializes it under — not `<Variant0>Child`.\n const requiredSet = new Set(variant.required ?? []);\n const siblings = collectProperties(variant);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(variant.properties ?? {})) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, variantName, requiredSet, schemas, siblings));\n }\n models.push({ name: variantName, description: variant.description, fields, ...constraintsEntry(variant) });\n }\n return models;\n }\n\n // Handle direct object\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const siblings = collectProperties(schema);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet, schemas, siblings));\n }\n return [{ name, description: schema.description, fields, ...constraintsEntry(schema) }];\n }\n\n // Handle array with inline items\n if (schema.type === 'array' && schema.items?.properties) {\n const requiredSet = new Set(schema.items.required ?? []);\n const siblings = collectProperties(schema.items);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.items.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet, schemas, siblings));\n }\n return [{ name, description: schema.items.description, fields, ...constraintsEntry(schema.items) }];\n }\n\n return [];\n}\n\n/**\n * The prefix a variant's `title` contributes to its name: the title trimmed\n * and PascalCased, or null when there is no title or it PascalCases to\n * nothing.\n */\nfunction variantTitlePrefix(variant: SchemaObject): string | null {\n const title = typeof variant['title'] === 'string' ? variant['title'].trim() : '';\n return title ? toPascalCase(title) || null : null;\n}\n\n/** `<Prefix><Base>`, or `base` unchanged when it already starts with the prefix (no doubling). */\nfunction prefixedVariantName(prefix: string, base: string): string {\n return base.startsWith(prefix) ? base : `${prefix}${base}`;\n}\n\n/**\n * The properties `variant` declares that no other inline object variant of\n * the same union declares, in the variant's own `properties` order.\n */\nfunction distinguishingProperties(variant: SchemaObject, siblings: readonly SchemaObject[]): string[] {\n const declaredElsewhere = new Set<string>();\n for (const sibling of siblings) {\n if (sibling === variant) continue;\n for (const property of Object.keys(sibling.properties ?? {})) declaredElsewhere.add(property);\n }\n return Object.keys(variant.properties ?? {}).filter((property) => !declaredElsewhere.has(property));\n}\n\n/**\n * Name an inline object variant of a `oneOf`/`anyOf` that has no better\n * signal: it is not variant 0 (which keeps the union's base name) and no\n * const discriminator gave it a prefix. The name is derived from the\n * variant's own content, never from where it sits in the document (beyond\n * its position among the variants, which only the final counter reads), so\n * an SDK user can tell the variants apart and reordering them changes nothing\n * but which one is variant 0. In order, taking the first candidate that is\n * neither the base name nor a name already given to an earlier variant of\n * the same union:\n *\n * 1. the variant's `title` (trimmed and PascalCased): `<Title><Base>`\n * (`CircleDrawingShape`), the same prefix form a const discriminator\n * produces, including the rule that a base already starting with the\n * prefix is not doubled (that candidate equals the base, so it falls\n * through); a title an earlier variant already took falls through too;\n * 2. a distinguishing property — the first property, in the variant's own\n * order, that it declares and no other inline object variant declares:\n * `<Base>With<Property>` (`DrawingShapeWithSide`); a property that\n * PascalCases to nothing is skipped;\n * 3. the position counter, `<Base><position + 1>` (`DrawingShape2`), which\n * now remains only for variants whose property sets are identical, and\n * which keeps counting past a taken name (`DrawingShape3`).\n *\n * Every candidate is also checked against `reserved`: the inline names the\n * parent's other properties mint (`reservedInlineNames`), so a variant can\n * never take a name another field's model already has — beside a\n * `shape_with_side` object, the `{ side }` variant of `shape` is not\n * `DrawingShapeWithSide` but the next candidate. Read from sibling names and\n * content only, so document order plays no part.\n *\n * `siblings` are the inline object variants of the union, this one included;\n * `emitted` are the names already given to the earlier ones, in order. Every\n * site that names a variant — the union TypeRef, the component-field,\n * request-body and response extractors, and `mintedInlineNames` — goes\n * through this function (via `nameInlineVariant`), so they cannot drift.\n */\nexport function nameUndiscriminatedVariant(\n variant: SchemaObject,\n siblings: readonly SchemaObject[],\n base: string,\n emitted: readonly string[],\n reserved: ReadonlySet<string> = NO_RESERVED,\n): string {\n const taken = (candidate: string): boolean =>\n candidate === base || emitted.includes(candidate) || reserved.has(candidate);\n\n const titlePrefix = variantTitlePrefix(variant);\n if (titlePrefix !== null) {\n const candidate = prefixedVariantName(titlePrefix, base);\n if (!taken(candidate)) return candidate;\n }\n\n for (const property of distinguishingProperties(variant, siblings)) {\n const word = toPascalCase(property);\n if (!word) continue;\n const candidate = `${base}With${word}`;\n if (!taken(candidate)) return candidate;\n }\n\n for (let position = emitted.length + 1; ; position++) {\n const candidate = `${base}${position}`;\n if (!taken(candidate)) return candidate;\n }\n}\n\n/** No reserved names: for a union with no sibling properties (a request body or response that is itself a union). */\nconst NO_RESERVED: ReadonlySet<string> = new Set();\n\n/**\n * True when the union's inline object variants (two or more) each carry a\n * title and no two titles PascalCase to the same prefix: the one case in\n * which variant 0 is named from its title rather than keeping the base name.\n */\nfunction allDistinctlyTitled(siblings: readonly SchemaObject[]): boolean {\n if (siblings.length < 2) return false;\n const prefixes = siblings.map(variantTitlePrefix);\n return prefixes.every((prefix) => prefix !== null) && new Set(prefixes).size === prefixes.length;\n}\n\n/**\n * The name of one inline object variant of a `oneOf`/`anyOf`, given the\n * union's base name (the field's qualified inline name, e.g. `ApiKeyOwner`),\n * the inline object variants of the union (`siblings`, this one included),\n * the names already given to the earlier variants (`emitted`, in order), and\n * the const-valued property that distinguishes the variants when there is\n * one (`deriveConstNamingDiscriminator`).\n *\n * Variant 0 keeps the bare base name: the union TypeRef and every extractor\n * reference it under that name, and a consumer's typed field keeps the name\n * it always had. The one exception: when the union has no const discriminator\n * and every variant carries a distinct title, variant 0 is named from its\n * title like the others (`CircleDrawingShape` beside `SquareDrawingShape`)\n * instead of being the only one left bare. Whether the union is discriminated\n * is read from the variants themselves here, not from `discriminator`, so a\n * caller forcing a property (an explicit `discriminator:` without `mapping:`)\n * still agrees with the extractors on variant 0.\n *\n * A later variant takes `<ConstValue><Base>` from the discriminator\n * (`UserApiKeyOwner`) when the value PascalCases to something and the name is\n * neither the base, nor already emitted, nor minted by one of the parent's\n * other properties (`reserved`), and otherwise falls to\n * `nameUndiscriminatedVariant`: its title, a distinguishing property, then\n * the position counter, each checked the same way.\n */\nexport function nameInlineVariant(\n variant: SchemaObject,\n siblings: readonly SchemaObject[],\n base: string,\n emitted: readonly string[],\n discriminator: { property: string } | null,\n reserved: ReadonlySet<string> = NO_RESERVED,\n): string {\n if (emitted.length === 0) {\n const undiscriminated = deriveConstNamingDiscriminator([...siblings]) === null;\n const titlePrefix = undiscriminated && allDistinctlyTitled(siblings) ? variantTitlePrefix(variant) : null;\n return titlePrefix === null ? base : prefixedVariantName(titlePrefix, base);\n }\n\n if (discriminator) {\n const constValue = getConstPropertyValue(variant, discriminator.property);\n const prefix = constValue ? toPascalCase(constValue) : '';\n if (prefix) {\n const candidate = prefixedVariantName(prefix, base);\n if (candidate !== base && !emitted.includes(candidate) && !reserved.has(candidate)) return candidate;\n }\n }\n return nameUndiscriminatedVariant(variant, siblings, base, emitted, reserved);\n}\n\n/**\n * Name every inline object variant of a `oneOf`/`anyOf` schema from the\n * union's base name, keyed by variant schema identity; null, non-object and\n * `$ref` variants get no entry. Positions are local to this variant list, so\n * the union's TypeRef entries and the extracted models agree no matter what\n * else has been extracted. `reserved` holds the inline names the parent's\n * other properties mint (`reservedInlineNames`); every site that has a\n * sibling set passes the same one, so the reference and the model step\n * around them identically.\n *\n * One union shape is named differently: a `oneOf` with no explicit\n * `discriminator:` whose every variant carries a `$ref` or a `title` and pins\n * the same const property (`titleMappedDiscriminatorProperty`). Its\n * discriminator mapping has always named an inline variant by its title\n * (`resolveSchemaName(title)`: `Circle`, `Square`, run through the project's\n * schema-name transform like a component), and `schemaToTypeRef` references\n * the variant by that mapped name, so the title is the model name here too —\n * unless it is the base, already emitted, or reserved by a sibling, in which\n * case the variant takes a context-qualified name (its title as a prefix on\n * the base, `CircleDrawingMarker`, else a distinguishing property, else the\n * counter) and the mapping, which is read from this map, follows it. A kept\n * title is context-free: it is the same whatever field, array or map the\n * union sits under, so it names one shape wherever it appears, as a\n * component name would. A second union beside it using the same title for a\n * variant of the identical shape (`schemaShapeKey`) therefore shares the\n * model instead of stepping around it; a sibling giving the same title a\n * different shape reserves it (`reservedInlineNames`), and since both sides\n * read their siblings in isolation the decision is symmetric: when the\n * shapes differ, both unions fall back to their context-qualified names\n * (`CircleDrawingShape`, `CircleDrawingMarker`) and neither keeps the bare\n * `Circle`; when they are identical, both keep `Circle` and one model is\n * emitted. `elementContextName` never lets a context-free name drive an\n * items/values step-aside, which no context could satisfy.\n * `nameInlineVariantEntries` reports which names are context-free; a\n * fallen-back title name is context-dependent.\n *\n * This is the list-level entry point every site uses: `schemaToTypeRef` (via\n * `nameInlineObjectVariants`), `extractNestedSchema`,\n * `extractInlineModelDeep`, `extractInlineModelsFromProperties` and\n * `mintedInlineNames`.\n */\nexport function nameInlineVariants(\n union: SchemaObject,\n base: string,\n reserved: ReadonlySet<string> = NO_RESERVED,\n): Map<SchemaObject, string> {\n const names = new Map<SchemaObject, string>();\n for (const [variant, entry] of nameInlineVariantEntries(union, base, reserved)) names.set(variant, entry.name);\n return names;\n}\n\n/** A variant's model name, and whether it is context-free (a title-mapped union's title, see `nameInlineVariants`). */\nexport interface InlineVariantName {\n name: string;\n contextFree: boolean;\n}\n\n/** `nameInlineVariants`, also telling for each name whether it is context-free. */\nexport function nameInlineVariantEntries(\n union: SchemaObject,\n base: string,\n reserved: ReadonlySet<string> = NO_RESERVED,\n): Map<SchemaObject, InlineVariantName> {\n const nonNullVariants = (union.oneOf ?? union.anyOf ?? []).filter((v) => !isNullVariantSchema(v));\n const inlineObjectVariants = nonNullVariants.filter((v) => isInlineObjectSchema(v));\n const discriminator = deriveConstNamingDiscriminator(inlineObjectVariants);\n const titleMapped =\n union.oneOf !== undefined && !union.discriminator && titleMappedDiscriminatorProperty(nonNullVariants) !== null;\n const emitted: string[] = [];\n const entries = new Map<SchemaObject, InlineVariantName>();\n for (const variant of inlineObjectVariants) {\n let name: string | null = null;\n let contextFree = false;\n if (titleMapped) {\n const titled = resolveVariantModelName(variant);\n if (titled !== null) {\n if (titled !== base && !emitted.includes(titled) && !reserved.has(titled)) {\n name = titled;\n contextFree = true;\n } else {\n // The title is taken (by a sibling's model, by a sibling's variant\n // of a different shape, or by an earlier variant of this union):\n // the variant takes a context-qualified name instead — its title\n // as a prefix on the base (`CircleDrawingMarker`), else a\n // distinguishing property, else the counter — and the mapping,\n // read from this map, follows.\n name = nameUndiscriminatedVariant(variant, inlineObjectVariants, base, emitted, reserved);\n }\n }\n }\n name ??= nameInlineVariant(variant, inlineObjectVariants, base, emitted, discriminator, reserved);\n emitted.push(name);\n entries.set(variant, { name, contextFree });\n }\n return entries;\n}\n\n/**\n * Returns a discriminator descriptor when every inline object variant in a\n * oneOf has a string-const value on the same property — the signature of a\n * discriminated union without an explicit `discriminator:` keyword. Used by\n * `nameInlineVariant` to derive variant names from the const values.\n *\n * Distinct from `detectConstPropertyDiscriminator` (which requires every\n * variant to carry a `$ref` or `title` so a name mapping can be built):\n * this pass operates on inline anonymous variants, where naming is exactly\n * what we're trying to derive.\n */\nfunction deriveConstNamingDiscriminator(variants: SchemaObject[]): { property: string } | null {\n if (variants.length < 2) return null;\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n const values = variants.map((v) => getConstPropertyValue(v, propName));\n if (values.some((v) => v === null)) continue;\n if (new Set(values).size !== values.length) continue; // collisions = no signal\n return { property: propName };\n }\n return null;\n}\n\n/**\n * True for a schema that `schemaToTypeRef` turns into an inline model reference:\n * it declares `properties` directly (no `$ref`) and is an object — whether by\n * `type: 'object'`, by omitting `type`, or by an OAS 3.1 nullable array such as\n * `type: ['object', 'null']`. Every inline-model extractor must use the same\n * test, or a field's reference points at a model nobody materializes.\n */\nexport function isInlineObjectSchema(schema: SchemaObject | undefined): schema is SchemaObject {\n if (!schema || schema.$ref || !schema.properties) return false;\n const { type } = schema;\n return type === undefined || type === 'object' || (Array.isArray(type) && type.includes('object'));\n}\n\n/** The `{ type: 'null' }` member that marks a `oneOf`/`anyOf` as nullable; never a variant to name. */\nfunction isNullVariantSchema(schema: SchemaObject): boolean {\n return (\n schema.type === 'null' || (Array.isArray(schema.type) && schema.type.length === 1 && schema.type[0] === 'null')\n );\n}\n\n/**\n * The synthetic context names a multi-type inline variant's non-object\n * members are typed and extracted under, chosen so the models they name can\n * never collide with a model named from one of the variant's own properties.\n * An `array` member's items go under `item` (`<Variant>Item`), falling back\n * to `array_item` (`<Variant>ArrayItem`) and then `array_item2`,\n * `array_item3`, ... when a property already claims that name; any other\n * member goes under `value` (`<Variant>Value`), then `member_value`,\n * `member_value2`, .... A candidate is skipped when the model name\n * `qualifyInlineModelName` derives from it equals one derived from a\n * property — compared after qualification, so a property `items`, whose\n * name singularizes to `<Variant>Item`, blocks `item` as well.\n * This is the single source of these names for the TypeRef builder\n * (`inlineVariantTypeRef`) and the extractors (`variantMemberSchemas`).\n */\nexport function variantMemberKeys(variant: SchemaObject, variantName: string): { item: string; value: string } {\n const modelNameFor = (key: string): string => qualifyInlineModelName(toPascalCase(key), variantName);\n const claimed = new Set(Object.keys(variant.properties ?? {}).map(modelNameFor));\n const pick = (preferred: string, fallback: string): string => {\n for (let i = 0; ; i++) {\n const candidate = i === 0 ? preferred : i === 1 ? fallback : `${fallback}${i}`;\n if (!claimed.has(modelNameFor(candidate))) return candidate;\n }\n };\n return { item: pick('item', 'array_item'), value: pick('value', 'member_value') };\n}\n\n/**\n * The schemas carried by the non-object members of a multi-type inline\n * variant (`type: ['object', 'array']` with `items`), keyed by the synthetic\n * context name from `variantMemberKeys` that `schemaToTypeRef` types them\n * under, so an inline object item is `<Variant>Item` (or `<Variant>ArrayItem`\n * when `item` is taken) and its own nested objects `<Variant>ItemChild`.\n * Every extractor re-enters with these under the variant's name so the\n * models line up with the refs by construction. A map member cannot occur\n * here: a variant with `properties` is typed as a model, never as a map.\n */\nexport function variantMemberSchemas(variant: SchemaObject, variantName: string): Record<string, SchemaObject> {\n const members: Record<string, SchemaObject> = {};\n if (Array.isArray(variant.type) && variant.type.includes('array') && variant.items) {\n members[variantMemberKeys(variant, variantName).item] = variant.items;\n }\n return members;\n}\n\n/**\n * Build a single Field from a schema property entry. Shared across all\n * extraction sites. Pass `componentSchemas` where they are at hand so a\n * field whose schema is a bare `$ref` can take `example`/`examples` from the\n * component it points at, as a parameter does. `siblingProperties` are the\n * other properties of the object the field belongs to (`collectProperties`);\n * array items and map values use them to step aside from a sibling that\n * would take their singular name (`elementContextName`).\n */\nexport function buildFieldFromSchema(\n fieldName: string,\n fieldSchema: SchemaObject,\n contextName: string,\n requiredSet: Set<string>,\n componentSchemas?: Record<string, SchemaObject>,\n siblingProperties?: ReadonlyMap<string, SchemaObject>,\n): Field {\n const refTarget = resolveComponentSchemaRef(fieldSchema, componentSchemas);\n const { example, examples } = resolveExamples([\n { example: fieldSchema.example, examples: nonEmptyExamples(fieldSchema.examples) },\n { example: refTarget?.example, examples: nonEmptyExamples(refTarget?.examples) },\n ]);\n return {\n name: fieldName,\n type: schemaToTypeRef(fieldSchema, fieldName, contextName, siblingProperties),\n required: requiredSet.has(fieldName),\n description: fieldSchema.description,\n readOnly: fieldSchema.readOnly || undefined,\n writeOnly: fieldSchema.writeOnly || undefined,\n deprecated: fieldSchema.deprecated || undefined,\n default: fieldSchema.default,\n example,\n // Only materialise the key when there is something to carry so existing\n // inline snapshots of fields without examples stay byte-identical.\n ...(examples ? { examples } : {}),\n // Keywords written beside a `$ref` (legal in OAS 3.1) are the field's own;\n // a bare `$ref` declares none, and the referenced model carries its limits.\n ...constraintsEntry(fieldSchema),\n };\n}\n\n/**\n * If every non-null oneOf/anyOf variant is a string-valued const, return the\n * list of those const values so the union can collapse into a single enum.\n * Returns null when any variant isn't a pure string-const (model ref,\n * number const, nullable, etc.).\n */\nfunction collectLiteralStringConsts(variants: SchemaObject[]): string[] | null {\n if (variants.length === 0) return null;\n const values: string[] = [];\n for (const v of variants) {\n // A single-element enum is semantically identical to const.\n if (typeof v.const === 'string') {\n values.push(v.const);\n continue;\n }\n if (Array.isArray(v.enum) && v.enum.length === 1 && typeof v.enum[0] === 'string') {\n values.push(v.enum[0]);\n continue;\n }\n return null;\n }\n return values;\n}\n\n/** Build an EnumRef the same way the regular enum path does for naming. */\nfunction buildSyntheticEnumRef(\n values: string[],\n contextName: string | undefined,\n parentModelName: string | undefined,\n): TypeRef {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n // Run the same `schemaNameTransform` we apply to component-schema names so\n // a project-level rename map (e.g. `RadarAction` → `RadarListAction` in\n // `oagen.config.ts`) catches inline parameter enums too.\n const finalName = activeSchemaNameTransform ? activeSchemaNameTransform(qualifiedName) : qualifiedName;\n return { kind: 'enum', name: finalName, values };\n}\n\n/**\n * Detect an implicit discriminator on a `oneOf` whose every variant pins the\n * same property to a const value AND is nameable on its own — by a `$ref` to\n * a component or by a `title` — so the IR can represent the union as\n * discriminated, with a mapping to concrete names, without an explicit\n * `discriminator:` keyword. Returns the property, or null when any variant\n * doesn't fit the pattern or when the variants disagree on which property\n * carries the discriminator. The mapping itself is built by `schemaToTypeRef`\n * from the names `nameInlineVariants` gives the inline variants (their titles\n * unless taken) and the component names of `$ref` variants, so it can only\n * ever point at a model that exists.\n *\n * Both const shapes are supported:\n * { properties: { event: { const: \"x\" } }, required: [\"event\"] }\n * { properties: { event: { type: \"string\", enum: [\"x\"] } } }\n */\nfunction titleMappedDiscriminatorProperty(variants: SchemaObject[]): string | null {\n if (variants.length < 2) return null;\n // Require a $ref or title on every variant so there is a concrete name to map to.\n if (!variants.every((v) => resolveVariantModelName(v) !== null)) return null;\n\n // The first property whose const value is present on every variant.\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n if (variants.every((v) => getConstPropertyValue(v, propName) !== null)) return propName;\n }\n return null;\n}\n\nfunction getConstPropertyValue(schema: SchemaObject, property: string): string | null {\n const prop = schema.properties?.[property];\n if (!prop) return null;\n if (typeof prop.const === 'string') return prop.const;\n if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n return prop.enum[0];\n }\n return null;\n}\n\nfunction resolveVariantModelName(schema: SchemaObject): string | null {\n if (schema.$ref) {\n return resolveSchemaName(schema.$ref.replace(/^#\\/components\\/schemas\\//, ''));\n }\n const title = typeof schema['title'] === 'string' ? (schema['title'] as string) : null;\n if (title) return resolveSchemaName(title);\n return null;\n}\n\n/** Look up the discriminator's mapped variant name for an inline object\n * variant by reading its const-valued discriminator property. Returns null\n * when the variant doesn't pin the property to a string const, or when\n * the value isn't in the mapping. */\nfunction mapVariantToDiscriminatorEntry(\n variant: SchemaObject,\n discriminator: { property: string; mapping: Record<string, string> },\n): string | null {\n const value = getConstPropertyValue(variant, discriminator.property);\n if (value === null) return null;\n return discriminator.mapping[value] ?? null;\n}\n\n/**\n * Derive a discriminator value → variant model name mapping for an inline-\n * variant `oneOf` from the names `nameInlineVariants` gave its variants\n * (`inlineVariantNames`): the explicit `discriminator:` without a `mapping:`\n * clause, and the implicit const discriminator of anonymous inline variants\n * (`ApiKeyCreatedData.owner`: `ApiKeyCreatedDataOwner`,\n * `UserApiKeyCreatedDataOwner`). Reading the names rather than deriving them\n * again is what keeps the mapping pointing at models the extractors create.\n * Returns null without a context name, when any variant is not an inline\n * object, or when a variant lacks a const value on the property.\n */\nfunction deriveInlineVariantMapping(\n variants: SchemaObject[],\n discriminatorProperty: string,\n contextName: string | undefined,\n inlineVariantNames: ReadonlyMap<SchemaObject, string>,\n): Record<string, string> | null {\n if (variants.length === 0 || !contextName) return null;\n const mapping: Record<string, string> = {};\n for (const variant of variants) {\n const variantName = inlineVariantNames.get(variant);\n if (variantName === undefined) return null;\n const constValue = getConstPropertyValue(variant, discriminatorProperty);\n if (constValue === null) return null;\n mapping[constValue] = variantName;\n }\n return mapping;\n}\n\n/**\n * The names reserved for a union typed under `contextName`: the set an\n * enclosing field handed down (`reservedNames`, for a union among a field's\n * array items or map values), else the inline names the field's own sibling\n * properties mint (`reservedInlineNames`), else nothing. The extractor\n * derives the same set at each of those levels, so the reference and the\n * model step around a sibling's name identically.\n */\nfunction reservedNamesFor(\n contextName: string | undefined,\n siblingProperties: ReadonlyMap<string, SchemaObject> | undefined,\n parentModelName: string | undefined,\n reservedNames: ReadonlySet<string> | undefined,\n): ReadonlySet<string> {\n if (reservedNames) return reservedNames;\n if (contextName === undefined) return NO_RESERVED;\n return reservedInlineNames(contextName, siblingProperties, parentModelName);\n}\n\n/**\n * Name the inline object variants of a field's `oneOf`/`anyOf` exactly as the\n * inline-model extractors do (`extractInlineModelsFromProperties` in\n * inline-models.ts, and `extractNestedSchema` / `extractInlineModelDeep`\n * here): the union's base name is the field's qualified inline name, the\n * names the field's sibling properties mint — or the set handed down from an\n * enclosing field — are reserved (`reservedNamesFor`), and\n * `nameInlineVariants` hands out the variant names from there. Returned keyed\n * by variant schema identity.\n */\nfunction nameInlineObjectVariants(\n union: SchemaObject,\n contextName: string | undefined,\n parentModelName: string | undefined,\n siblingProperties: ReadonlyMap<string, SchemaObject> | undefined,\n reservedNames: ReadonlySet<string> | undefined,\n): Map<SchemaObject, string> {\n const baseInlineName = qualifyInlineModelName(toPascalCase(contextName ?? 'UnknownModel'), parentModelName);\n return nameInlineVariants(\n union,\n baseInlineName,\n reservedNamesFor(contextName, siblingProperties, parentModelName, reservedNames),\n );\n}\n\n/**\n * The TypeRef for an inline object variant referenced by the name its\n * extracted model carries, keeping every other type the variant allows.\n * Mirrors what `schemaToTypeRef` builds for the same schema — one member per\n * non-null entry of a `type` array, `union`-wrapped when there is more than\n * one, `nullable`-wrapped when `null` or OAS 3.0 `nullable: true` is present\n * — with the `object` member swapped for the named ref:\n * `type: ['object', 'string']` → `union[model, string]`,\n * `['object', 'integer', 'null']` → `nullable<union[model, integer]>`,\n * `['object', 'null']` / `nullable: true` → `nullable<model>`.\n * A `oneOf: [X, { type: 'null' }]` variant has no `properties` of its own\n * and never reaches this path; `schemaToTypeRef` types it directly.\n *\n * Anything inline under a non-object member is named from the variant, never\n * from the union's field: an `array` member types its items under the\n * variant as parent with the context `variantMemberKeys` picks (`item` →\n * `<Variant>Item`, or `array_item` → `<Variant>ArrayItem` when a property\n * claims `item`), and any other member under its `value` key\n * (`<Variant>Value` for an inline enum, else `<Variant>MemberValue`). Naming\n * them from the field would hand variant 0's model name to every variant's\n * items.\n */\nfunction inlineVariantTypeRef(variant: SchemaObject, name: string): TypeRef {\n const modelRef: TypeRef = { kind: 'model', name };\n const typeList = Array.isArray(variant.type) ? variant.type : [];\n const nullable = variant.nullable === true || typeList.includes('null');\n const keys = variantMemberKeys(variant, name);\n const members = typeList\n .filter((t) => t !== 'null')\n .map((t) =>\n t === 'object'\n ? modelRef\n : schemaToTypeRef({ ...variant, type: t, nullable: false }, t === 'array' ? keys.item : keys.value, name),\n );\n const ref: TypeRef = members.length > 1 ? { kind: 'union', variants: members } : modelRef;\n return nullable ? asNullable(ref) : ref;\n}\n\nfunction extractEnum(name: string, schema: SchemaObject): Enum {\n // A `null` member marks the schema as nullable (OAS 3.1); it is not a\n // value. Nullability is carried on the `$ref` side via\n // `activeNullableEnumSchemaNames`, so drop it here instead of emitting a\n // bogus `NULL = \"null\"` member.\n const values: EnumValue[] = nonNullEnumValues(schema.enum).map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: typeof v === 'number' ? v : String(v),\n description: undefined,\n }));\n\n const rawDefault = schema.default;\n const def =\n rawDefault !== undefined && values.some((v) => v.value === rawDefault)\n ? (rawDefault as string | number)\n : undefined;\n\n return { name, values, default: def };\n}\nfunction extractModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n if (schema.allOf) {\n return extractAllOfModel(name, schema, schemas);\n }\n\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n // The sibling set the field extractor derives for this component too, so\n // array items and map values are named the same on both sides.\n const siblings = collectProperties(schema, schemas);\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet, schemas, siblings));\n }\n\n // Pure oneOf/anyOf schemas (no allOf, no properties): merge variant fields\n // as optional. This handles schemas like UpdateOrganizationMembership which\n // is a oneOf with mutually exclusive field groups (role_slug vs role_slugs).\n if (fields.length === 0 && (schema.oneOf || schema.anyOf)) {\n const variants = schema.oneOf ?? schema.anyOf ?? [];\n const emptyRequired = new Set<string>();\n const seenFieldNames = new Set<string>();\n for (const variant of variants) {\n if (!variant.properties) continue;\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n seenFieldNames.add(fieldName);\n fields.push(\n buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired, schemas, siblings),\n );\n }\n }\n }\n\n // When additionalProperties is an object schema alongside properties,\n // surface it as a catch-all map field so emitters can generate Map<string, T>.\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && schema.properties) {\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n const valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, 'additionalProperties', name);\n fields.push({\n name: 'additionalProperties',\n type: { kind: 'map', valueType },\n required: false,\n description: 'Additional properties not captured by named fields',\n });\n }\n }\n\n return { name, description: schema.description, fields, ...constraintsEntry(schema) };\n}\n\nfunction extractAllOfModel(\n name: string,\n schema: SchemaObject,\n schemas?: Record<string, SchemaObject>,\n siblingProperties?: ReadonlyMap<string, SchemaObject>,\n): Model {\n const fields: Field[] = [];\n const requiredSet = new Set<string>();\n // One sibling set for every field of the composed model, nested `allOf`\n // levels included, matching what the field extractor derives for it.\n const siblings = siblingProperties ?? collectProperties(schema, schemas);\n let resultDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n\n for (const subSchema of schema.allOf ?? []) {\n // Resolve $ref sub-schemas by looking up the referenced component schema\n let resolved = subSchema;\n if (subSchema.$ref && schemas) {\n const segments = subSchema.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) {\n resolved = schemas[refName];\n }\n }\n\n // If the resolved schema is itself an allOf, recursively extract its fields\n if (resolved.allOf) {\n const nested = extractAllOfModel(name, resolved, schemas, siblings);\n for (const f of nested.fields) {\n fields.push({ ...f, required: false }); // will be re-set below\n if (f.required) requiredSet.add(f.name);\n }\n } else if (resolved.oneOf || resolved.anyOf) {\n const variants = resolved.oneOf ?? resolved.anyOf ?? [];\n // Detect discriminated union: every variant pins the same property to a\n // distinct const value (e.g. EventSchema where each variant has event: const).\n // When detected, store the discriminator instead of flattening variant fields —\n // the base allOf schema already captures the common fields.\n const discriminatorInfo = detectAllOfVariantDiscriminator(variants, name);\n if (discriminatorInfo) {\n resultDiscriminator = discriminatorInfo;\n } else {\n // Flatten oneOf/anyOf variant fields into the parent model as optional\n // fields. This handles the common allOf + oneOf pattern where the spec\n // uses mutually exclusive variant groups (e.g. password vs password_hash).\n const emptyRequired = new Set<string>();\n const seenFieldNames = new Set(fields.map((f) => f.name));\n for (const variant of variants) {\n if (!variant.properties) continue;\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n seenFieldNames.add(fieldName);\n fields.push(\n buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired, schemas, siblings),\n );\n }\n }\n // Do NOT add variant-level required to the requiredSet — these fields\n // are optional at the parent level because they come from mutually\n // exclusive branches.\n }\n } else {\n if (resolved.required) {\n for (const r of resolved.required) requiredSet.add(r);\n }\n if (resolved.properties) {\n // Use an empty requiredSet — required flags are set in the final pass below\n const emptyRequired = new Set<string>();\n for (const [fieldName, fieldSchema] of Object.entries(resolved.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, emptyRequired, schemas, siblings));\n }\n }\n }\n }\n\n // Also collect required from the outer schema\n if (schema.required) {\n for (const r of schema.required) requiredSet.add(r);\n }\n\n // Set required flags\n for (const f of fields) {\n f.required = requiredSet.has(f.name);\n }\n\n return {\n name,\n description: schema.description,\n fields,\n ...(resultDiscriminator ? { discriminator: resultDiscriminator } : {}),\n // The wrapper's own keywords conjoined with its inline members'; `$ref`\n // members keep theirs on the referenced model.\n ...constraintsEntry(schema),\n };\n}\n\n/**\n * Walk through `allOf` wrappers to collect the effective top-level properties\n * of a schema. Stops at `oneOf` / `anyOf` boundaries — those are different\n * variant axes, not part of the same flat object.\n *\n * Used by `detectAllOfVariantDiscriminator` and `deriveDiscriminatedVariantName`\n * so a oneOf variant of the form `{ allOf: [{ properties: { … } }, { oneOf: […] }] }`\n * still surfaces its top-level `properties` (in particular its discriminator\n * `const`) instead of being treated as having none.\n */\nfunction getEffectiveProperties(schema: SchemaObject): Record<string, SchemaObject> {\n const props: Record<string, SchemaObject> = {};\n const visit = (s: SchemaObject): void => {\n if (s.properties) {\n for (const [k, v] of Object.entries(s.properties)) {\n if (!(k in props) && v) props[k] = v;\n }\n }\n if (s.allOf) {\n for (const sub of s.allOf) visit(sub);\n }\n // Do NOT walk into oneOf / anyOf — those are alternatives, not\n // simultaneously-present properties.\n };\n visit(schema);\n return props;\n}\n\nfunction getEffectiveConstPropertyValue(schema: SchemaObject, property: string): string | null {\n const direct = getConstPropertyValue(schema, property);\n if (direct !== null) return direct;\n const effective = getEffectiveProperties(schema)[property];\n if (!effective) return null;\n if (typeof effective.const === 'string') return effective.const;\n if (Array.isArray(effective.enum) && effective.enum.length === 1 && typeof effective.enum[0] === 'string') {\n return effective.enum[0];\n }\n return null;\n}\n\n/**\n * Detect an implicit discriminator on an allOf+oneOf where every variant is an\n * object that pins the same property to a distinct const value. Unlike\n * detectConstPropertyDiscriminator (which requires $ref or title for variant\n * model names), this version derives model names from the const value itself\n * using deriveDiscriminatedVariantName — matching how extractDiscriminatedAllOfVariantModels\n * names those models.\n *\n * Walks through allOf wrappers on each variant so a oneOf branch like\n * { allOf: [{ properties: { type: { const: 'oauth' } } }, { oneOf: […] }] }\n * still surfaces `type` as a candidate discriminator.\n *\n * Returns null when no discriminator can be reliably detected.\n */\nfunction detectAllOfVariantDiscriminator(\n variants: SchemaObject[],\n fallbackName: string,\n): { property: string; mapping: Record<string, string> } | null {\n if (variants.length < 2) return null;\n\n // Find a property whose const value is present on every variant\n // (looking through allOf wrappers on each variant).\n const firstProps = getEffectiveProperties(variants[0] ?? {});\n let candidateProperty: string | null = null;\n for (const propName of Object.keys(firstProps)) {\n if (variants.every((v) => getEffectiveConstPropertyValue(v, propName) !== null)) {\n candidateProperty = propName;\n break;\n }\n }\n if (!candidateProperty) return null;\n\n const mapping: Record<string, string> = {};\n const seenModelNames = new Set<string>();\n for (const v of variants) {\n const value = getEffectiveConstPropertyValue(v, candidateProperty);\n if (value === null) return null;\n const modelName = deriveDiscriminatedVariantName(v, fallbackName);\n // If two variants map to the same model name, the discriminator is ambiguous\n if (seenModelNames.has(modelName)) return null;\n seenModelNames.add(modelName);\n mapping[value] = modelName;\n }\n\n return { property: candidateProperty, mapping };\n}\n\nfunction extractDiscriminatedAllOfVariantModels(\n schema: SchemaObject,\n fallbackName: string,\n schemas?: Record<string, SchemaObject>,\n): Model[] {\n const models: Model[] = [];\n const seenNames = new Set<string>();\n\n // Collect base-object properties + required from the allOf wrapper so each\n // variant can be emitted as a complete, self-contained type. Schemas like\n // `EventSchema` repeat the base fields inside every variant in the spec\n // (so this merge is a no-op there), but `ConnectApplication`'s OAuth /\n // M2M variants don't — without this, dispatcher consumers would get a\n // variant that's missing the shared `id` / `name` / `object` etc.\n const baseProperties: Record<string, SchemaObject> = {};\n const baseRequired = new Set<string>();\n // Shared limits every variant instance must satisfy under allOf semantics:\n // the outer wrapper's own keywords, each base member's (through its allOf\n // wrappers), and any written beside the `oneOf` itself — everything except\n // the branches. They ride along with the base properties and are conjoined\n // with each variant's own below, so on a shared keyword the stricter bound\n // wins.\n let baseConstraints = ownConstraints(schema);\n for (const subSchema of schema.allOf ?? []) {\n if (subSchema.oneOf) {\n // The variant axis: its branches are handled below, its own keywords\n // bind all of them.\n baseConstraints = combineConstraints(baseConstraints, ownConstraints(subSchema));\n continue;\n }\n const flat = subSchema.allOf ? flattenVariantForExtraction(subSchema) : subSchema;\n if (flat.properties) {\n for (const [k, v] of Object.entries(flat.properties)) {\n if (!(k in baseProperties) && v) baseProperties[k] = v;\n }\n }\n if (flat.required) for (const r of flat.required) baseRequired.add(r);\n baseConstraints = combineConstraints(baseConstraints, extractConstraints(subSchema));\n }\n\n for (const subSchema of schema.allOf ?? []) {\n for (const variant of subSchema.oneOf ?? []) {\n // Flatten any allOf wrapper on the variant (e.g. `ConnectApplication`'s\n // OAuth branch is `allOf: [{ properties: {…} }, { oneOf: [first-party\n // sub-variants] }]`). The flattened object has merged properties and\n // an inlined sub-variant `oneOf` so `extractInlineModelDeep` can pull\n // out a complete variant model.\n const flat = flattenVariantForExtraction(variant);\n if (!flat.properties || (flat.type !== undefined && flat.type !== 'object')) continue;\n\n // Merge base fields into the variant. Variant-specific properties win\n // on name collisions because the spec may pin a base field to a more\n // specific shape inside a variant.\n const mergedProperties: Record<string, SchemaObject> = { ...baseProperties };\n for (const [k, v] of Object.entries(flat.properties)) {\n if (v) mergedProperties[k] = v;\n }\n const mergedRequired = new Set<string>([...baseRequired, ...(flat.required ?? [])]);\n // The variant's own keywords (read through its allOf wrappers, like its\n // properties) conjoined with the base members'. They are already in the\n // 3.1 shape, so spreading them into the rebuilt schema lets\n // extractInlineModelDeep's constraintsEntry read them back unchanged.\n const merged: SchemaObject = {\n type: 'object',\n properties: mergedProperties,\n required: [...mergedRequired],\n ...combineConstraints(baseConstraints, extractConstraints(variant)),\n };\n\n const variantName = deriveDiscriminatedVariantName(variant, fallbackName);\n for (const model of extractInlineModelDeep(variantName, merged, schemas)) {\n if (seenNames.has(model.name)) continue;\n seenNames.add(model.name);\n models.push(model);\n }\n }\n }\n\n return models;\n}\n\n/**\n * Flatten a oneOf variant schema into a single object-shaped schema for\n * variant-model extraction. Recursively merges `allOf` members and folds\n * any nested `oneOf` into an inline-oneOf field group whose properties are\n * the union across sub-branches (required only when present in every\n * sub-branch). Returns the schema unchanged when no flattening is needed.\n */\nfunction flattenVariantForExtraction(variant: SchemaObject): SchemaObject {\n if (!variant.allOf) return variant;\n\n const mergedProperties: Record<string, SchemaObject> = {};\n const mergedRequired = new Set<string>();\n const nestedOneOfs: SchemaObject[][] = [];\n\n const collect = (s: SchemaObject): void => {\n if (s.properties) {\n for (const [k, v] of Object.entries(s.properties)) {\n if (!(k in mergedProperties) && v) mergedProperties[k] = v;\n }\n }\n if (s.required) {\n for (const r of s.required) mergedRequired.add(r);\n }\n if (s.allOf) {\n for (const sub of s.allOf) collect(sub);\n }\n if (s.oneOf) nestedOneOfs.push(s.oneOf);\n };\n collect(variant);\n\n // Fold each nested oneOf into the merged shape: any field appearing in any\n // sub-branch is included as optional (or required iff present-and-required\n // in every sub-branch). Conflicting literal types widen to their primitive\n // base. This handles the `is_first_party: true | false` widening on the\n // OAuth variant's first-party sub-oneOf.\n for (const branches of nestedOneOfs) {\n const flatBranches = branches.map(flattenVariantForExtraction);\n const branchKeys = new Set<string>();\n for (const b of flatBranches) {\n for (const k of Object.keys(b.properties ?? {})) branchKeys.add(k);\n }\n for (const key of branchKeys) {\n const schemas: SchemaObject[] = [];\n for (const b of flatBranches) {\n const s = b.properties?.[key];\n if (s) schemas.push(s);\n }\n const merged = mergeBranchPropertySchemas(schemas);\n if (!(key in mergedProperties)) mergedProperties[key] = merged;\n const inAllBranches = flatBranches.every((b) => b.properties && key in b.properties);\n const requiredInAll = inAllBranches && flatBranches.every((b) => (b.required ?? []).includes(key));\n if (requiredInAll) mergedRequired.add(key);\n }\n }\n\n return {\n type: 'object',\n properties: mergedProperties,\n required: [...mergedRequired],\n };\n}\n\n/**\n * Merge same-named property schemas from across sub-variants. If every\n * occurrence is a boolean const, widen to plain boolean; if every occurrence\n * is a distinct string const, widen to plain string. Otherwise return the\n * first occurrence — emitters that build their own widened types (e.g. the\n * Node discriminated-models module) re-derive from the raw spec.\n */\nfunction mergeBranchPropertySchemas(schemas: SchemaObject[]): SchemaObject {\n if (schemas.length === 0) return {};\n if (schemas.length === 1) return schemas[0];\n\n const allBoolConst = schemas.every((s) => s.type === 'boolean' && typeof s.const === 'boolean');\n if (allBoolConst) {\n return { type: 'boolean', description: schemas[0].description };\n }\n const allStringConst = schemas.every((s) => s.type === 'string' && typeof s.const === 'string');\n if (allStringConst) {\n const values = schemas.map((s) => s.const as string);\n if (new Set(values).size === 1) return schemas[0];\n return { type: 'string', description: schemas[0].description };\n }\n return schemas[0];\n}\n\nfunction deriveDiscriminatedVariantName(schema: SchemaObject, fallbackName: string): string {\n // Walk through allOf wrappers so a variant of the form\n // `{ allOf: [{ properties: { type: const: 'oauth' } }, { oneOf: […] }] }`\n // still surfaces its discriminator const value for naming.\n const effective = getEffectiveProperties(schema);\n if (Object.keys(effective).length === 0) return fallbackName;\n\n const pickConst = (name: string): string | null => {\n const field = effective[name];\n if (!field) return null;\n if (typeof field.const === 'string') return field.const;\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return field.enum[0];\n }\n return null;\n };\n\n let constValue: string | null = null;\n for (const preferred of ['event', 'type', 'object']) {\n constValue = pickConst(preferred);\n if (constValue) break;\n }\n if (constValue === null) {\n for (const name of Object.keys(effective)) {\n constValue = pickConst(name);\n if (constValue) break;\n }\n }\n if (constValue === null) return fallbackName;\n\n const pascal = toPascalCase(constValue);\n if (!pascal) return fallbackName;\n\n // A single-word const like `oauth` or `m2m` is too generic to stand alone\n // as a top-level model name — it would collide with unrelated schemas. Pair\n // it with the parent name so the variant resolves to e.g. `ConnectApplicationOAuth`\n // / `ConnectApplicationM2M`. Multi-word consts like `action.authentication.denied`\n // are already specific enough on their own, matching the established\n // EventSchema variant naming.\n const wordCount = splitWords(constValue).length;\n if (wordCount >= 2) return pascal;\n if (pascal === fallbackName) return pascal;\n if (fallbackName.startsWith(pascal)) return fallbackName;\n if (pascal.endsWith(fallbackName)) return pascal;\n return `${fallbackName}${pascal}`;\n}\n\nfunction extractInlineModelDeep(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n const siblings = collectProperties(schema);\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet, schemas, siblings));\n\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema, schemas));\n }\n\n // Array items and map values are named like the field — or `<Field>Item` /\n // `<Field>Value` when a sibling takes the singular name — exactly as\n // `schemaToTypeRef` references them (`elementContextName`).\n if (fieldSchema.type === 'array' && fieldSchema.items?.properties) {\n const itemContext = elementContextName(fieldName, 'item', siblings, name, fieldSchema.items);\n nestedModels.push(\n ...extractInlineModelDeep(qualifyNestedInlineName(name, itemContext), fieldSchema.items, schemas),\n );\n }\n\n if (fieldSchema.type === 'object' && !fieldSchema.properties) {\n const valueSchema = mapValueSchema(fieldSchema);\n if (valueSchema && !valueSchema.$ref && valueSchema.properties) {\n const valueContext = elementContextName(fieldName, 'value', siblings, name, valueSchema);\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, valueContext), valueSchema, schemas));\n }\n }\n\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n nestedModels.push(\n ...extractInlineModelDeep(\n qualifyNestedInlineName(name, fieldName),\n {\n type: 'object',\n properties: mergedProperties,\n required: mergedRequired,\n ...extractConstraints(fieldSchema),\n },\n schemas,\n ),\n );\n }\n }\n\n if (fieldSchema.oneOf) {\n const inlineObjectVariants = fieldSchema.oneOf.filter((v) => isInlineObjectSchema(v));\n if (inlineObjectVariants.length > 0) {\n const variantNames = nameInlineVariants(\n fieldSchema,\n qualifyNestedInlineName(name, fieldName),\n reservedInlineNames(fieldName, siblings, name),\n );\n for (const variant of inlineObjectVariants) {\n const variantName = variantNames.get(variant);\n if (variantName === undefined) continue;\n nestedModels.push(...extractInlineModelDeep(variantName, variant, schemas));\n // A multi-type variant's array member types its items under the\n // variant's name (`<Variant>Item`); extract them there too. The\n // synthetic wrapper model is dropped, only its nested models kept.\n const memberSchemas = variantMemberSchemas(variant, variantName);\n if (Object.keys(memberSchemas).length > 0) {\n nestedModels.push(...extractInlineModelDeep(variantName, { properties: memberSchemas }, schemas).slice(1));\n }\n }\n }\n }\n }\n\n return [{ name, description: schema.description, fields, ...constraintsEntry(schema) }, ...nestedModels];\n}\n\nfunction qualifyNestedInlineName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n if (pascalField.startsWith(parentName)) return pascalField;\n\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n return match[1] + singularize(match[2]);\n }\n return qualified;\n}\n\n/**\n * `elementContextName` for an optional context: with no field name there is\n * nothing to decide, and the items / values keep an undefined context.\n */\nfunction elementContext(\n contextName: string | undefined,\n kind: 'item' | 'value',\n siblingProperties: ReadonlyMap<string, SchemaObject> | undefined,\n parentModelName: string | undefined,\n elementSchema: SchemaObject,\n): string | undefined {\n return contextName === undefined\n ? undefined\n : elementContextName(contextName, kind, siblingProperties, parentModelName, elementSchema);\n}\n\nexport function schemaToTypeRef(\n schema: SchemaObject,\n contextName?: string,\n parentModelName?: string,\n siblingProperties?: ReadonlyMap<string, SchemaObject>,\n // The inline names an enclosing field's siblings mint, handed down to the\n // field's array items and map values so a union among them steps around a\n // sibling's model like a union at field level (`reservedNamesFor`).\n reservedNames?: ReadonlySet<string>,\n): TypeRef {\n // Handle $ref → ModelRef or EnumRef.\n // A `$ref` to a top-level component schema needs to preserve whether the\n // target is a model or an enum, because emitters route imports differently\n // for the two kinds (e.g. com.example.models.X vs com.example.types.X). The\n // set of enum names is precomputed by extractSchemas() in a first pass so\n // it's available even when called recursively for nested $refs.\n if (schema.$ref) {\n const segments = schema.$ref.split('/');\n const rawName = segments[segments.length - 1];\n const resolved = resolveSchemaName(rawName);\n if (activeEnumSchemaNames.has(resolved)) {\n const enumRef: TypeRef = { kind: 'enum', name: resolved };\n // Carry the component's own nullability through the reference so\n // `field: { $ref: NullableEnum }` has the same shape as the inline\n // `oneOf: [{ $ref }, { type: 'null' }]` form.\n return activeNullableEnumSchemaNames.has(resolved) ? { kind: 'nullable', inner: enumRef } : enumRef;\n }\n return { kind: 'model', name: resolved };\n }\n\n // Handle OAS 3.1 nullable type arrays: type: [string, null]\n if (Array.isArray(schema.type)) {\n const nonNullTypes = schema.type.filter((t: string) => t !== 'null');\n // type: ['null'] — only null, no real type\n if (nonNullTypes.length === 0) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n // Keep `parentModelName` through the unwrap so an inline object, map\n // value, or enum under a nullable field is qualified exactly like its\n // non-nullable twin — the inline-model extractor names it that way.\n if (schema.type.includes('null') && nonNullTypes.length === 1) {\n return asNullable(\n schemaToTypeRef(\n { ...schema, type: nonNullTypes[0], nullable: false },\n contextName,\n parentModelName,\n siblingProperties,\n reservedNames,\n ),\n );\n }\n // Multiple non-null types → union\n if (nonNullTypes.length > 1) {\n const variants = nonNullTypes.map((t: string) =>\n schemaToTypeRef({ ...schema, type: t }, contextName, parentModelName, siblingProperties, reservedNames),\n );\n const ref: TypeRef = { kind: 'union', variants };\n if (schema.type.includes('null')) {\n return { kind: 'nullable', inner: ref };\n }\n return ref;\n }\n }\n\n // Handle OAS 3.0 nullable flag\n if (schema.nullable && schema.type) {\n return asNullable(\n schemaToTypeRef({ ...schema, nullable: false }, contextName, parentModelName, siblingProperties, reservedNames),\n );\n }\n\n // Handle allOf — merge properties from all sub-schemas.\n // This handles patterns like: allOf: [{ type: object, properties: {...} }, { oneOf: [...] }]\n // which are valid OAS 3.1 but weren't handled for field-level schemas.\n if (schema.allOf) {\n // If allOf contains a $ref, prefer the ref (it's a named type)\n const refItem = schema.allOf.find((s: SchemaObject) => s.$ref);\n if (refItem) {\n // If allOf has $ref AND siblings with properties, return a merged model ref\n // to avoid losing the augmentation properties\n const hasAugmentation = schema.allOf.some((s: SchemaObject) => !s.$ref && (s.properties || s.type === 'object'));\n if (hasAugmentation) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return { kind: 'model', name: qualifyInlineModelName(baseName, parentModelName) };\n }\n return schemaToTypeRef(refItem, contextName, parentModelName);\n }\n // If allOf has a single item, unwrap it\n if (schema.allOf.length === 1) {\n return schemaToTypeRef(schema.allOf[0], contextName, parentModelName, siblingProperties, reservedNames);\n }\n // If allOf items all have properties, treat as a merged model\n const hasProperties = schema.allOf.some((s: SchemaObject) => s.properties);\n if (hasProperties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n // Fall through to other checks\n }\n\n // Handle oneOf / anyOf → Union or Nullable\n // Valid OAS 3.1: properties can have { oneOf: [{ type: object }, { type: 'null' }] }\n // without a wrapping `type` field.\n if (schema.oneOf || schema.anyOf) {\n const compositionKind: 'oneOf' | 'anyOf' = schema.oneOf ? 'oneOf' : 'anyOf';\n const rawVariants: SchemaObject[] = schema.oneOf ?? schema.anyOf ?? [];\n\n // Check for nullable pattern: oneOf: [realType, { type: 'null' }]\n const nullVariant = rawVariants.find(isNullVariantSchema);\n const nonNullVariants = rawVariants.filter((v) => v !== nullVariant);\n\n if (nullVariant && nonNullVariants.length === 1) {\n // Nullable single type — unwrap as nullable. `asNullable` keeps a\n // `$ref` to an already-nullable enum component from double-wrapping.\n return asNullable(\n schemaToTypeRef(nonNullVariants[0], contextName, parentModelName, siblingProperties, reservedNames),\n );\n }\n\n // Collapse an oneOf/anyOf whose non-null variants are all string-const\n // schemas into a single enum. This turns patterns like\n // provider: { oneOf: [{ const: \"AppleOAuth\" }, { const: \"GitHubOAuth\" }, ...] }\n // into a proper enum type with one member per variant instead of a\n // structurally-opaque union of literal refs.\n const literalStrings = collectLiteralStringConsts(nonNullVariants);\n if (literalStrings !== null && literalStrings.length >= 2) {\n const enumRef = buildSyntheticEnumRef(literalStrings, contextName, parentModelName);\n return nullVariant ? { kind: 'nullable', inner: enumRef } : enumRef;\n }\n\n // The inline object variants' model names, decided once for this TypeRef\n // and every extractor (`nameInlineVariants`): variant 0's bare qualified\n // field name, a const prefix, a title, a distinguishing property or a\n // counter — or, for a `oneOf` whose every variant is titled and pins a\n // const (3. below), the title itself — never a name a sibling property\n // mints. Computed first because the derived discriminator mappings below\n // are read from it, so a mapping can only point at a model that exists.\n const inlineVariantNames = nameInlineObjectVariants(\n schema,\n contextName,\n parentModelName,\n siblingProperties,\n reservedNames,\n );\n\n // Resolve the discriminator. Four sources, in order:\n // 1. Explicit `discriminator:` with explicit `mapping:` — trust the spec.\n // 2. Explicit `discriminator:` with no `mapping:` — pair each variant's\n // const value on the property with its inline model name\n // (`deriveInlineVariantMapping`). This covers `ApiKey.owner`-shaped\n // schemas where the spec uses `discriminator: { propertyName: type }`\n // but lists inline anonymous `oneOf` variants instead of `$ref` links.\n // 3. No explicit discriminator, but every variant carries a `$ref` or a\n // `title` and pins the same const property\n // (`titleMappedDiscriminatorProperty`): the mapping names a `$ref`\n // variant by its component and an inline variant by the name\n // `nameInlineVariants` gave it — its title (`Circle`, `Square`)\n // unless that is taken — so the extracted model and the mapping agree.\n // 4. Otherwise, when every inline variant pins the same const property\n // with distinct values (`deriveConstNamingDiscriminator`), the same\n // value → inline model name pairing as 2. This covers\n // `ApiKeyCreatedData.owner`-shaped schemas (oneOf with inline\n // const-discriminating variants but no `discriminator:` keyword).\n let resolvedDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n if (schema.discriminator) {\n const property = schema.discriminator.propertyName;\n const explicitMapping = schema.discriminator.mapping ?? {};\n let mapping: Record<string, string> = Object.fromEntries(\n Object.entries(explicitMapping).map(([k, v]) => [k, v.replace(/^#\\/components\\/schemas\\//, '')]),\n );\n if (Object.keys(mapping).length === 0) {\n const inlineMapping = deriveInlineVariantMapping(nonNullVariants, property, contextName, inlineVariantNames);\n if (inlineMapping) mapping = inlineMapping;\n }\n resolvedDiscriminator = { property, mapping };\n } else if (compositionKind === 'oneOf') {\n const titleProperty = titleMappedDiscriminatorProperty(nonNullVariants);\n if (titleProperty) {\n const mapping: Record<string, string> = {};\n for (const v of nonNullVariants) {\n const value = getConstPropertyValue(v, titleProperty);\n const mappedName = inlineVariantNames.get(v) ?? resolveVariantModelName(v);\n if (value !== null && mappedName !== null) mapping[value] = mappedName;\n }\n resolvedDiscriminator = { property: titleProperty, mapping };\n } else {\n const namingDisc = deriveConstNamingDiscriminator(nonNullVariants);\n if (namingDisc) {\n const inlineMapping = deriveInlineVariantMapping(\n nonNullVariants,\n namingDisc.property,\n contextName,\n inlineVariantNames,\n );\n if (inlineMapping) {\n resolvedDiscriminator = { property: namingDisc.property, mapping: inlineMapping };\n }\n }\n }\n }\n\n // Build variants. An inline object variant is referenced by the name its\n // extracted model carries (`inlineVariantNames`); a discriminator mapping\n // entry substitutes for it only when the spec's own `mapping:` (1.) names\n // the variant, since the derived mappings (2.–4.) are read from the same\n // names. Falling back to `schemaToTypeRef` instead would hand every\n // inline variant the same parent-derived name (e.g. `ApiKeyOwner`),\n // collapsing the union onto one repeated model ref while the extractor\n // emits `ApiKeyOwner`, `UserApiKeyOwner`, ... for them.\n // The named ref replaces only the `object` member of what `schemaToTypeRef`\n // would build for the variant: a nullable variant (`['object', 'null']`,\n // OAS 3.0 `nullable: true`) keeps its wrapper, and a multi-type variant\n // (`['object', 'string']`) keeps its other alternatives in a union — see\n // `inlineVariantTypeRef`. The extractor emits the model under the same\n // name in every case.\n const variants: TypeRef[] = [];\n for (const v of rawVariants) {\n if (v === nullVariant) continue;\n const inlineName = inlineVariantNames.get(v);\n if (inlineName) {\n const mappedName = resolvedDiscriminator ? mapVariantToDiscriminatorEntry(v, resolvedDiscriminator) : null;\n variants.push(inlineVariantTypeRef(v, mappedName ?? inlineName));\n } else {\n variants.push(schemaToTypeRef(v, contextName, parentModelName));\n }\n }\n const hasNull = !!nullVariant;\n\n const union: TypeRef = {\n kind: 'union',\n variants,\n compositionKind,\n ...(resolvedDiscriminator ? { discriminator: resolvedDiscriminator } : {}),\n };\n return hasNull ? { kind: 'nullable', inner: union } : union;\n }\n\n // Handle const → LiteralType (supports string, number, boolean)\n if (schema.const !== undefined) {\n if (typeof schema.const === 'string' || typeof schema.const === 'number' || typeof schema.const === 'boolean') {\n return { kind: 'literal', value: schema.const };\n }\n // null const → nullable unknown\n if (schema.const === null) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n // const of object/array → map or array with unknown values\n if (typeof schema.const === 'object') {\n if (Array.isArray(schema.const)) {\n return { kind: 'array', items: { kind: 'primitive', type: 'unknown' } };\n }\n return { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } };\n }\n }\n // A `null` member of an inline `enum:` marks nullability, not a value.\n // Strip it before deciding literal-vs-enum, and wrap the result so a\n // bare `type: 'string', enum: ['a', null]` is nullable even without a\n // `type: [..., 'null']` array (the array branch above already wrapped\n // us when present; `asNullable` keeps that from doubling up).\n const enumValues = nonNullEnumValues(schema.enum);\n const enumAdmitsNull = schema.enum !== undefined && enumValues.length !== schema.enum.length;\n if (schema.enum && enumValues.length === 1) {\n const v = enumValues[0];\n const literal: TypeRef = { kind: 'literal', value: typeof v === 'number' ? v : String(v) };\n return enumAdmitsNull ? asNullable(literal) : literal;\n }\n\n // Handle enum\n if (schema.enum) {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n // Strip ListItem/ByExternalId markers from parent name so enum names are clean:\n // e.g., DirectoryListItem + State → Directory + State = DirectoryState\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n // Avoid redundant prefix: Connection + ConnectionType → ConnectionType\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n // Run `schemaNameTransform` so project-level rename maps in\n // `oagen.config.ts` reach inline parameter/field enums too — without\n // this, `RadarAction` (built from path param `action` on the Radar\n // service) couldn't be redirected to `RadarListAction` from config.\n const finalName = activeSchemaNameTransform ? activeSchemaNameTransform(qualifiedName) : qualifiedName;\n const enumRef: TypeRef = {\n kind: 'enum',\n name: finalName,\n values: enumValues.map((v) => (typeof v === 'number' ? v : String(v))),\n };\n return enumAdmitsNull ? asNullable(enumRef) : enumRef;\n }\n\n // Handle array — pass parentModelName through to qualify inline items. The\n // items' context is the field itself, or `<field>_item` when a sibling\n // property would take the singular name (`elementContextName`), so an\n // inline object item is `<Parent><Field>` or `<Parent><Field>Item`. The\n // items get no sibling set of their own (they are not a property), but a\n // union among them must still step around the models the field's siblings\n // mint, so that set is handed down (`reservedNamesFor`), exactly as the\n // extractor passes it into its items re-entry.\n if ((schema.type === 'array' || !schema.type) && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(\n schema.items,\n elementContext(contextName, 'item', siblingProperties, parentModelName, schema.items),\n parentModelName,\n undefined,\n reservedNamesFor(contextName, siblingProperties, parentModelName, reservedNames),\n ),\n };\n }\n\n // Handle object → ModelRef (if it has properties, it's a named model reference)\n // When additionalProperties is also present, we still return a ModelRef so the\n // named properties are preserved. The extractModel path will pick up the extra\n // properties as a catch-all map field named `additionalProperties`.\n if (schema.type === 'object' && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Handle freeform object with additionalProperties or patternProperties → Map<string, T>\n // The value schema is typed with the field's own `contextName` and\n // `parentModelName`, exactly like array items, so an inline object value is\n // referenced as `${Parent}${SingularField}` (`layers` on\n // `CreateDrawingRequest` → `CreateDrawingRequestLayer`) and the inline-model\n // extractor (`extractInlineModelsFromProperties`) emits a model of that name.\n // When a sibling property would take that singular name the values use\n // `<field>_value` instead (`<Parent><Field>Value`, see `elementContextName`).\n if (schema.type === 'object' && !schema.properties) {\n // `mapValueSchema` picks the value schema in this branch's precedence: a\n // non-empty `additionalProperties` object, else the first\n // `patternProperties` entry; `additionalProperties: {}` or `true` means\n // \"any value\" and stays unknown.\n let valueType: TypeRef = { kind: 'primitive', type: 'unknown' };\n const valueSchema = mapValueSchema(schema);\n if (valueSchema) {\n const valueContext = elementContext(contextName, 'value', siblingProperties, parentModelName, valueSchema);\n // Like array items: the field's sibling reservations reach the values.\n valueType = schemaToTypeRef(\n valueSchema,\n valueContext,\n parentModelName,\n undefined,\n reservedNamesFor(contextName, siblingProperties, parentModelName, reservedNames),\n );\n }\n return {\n kind: 'map',\n valueType,\n };\n }\n\n // Handle primitives\n const primitiveMap: Record<string, 'string' | 'integer' | 'number' | 'boolean'> = {\n string: 'string',\n integer: 'integer',\n number: 'number',\n boolean: 'boolean',\n };\n\n const typeStr = Array.isArray(schema.type) ? schema.type[0] : schema.type;\n if (typeStr && primitiveMap[typeStr]) {\n return {\n kind: 'primitive',\n type: primitiveMap[typeStr],\n ...(schema.format ? { format: schema.format } : {}),\n };\n }\n\n // Handle schemas with no type — if it has properties, treat as model\n if (!schema.type && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Empty schema {} → unknown\n if (\n !schema.type &&\n !schema.$ref &&\n !schema.oneOf &&\n !schema.anyOf &&\n !schema.allOf &&\n !schema.enum &&\n !schema.properties &&\n !schema.items\n ) {\n return { kind: 'primitive', type: 'unknown' };\n }\n\n // Fallback: treat unknown schemas as unknown\n if (contextName) {\n console.warn(`[oagen] Warning: Unknown schema shape treated as unknown (context: ${contextName})`);\n }\n return { kind: 'primitive', type: 'unknown' };\n}\n\nimport {\n collectProperties,\n elementContextName,\n mapValueSchema,\n qualifyInlineModelName,\n reservedInlineNames,\n} from './inline-models.js';\n\nexport { qualifyInlineModelName, extractInlineModelsFromSchemas } from './inline-models.js';\n","import type { TypeRef, Parameter, PaginationMeta } from '../ir/types.js';\n\nconst CURSOR_PARAMS = ['cursor', 'after', 'before', 'starting_after', 'ending_before', 'page_token', 'next_token'];\n\nconst OFFSET_PARAMS = ['offset', 'page', 'page_number', 'skip'];\nconst LIMIT_PARAMS = ['limit', 'page_size', 'per_page', 'size', 'count'];\n\n/**\n * Detect if an operation uses pagination and return structured metadata\n * for auto-paging iterator generation.\n *\n * Supports two strategies:\n * 1. **Cursor-based**: query params include a cursor-like parameter\n * 2. **Offset-based**: query params include both an offset-like and limit-like parameter\n *\n * Returns null if no pagination pattern is detected.\n */\nexport function detectPagination(\n response: TypeRef,\n queryParams: Parameter[],\n dataPath?: string,\n): PaginationMeta | null {\n // Try cursor-based first (preferred). Scan in CURSOR_PARAMS priority order\n // rather than queryParams order so that an endpoint exposing both `before`\n // and `after` reports `after` (forward iteration) — matches the wire\n // convention where `after` advances through pages.\n const cursorParam = CURSOR_PARAMS.map((name) => queryParams.find((p) => p.name === name)).find(\n (p): p is Parameter => p !== undefined,\n );\n\n if (cursorParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'cursor',\n param: cursorParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n // Try offset-based pagination\n const offsetParam = queryParams.find((p) => OFFSET_PARAMS.includes(p.name));\n const limitParam = queryParams.find((p) => LIMIT_PARAMS.includes(p.name));\n\n if (offsetParam && limitParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'offset',\n param: offsetParam.name,\n limitParam: limitParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n return null;\n}\n","import type { TypeRef, Model, Field } from '../ir/types.js';\nimport { toPascalCase } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport {\n schemaToTypeRef,\n buildFieldFromSchema,\n constraintsEntry,\n extractConstraints,\n isInlineObjectSchema,\n} from './schemas.js';\nimport type { EnvelopeCompanion } from './envelope-companion-names.js';\nimport { collectProperties, extractInlineModelsFromProperties } from './inline-models.js';\n\nexport interface ResponseExtractionResult {\n /** The TypeRef to use as the operation's response type */\n response: TypeRef;\n /** Any inline models discovered during extraction (to merge into ir.models) */\n inlineModels: Model[];\n /** Whether this response indicates a paginated list */\n isPaginated: boolean;\n /** Path to the data array within the response envelope (e.g., 'data') */\n dataPath?: string;\n /** TypeRef of individual items in a paginated list */\n itemType?: TypeRef;\n /**\n * The envelope's properties other than the data array (see\n * `PaginationMeta.envelopeFields`). Set only for a list envelope.\n */\n envelopeFields?: Field[];\n /**\n * Models lifted from inline companion objects, still under their\n * operation-qualified names. They are deliberately not in `inlineModels`:\n * `resolveEnvelopeCompanionNames` decides their final names once every list\n * operation has been extracted.\n */\n envelopeCompanions?: EnvelopeCompanion[];\n}\n\nexport function classifyAndExtractResponse(\n schema: SchemaObject,\n contextName: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ResponseExtractionResult {\n // 1. If schema is a $ref, resolve to model name (Phase 1)\n if (schema.$ref) {\n return { response: schemaToTypeRef(schema, contextName), inlineModels: [], isPaginated: false };\n }\n\n // 2. Check for list envelope (structural detection: array prop + non-array companion)\n const envelope = detectListEnvelope(schema);\n if (envelope.isEnvelope) {\n return extractListResponse(schema, contextName, envelope.dataPath!, componentSchemas);\n }\n\n // 3. Check for single-resource wrapper ({ resource_name: { object: \"...\", ... } })\n if (isSingleResourceWrapper(schema)) {\n return extractWrappedResource(schema, contextName, componentSchemas);\n }\n\n // 4. Direct resource or plain inline object\n return extractDirectResource(schema, contextName, componentSchemas);\n}\n\ninterface ListEnvelopeResult {\n isEnvelope: boolean;\n dataPath: string | null;\n}\n\nconst KNOWN_DATA_PATHS = new Set(['data', 'items', 'results', 'records', 'entries', 'values', 'nodes', 'edges']);\n\nconst PAGINATION_METADATA_PATTERNS = [\n 'meta',\n 'metadata',\n 'pagination',\n 'cursor',\n 'has_more',\n 'page_info',\n 'total',\n 'next_page',\n 'previous_page',\n 'offset',\n];\n\nfunction detectListEnvelope(schema: SchemaObject): ListEnvelopeResult {\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n if (propSources.length === 0) return { isEnvelope: false, dataPath: null };\n\n // Merge all properties into a single view\n const mergedProps: Record<string, SchemaObject | undefined> = {};\n for (const source of propSources) {\n Object.assign(mergedProps, source);\n }\n\n // Find array-typed properties and non-array companion properties\n const arrayProps: string[] = [];\n const nonArrayKeys: string[] = [];\n\n for (const [key, propSchema] of Object.entries(mergedProps)) {\n if (!propSchema) continue;\n if (propSchema.type === 'array') {\n arrayProps.push(key);\n } else {\n nonArrayKeys.push(key);\n }\n }\n\n // List envelope heuristic: exactly one array property + at least one non-array companion\n // that looks like pagination metadata. A `data` array alone (e.g. with only an\n // `object` discriminant companion) is NOT sufficient — the companion must indicate\n // actual pagination (cursor, metadata, total, etc.).\n if (arrayProps.length === 1 && nonArrayKeys.length >= 1) {\n const arrayPropName = arrayProps[0];\n\n const hasPaginationCompanion = nonArrayKeys.some((key) =>\n PAGINATION_METADATA_PATTERNS.some((pattern) => key.toLowerCase().includes(pattern)),\n );\n\n if (KNOWN_DATA_PATHS.has(arrayPropName) && hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n\n // Non-standard array property name — still treat as envelope if pagination companion exists\n if (hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n }\n\n return { isEnvelope: false, dataPath: null };\n}\n\nfunction extractListResponse(\n schema: SchemaObject,\n contextName: string,\n dataPath: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ResponseExtractionResult {\n let itemTypeRef: TypeRef = { kind: 'primitive', type: 'string' };\n const inlineModels: Model[] = [];\n\n const { properties, required } = collectEnvelopeProperties(schema, componentSchemas);\n\n const dataProp = properties[dataPath];\n if (dataProp?.type === 'array' && dataProp.items) {\n const items = dataProp.items;\n if (items.$ref) {\n itemTypeRef = schemaToTypeRef(items, contextName);\n } else if (items.type === 'object' && items.properties) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n itemTypeRef = { kind: 'model', name: itemName };\n inlineModels.push(...extractInlineModel(itemName, items, componentSchemas));\n }\n }\n\n // Everything the envelope carries besides the data array: the pagination\n // companion (`list_metadata`, `pagination`, `has_more`, …) and any\n // discriminant such as `object: \"list\"`. Without these an emitter cannot\n // type the endpoint's actual response or read the next-page details.\n const { envelopeFields, envelopeCompanions } = extractEnvelopeCompanions(\n properties,\n required,\n dataPath,\n contextName.replace(/Response$/, ''),\n componentSchemas,\n );\n\n return {\n response: { kind: 'array', items: itemTypeRef },\n inlineModels,\n isPaginated: true,\n dataPath,\n itemType: itemTypeRef,\n envelopeFields,\n envelopeCompanions: envelopeCompanions.length > 0 ? envelopeCompanions : undefined,\n };\n}\n\n/**\n * Every property the envelope declares, merged across its `allOf` branches,\n * with the `required` lists that go with them.\n *\n * A `$ref` branch is resolved against the component schemas so fields an\n * envelope inherits from a shared base (`trace_id` on every response, say)\n * are not silently dropped. A property declared by more than one branch keeps\n * both declarations' shape when both are inline objects — `pagination.next`\n * from one branch and `pagination.total` from another both belong to the\n * response — and otherwise takes the later declaration, as `allOf` merging\n * does elsewhere in the parser.\n */\nfunction collectEnvelopeProperties(\n schema: SchemaObject,\n componentSchemas?: Record<string, SchemaObject>,\n): { properties: Record<string, SchemaObject>; required: string[] } {\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n const seenRefs = new Set<string>();\n\n const visit = (s: SchemaObject): void => {\n if (s.$ref) {\n if (seenRefs.has(s.$ref)) return;\n seenRefs.add(s.$ref);\n const refName = s.$ref.split('/').pop();\n const resolved = refName ? componentSchemas?.[refName] : undefined;\n if (resolved) visit(resolved);\n return;\n }\n for (const sub of s.allOf ?? []) visit(sub);\n for (const [key, prop] of Object.entries(s.properties ?? {})) {\n if (!prop) continue;\n const existing = properties[key];\n properties[key] = existing ? mergePropertyDeclarations(existing, prop) : prop;\n }\n if (s.required) required.push(...s.required);\n };\n visit(schema);\n\n return { properties, required };\n}\n\n/**\n * Combine two `allOf` declarations of one property. Inline objects merge their\n * fields; an array keeps the earlier `items` when the later declaration only\n * constrains it (`minItems: 1`), so `data: User[]` is not downgraded to\n * `string[]`; anything else takes the later declaration.\n */\nfunction mergePropertyDeclarations(earlier: SchemaObject, later: SchemaObject): SchemaObject {\n if (isInlineObjectSchema(earlier) && isInlineObjectSchema(later)) {\n return {\n ...earlier,\n ...later,\n properties: { ...earlier.properties, ...later.properties },\n required: [...(earlier.required ?? []), ...(later.required ?? [])],\n };\n }\n if (earlier.type === 'array' && later.type === 'array') {\n return { ...earlier, ...later, items: later.items ?? earlier.items };\n }\n return later;\n}\n\n/**\n * Type a list envelope's companion properties as fields, lifting any inline\n * object among them (and anything nested inside it) to a model.\n *\n * Models come from `extractInlineModelsFromProperties`, the extractor that\n * mirrors `schemaToTypeRef` form for form — plain, nullable and `allOf`\n * objects, arrays of objects, and every `oneOf`/`anyOf` object variant — so a\n * field's reference always has a model behind it.\n *\n * Each companion is extracted twice: once under the operation's name, which\n * is how its models enter the IR (`ListUsersListMetadata`), and once under no\n * parent, which yields the name each model would carry if named from its\n * property alone (`ListMetadata`). Both runs walk the same code path, so the\n * two model lists line up index for index. `resolveEnvelopeCompanionNames`\n * later picks, per companion, which of the two names survives — the bare one\n * only where every copy of that companion across the API agrees structurally.\n */\nfunction extractEnvelopeCompanions(\n properties: Record<string, SchemaObject>,\n required: string[],\n dataPath: string,\n operationName: string,\n componentSchemas?: Record<string, SchemaObject>,\n): { envelopeFields: Field[]; envelopeCompanions: EnvelopeCompanion[] } {\n const envelopeFields: Field[] = [];\n const envelopeCompanions: EnvelopeCompanion[] = [];\n const requiredSet = new Set(required);\n // The companion is extracted from a one-property schema, so hand the\n // extractor the envelope's full property list: array items and map values\n // must step aside from a singular sibling exactly as the field does.\n const siblings = collectProperties({ properties });\n\n for (const [key, propSchema] of Object.entries(properties)) {\n if (key === dataPath) continue;\n const field = buildFieldFromSchema(key, propSchema, operationName, requiredSet, componentSchemas, siblings);\n envelopeFields.push(field);\n\n // Both runs get the component map so a companion's `$ref` fields carry\n // the component's example in the qualified and bare copies alike; it\n // only feeds field metadata, so the two model lists still line up.\n const single: SchemaObject = { type: 'object', properties: { [key]: propSchema } };\n const models: Model[] = [];\n extractInlineModelsFromProperties(single, models, operationName, componentSchemas, siblings);\n if (models.length === 0) continue;\n const bare: Model[] = [];\n extractInlineModelsFromProperties(single, bare, undefined, componentSchemas, siblings);\n envelopeCompanions.push({ field, models, bareNames: bare.map((m) => m.name) });\n }\n\n return { envelopeFields, envelopeCompanions };\n}\n\nfunction hasDiscriminantConstField(schema: SchemaObject): { property: string; value: string } | null {\n if (!schema.properties) return null;\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n // Fall back to any property with a const or single-value enum\n for (const [name, field] of Object.entries(schema.properties)) {\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n return null;\n}\n\nfunction isSingleResourceWrapper(schema: SchemaObject): boolean {\n if (schema.type !== 'object') return false;\n if (!schema.properties) return false;\n\n // Find the wrapper property: use required[0] if available, or the single property key\n let wrapperKey: string | undefined;\n if (schema.required && schema.required.length === 1) {\n wrapperKey = schema.required[0];\n } else {\n const propKeys = Object.keys(schema.properties);\n if (propKeys.length === 1) {\n wrapperKey = propKeys[0];\n }\n }\n if (!wrapperKey) return false;\n\n const propSchema = schema.properties[wrapperKey];\n if (!propSchema) return false;\n\n // Direct object with a discriminant const field\n if (propSchema.type === 'object' && hasDiscriminantConstField(propSchema) !== null) return true;\n\n // oneOf with object + null (nullable resource)\n if (propSchema.oneOf) {\n return propSchema.oneOf.some((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n }\n\n return false;\n}\n\nfunction extractWrappedResource(\n schema: SchemaObject,\n contextName: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ResponseExtractionResult {\n const props = schema.properties!;\n const wrapperKey = schema.required && schema.required.length === 1 ? schema.required[0] : Object.keys(props)[0];\n const propSchema = props[wrapperKey]!;\n const inlineModels: Model[] = [];\n\n // Derive model name from the object const value or wrapper property name\n const resourceName = contextName.replace(/Response$/, '');\n\n if (propSchema.oneOf) {\n const objectVariant = propSchema.oneOf.find((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n\n if (objectVariant) {\n const modelName = deriveModelName(objectVariant, resourceName);\n inlineModels.push(...extractInlineModel(modelName, objectVariant, componentSchemas));\n\n const hasNullVariant = propSchema.oneOf.some(\n (v) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n\n const modelRef: TypeRef = { kind: 'model', name: modelName };\n return {\n response: hasNullVariant ? { kind: 'nullable', inner: modelRef } : modelRef,\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Direct object\n const modelName = deriveModelName(propSchema, resourceName);\n inlineModels.push(...extractInlineModel(modelName, propSchema, componentSchemas));\n\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction extractDirectResource(\n schema: SchemaObject,\n contextName: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ResponseExtractionResult {\n const inlineModels: Model[] = [];\n\n // Direct object with properties (with or without explicit type: 'object')\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const modelName = deriveModelName(schema, contextName);\n inlineModels.push(...extractInlineModel(modelName, schema, componentSchemas));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n\n // allOf — merge into a single model. $ref branches are resolved against\n // component schemas so the referenced model's fields are merged rather\n // than silently dropped.\n if (schema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n const unresolvedRefs: string[] = [];\n const seenRefs = new Set<string>();\n let mergedRefFields = false;\n\n const mergeSubSchemas = (subs: SchemaObject[]) => {\n for (const sub of subs) {\n let resolved: SchemaObject = sub;\n if (sub.$ref) {\n if (seenRefs.has(sub.$ref)) continue;\n seenRefs.add(sub.$ref);\n const segments = sub.$ref.split('/');\n const refName = segments[segments.length - 1];\n const refSchema = refName ? componentSchemas?.[refName] : undefined;\n if (!refSchema) {\n unresolvedRefs.push(sub.$ref);\n continue;\n }\n resolved = refSchema;\n mergedRefFields = true;\n }\n if (resolved.allOf) mergeSubSchemas(resolved.allOf);\n if (resolved.properties) Object.assign(mergedProperties, resolved.properties);\n if (resolved.required) mergedRequired.push(...resolved.required);\n }\n };\n mergeSubSchemas(schema.allOf);\n\n // An unresolvable $ref branch (no component schema map) would drop the\n // referenced model's fields entirely — prefer the referenced model as\n // the response type over a merge that silently guts it.\n if (unresolvedRefs.length === 1 && !mergedRefFields) {\n return {\n response: schemaToTypeRef({ $ref: unresolvedRefs[0] }, contextName),\n inlineModels,\n isPaginated: false,\n };\n }\n\n if (Object.keys(mergedProperties).length > 0) {\n // Carry the wrapper's limits, conjoined with its inline members', so the\n // rebuilt schema still declares what an instance must satisfy.\n const merged: SchemaObject = {\n type: 'object',\n properties: mergedProperties,\n required: mergedRequired,\n ...extractConstraints(schema),\n };\n // Fields merged from a $ref carry the referenced model's const\n // discriminant (e.g. object: 'magic_auth'); deriving the name from it\n // would collide with the component model, so keep the context name.\n const modelName = mergedRefFields ? toPascalCase(contextName) : deriveModelName(merged, contextName);\n inlineModels.push(...extractInlineModel(modelName, merged, componentSchemas));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // oneOf — delegate to schemaToTypeRef (returns union) and materialize the\n // inline object variants through the field extractor, as a field of this\n // name under no parent: it names them exactly as the union below references\n // them (`nameInlineVariants` from the context name — `GetThingResponse`,\n // `GetThingResponseWithSide`, `SquareGetThingResponse`), covers a nullable\n // (`type: ['object', 'null']`) or multi-type variant that a plain\n // `type === 'object'` test would skip, and recurses into everything nested\n // under each variant, so the response never references a model the parser\n // did not create.\n if (schema.oneOf) {\n extractInlineModelsFromProperties(\n { properties: { [contextName]: schema } },\n inlineModels,\n undefined,\n componentSchemas,\n );\n }\n\n // Array with inline object items — extract the item model\n if (schema.type === 'array' && schema.items) {\n const items = schema.items;\n if (items.$ref) {\n return {\n response: { kind: 'array', items: schemaToTypeRef(items, contextName) },\n inlineModels,\n isPaginated: false,\n };\n }\n if (items.properties && (items.type === 'object' || !items.type)) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n inlineModels.push(...extractInlineModel(itemName, items, componentSchemas));\n return {\n response: { kind: 'array', items: { kind: 'model', name: itemName } },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Non-object schema (primitive, union, etc.) — delegate to schemaToTypeRef\n return {\n response: schemaToTypeRef(schema, contextName),\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction deriveModelName(schema: SchemaObject, fallback: string): string {\n if (!schema.properties) return toPascalCase(fallback);\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n // Fall back to any property with a const string value\n for (const [, field] of Object.entries(schema.properties)) {\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n return toPascalCase(fallback);\n}\n\n/**\n * Materialise an inline response object (and every nested inline object\n * under it) as models. `componentSchemas` only feeds `buildFieldFromSchema`,\n * so a response field that `$ref`s a component takes the component's\n * `example`/`examples` exactly as a request-body or component-model field\n * does; nested models get the same map so the fallback reaches every level.\n */\nfunction extractInlineModel(\n name: string,\n schema: SchemaObject,\n componentSchemas?: Record<string, SchemaObject>,\n): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n const siblings = collectProperties(schema);\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet, componentSchemas, siblings));\n }\n\n // Every nested inline model a field references — an inline object, array\n // items, map values, an `allOf` merge or `$ref` augmentation, every\n // `oneOf`/`anyOf` variant (numbered, const-prefixed, nullable, multi-type,\n // with `<Variant>Item` members), with sibling-aware item/value names —\n // comes from the same extractor that materializes them for component\n // schemas and request bodies. `buildFieldFromSchema` above named the\n // references through `schemaToTypeRef`; this names the models the same way,\n // so they agree by construction instead of through a response-local copy of\n // the rules.\n extractInlineModelsFromProperties(schema, nestedModels, name, componentSchemas);\n\n return [{ name, description: schema.description, fields, ...constraintsEntry(schema) }, ...nestedModels];\n}\n","import type { SecurityRequirementSet } from '../ir/types.js';\n\n/**\n * An OpenAPI security requirement list as written in the document: each\n * object is one alternative whose keys are scheme names and whose values are\n * the scopes that scheme needs.\n */\nexport type RawSecurityRequirements = Array<Record<string, string[] | undefined> | null | undefined>;\n\n/**\n * Convert a document- or operation-level `security` list into the IR shape,\n * preserving what the list says rather than flattening it:\n *\n * - absent (or not a list) → `undefined`: nothing declared here.\n * - `[]` → `[]`: no authentication required.\n * - `[{ a: [] }, { b: [] }]` → `[[a], [b]]`: either scheme suffices.\n * - `[{ a: [], b: [] }]` → `[[a, b]]`: both schemes are required together.\n * - `[{ a: [] }, {}]` → `[[a], []]`: the empty set is an anonymous alternative,\n * which is how a document marks authentication optional.\n *\n * An entry that is not an object (`null`, say) is not a requirement object.\n * Reading it as `{}` would declare an anonymous alternative and make the\n * operation look open, so it is dropped with an `[oagen] Warning:` naming\n * `context` (the operation, or the document). A non-empty list left with no\n * valid entry is treated as undeclared (`undefined`) rather than as `[]`:\n * the document never said \"no authentication\", so the operation keeps\n * inheriting the default.\n *\n * The previous flattening collapsed the alternatives onto one list and turned\n * `[]` into `undefined`, so \"no auth\" read the same as \"use the default\" and\n * \"either of\" the same as \"all of\" (#182).\n */\nexport function extractSecurityRequirements(\n security: RawSecurityRequirements | undefined,\n context: string,\n): SecurityRequirementSet[] | undefined {\n if (!Array.isArray(security)) return undefined;\n\n const sets: SecurityRequirementSet[] = [];\n for (const entry of security) {\n if (entry === null || typeof entry !== 'object' || Array.isArray(entry)) {\n console.warn(\n `[oagen] Warning: Ignoring security requirement ${JSON.stringify(entry)} on ${context} — not a requirement object`,\n );\n continue;\n }\n sets.push(\n Object.entries(entry).map(([schemeName, scopes]) => ({\n schemeName,\n scopes: Array.isArray(scopes) ? scopes : [],\n })),\n );\n }\n if (security.length > 0 && sets.length === 0) {\n console.warn(`[oagen] Warning: No valid security requirement on ${context}; treating security as undeclared`);\n return undefined;\n }\n return sets;\n}\n","import type { Field, Model, TypeRef } from '../ir/types.js';\nimport { assertNever, collectModelRefs, walkTypeRef } from '../ir/types.js';\n\n/**\n * A list-envelope companion that was lifted to one or more inline models:\n * `field` is the envelope field (shared by identity with\n * `Operation.pagination.envelopeFields`), `models[0]` is the companion's own\n * model and the rest are models nested inside it. Every model is named under\n * the operation (`ListUsersListMetadata`); `bareNames[i]` is the name\n * `models[i]` would carry if it were named from its property alone\n * (`ListMetadata`).\n */\nexport interface EnvelopeCompanion {\n field: Field;\n models: Model[];\n bareNames: string[];\n}\n\n/**\n * Decide the final name of every lifted companion model, across all list\n * operations at once, and return the models to merge into the IR.\n *\n * The same envelope recurs on every list endpoint of an API, so naming each\n * copy after its operation would mint one identical `ListMetadata` per\n * endpoint. But naming by property alone is only safe while the copies agree:\n * `mergeInlineResponseModels` keeps the largest model of a name, so a\n * `pagination` with three fields would silently replace an unrelated\n * `Pagination` component, or absorb another endpoint's two-field `pagination`.\n *\n * So a companion takes its bare name only when that cannot change any other\n * type's shape:\n *\n * Copies are compared structurally — field names, requiredness and each\n * field's shape, with nested models resolved and inline enums compared by\n * value — never by name alone. A copy collapses onto a target shape only when\n * the target *admits* every value the copy can hold: the same fields with the\n * same types, where the target may be looser (a field the copy requires may be\n * optional on the target, a non-null copy field may be nullable there) but\n * never stricter. Widening a response type loses no data a reader can see;\n * narrowing it would promise fields the wire may omit.\n *\n * - When a component model of that name exists — compared after the parser's\n * own renaming, so `PaginationDto` → `Pagination` is caught — the copies it\n * admits collapse onto it (the component stays as written); the others keep\n * their operation-qualified name.\n * - Otherwise the most common exact shape (first declared, on a tie) becomes\n * the target: it and every copy it admits take the bare name; any other\n * copy keeps its operation-qualified name.\n *\n * The comparison covers the companion's whole field type, so a `oneOf`\n * companion is judged on every variant, not just the first, and a copy folds\n * among copies only when its lifted models line up name for name with the\n * target's (same variants, same order); onto a component, only a companion\n * whose field references exactly its own lifted model can fold.\n *\n * Only the target's definition survives a collapse. The admitted copies'\n * models are dropped rather than handed to the merge pass, which keeps the\n * first model of a name and would let a stricter copy declared earlier\n * narrow the shared type for everyone; their field references are repointed\n * at the target's models instead.\n *\n * Enums declared inline in a companion stay operation-qualified, exactly like\n * enums declared inline in a parameter.\n */\nexport function resolveEnvelopeCompanionNames(companions: EnvelopeCompanion[], componentModels?: Model[]): Model[] {\n const byBareName = new Map<string, EnvelopeCompanion[]>();\n /** Copies folded onto another definition; their own models are not emitted. */\n const folded = new Set<EnvelopeCompanion>();\n for (const companion of companions) {\n if (companion.models.length === 0) continue;\n const bare = companion.bareNames[0];\n const group = byBareName.get(bare) ?? [];\n group.push(companion);\n byBareName.set(bare, group);\n }\n\n const componentMap = new Map((componentModels ?? []).map((m) => [m.name, m]));\n const localMap = (c: EnvelopeCompanion): Map<string, Model> => new Map(c.models.map((m) => [m.name, m]));\n // A folded copy keeps its own field wrapper and only its references move, so\n // whether the envelope field itself is nullable has no bearing on folding.\n const unwrap = (t: TypeRef): TypeRef => (t.kind === 'nullable' ? t.inner : t);\n\n for (const [bare, group] of byBareName) {\n // What every copy is measured against: a field type, the map its model\n // references resolve through (a component through the other components, a\n // copy through its own models), and the names a folded copy's references\n // are repointed to.\n let folds: (c: EnvelopeCompanion) => boolean;\n let finalNames: string[];\n let owner: EnvelopeCompanion | undefined;\n\n const component = componentMap.get(bare);\n if (component) {\n const targetType: TypeRef = { kind: 'model', name: component.name };\n finalNames = [component.name];\n folds = (c) => {\n // Only a field that references exactly its own lifted model can be\n // repointed at the component; a union of variants has nowhere to go.\n const refs = collectModelRefs(c.field.type);\n if (refs.length !== 1 || refs[0] !== c.models[0].name) return false;\n return typeAdmits(targetType, componentMap, unwrap(c.field.type), localMap(c), new Set());\n };\n } else {\n const counts = new Map<string, { n: number; first: EnvelopeCompanion }>();\n for (const c of group) {\n const key = `${fingerprintType(unwrap(c.field.type), localMap(c), new Set())}|${c.bareNames.join(',')}`;\n const seen = counts.get(key);\n if (seen) seen.n += 1;\n else counts.set(key, { n: 1, first: c });\n }\n let best = { n: 0, first: group[0] };\n for (const entry of counts.values()) if (entry.n > best.n) best = entry;\n owner = best.first;\n finalNames = owner.bareNames;\n const ownerType = unwrap(owner.field.type);\n const ownerMap = localMap(owner);\n const ownerNames = owner.bareNames;\n folds = (c) =>\n c.bareNames.length === ownerNames.length &&\n c.bareNames.every((name, i) => name === ownerNames[i]) &&\n typeAdmits(ownerType, ownerMap, unwrap(c.field.type), localMap(c), new Set());\n }\n\n // Decide every copy before renaming any: renaming the target repoints its\n // nested references to the bare names, which its map no longer resolves.\n const collapsing = group.filter(folds);\n for (const companion of collapsing) {\n renameCompanion(companion, finalNames);\n if (companion !== owner) folded.add(companion);\n }\n }\n\n return companions.filter((c) => !folded.has(c)).flatMap((c) => c.models);\n}\n\n/**\n * Rename a companion's models to `names` (index-aligned with `models`) and\n * repoint every reference, in its field and inside its models.\n */\nfunction renameCompanion(companion: EnvelopeCompanion, names: string[]): void {\n const renames = new Map<string, string>();\n companion.models.forEach((model, i) => {\n const name = names[i];\n if (name !== undefined && model.name !== name) renames.set(model.name, name);\n });\n if (renames.size === 0) return;\n\n const repoint = (ref: TypeRef): void => {\n walkTypeRef(ref, {\n model: (r) => {\n const renamed = renames.get(r.name);\n if (renamed !== undefined) (r as { name: string }).name = renamed;\n },\n });\n };\n repoint(companion.field.type);\n for (const model of companion.models) {\n model.name = renames.get(model.name) ?? model.name;\n for (const field of model.fields) repoint(field.type);\n }\n}\n\n/**\n * Whether `target` admits every value `copy` can hold: the same field names,\n * each field's type admitted (see `typeAdmits`), and no field the target\n * requires that the copy leaves optional. Nested models resolve through their\n * respective maps and are compared the same way; a model neither map resolves\n * is compared by name.\n */\nfunction admits(\n target: Model,\n targetMap: Map<string, Model>,\n copy: Model,\n copyMap: Map<string, Model>,\n visiting: Set<string>,\n): boolean {\n const key = `${target.name}|${copy.name}`;\n if (visiting.has(key)) return true;\n visiting.add(key);\n try {\n if (target.fields.length !== copy.fields.length) return false;\n const targetFields = new Map(target.fields.map((f) => [f.name, f]));\n for (const field of copy.fields) {\n const expected = targetFields.get(field.name);\n if (!expected) return false;\n if (expected.required && !field.required) return false;\n if (!typeAdmits(expected.type, targetMap, field.type, copyMap, visiting)) return false;\n }\n return true;\n } finally {\n visiting.delete(key);\n }\n}\n\n/**\n * Whether `target` admits every value of `copy`'s type. A nullable target\n * admits a nullable or a non-null copy; a non-null target admits only a\n * non-null copy. An enum with known values admits a copy whose values are a\n * subset of its own. Everything else must match exactly, by fingerprint.\n */\nfunction typeAdmits(\n target: TypeRef,\n targetMap: Map<string, Model>,\n copy: TypeRef,\n copyMap: Map<string, Model>,\n visiting: Set<string>,\n): boolean {\n if (target.kind === 'nullable') {\n return typeAdmits(target.inner, targetMap, copy.kind === 'nullable' ? copy.inner : copy, copyMap, visiting);\n }\n if (copy.kind === 'nullable') return false;\n if (target.kind !== copy.kind) return false;\n switch (target.kind) {\n case 'model': {\n const t = targetMap.get(target.name);\n const c = copyMap.get((copy as typeof target).name);\n if (t && c) return admits(t, targetMap, c, copyMap, visiting);\n return target.name === (copy as typeof target).name;\n }\n case 'array':\n return typeAdmits(target.items, targetMap, (copy as typeof target).items, copyMap, visiting);\n case 'enum': {\n const c = copy as typeof target;\n if (target.values && c.values) {\n const allowed = new Set(target.values.map((v) => `${typeof v}:${String(v)}`));\n return c.values.every((v) => allowed.has(`${typeof v}:${String(v)}`));\n }\n return target.name === c.name;\n }\n default:\n return fingerprintType(target, targetMap, new Set()) === fingerprintType(copy, copyMap, new Set());\n }\n}\n\n/**\n * Structural fingerprint of a companion model: field names, requiredness, and\n * each field's shape, with models nested inside the companion compared by\n * shape rather than by (operation-qualified) name, and inline enums compared\n * by their values. Models outside the companion are compared by name.\n */\nfunction fingerprintModel(model: Model, local: Map<string, Model>, visiting: Set<string>): string {\n if (visiting.has(model.name)) return `rec:${model.name}`;\n visiting.add(model.name);\n const fields = [...model.fields]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((f) => `${f.name}${f.required ? '!' : '?'}:${fingerprintType(f.type, local, visiting)}`);\n visiting.delete(model.name);\n return `{${fields.join(',')}}`;\n}\n\nfunction fingerprintType(ref: TypeRef, local: Map<string, Model>, visiting: Set<string>): string {\n switch (ref.kind) {\n case 'primitive':\n return `p:${ref.type}${ref.format ? `:${ref.format}` : ''}`;\n case 'literal':\n return `l:${typeof ref.value}:${String(ref.value)}`;\n case 'nullable':\n return `n<${fingerprintType(ref.inner, local, visiting)}>`;\n case 'array':\n return `a<${fingerprintType(ref.items, local, visiting)}>`;\n case 'map':\n return `m<${ref.keyType ? `${fingerprintType(ref.keyType, local, visiting)},` : ''}${fingerprintType(ref.valueType, local, visiting)}>`;\n case 'union':\n return `u:${ref.compositionKind ?? ''}<${ref.variants\n .map((v) => fingerprintType(v, local, visiting))\n .sort()\n .join(',')}>`;\n case 'enum':\n return ref.values\n ? `e<${[...ref.values]\n .map((v) => `${typeof v}:${String(v)}`)\n .sort()\n .join('|')}>`\n : `e:${ref.name}`;\n case 'model': {\n const nested = local.get(ref.name);\n return nested ? fingerprintModel(nested, local, visiting) : `ref:${ref.name}`;\n }\n default:\n return assertNever(ref);\n }\n}\n","import type {\n Service,\n Operation,\n HttpMethod,\n Parameter,\n ParameterGroup,\n TypeRef,\n ErrorResponse,\n SuccessResponse,\n ResponseHeader,\n Model,\n Field,\n PaginationMeta,\n} from '../ir/types.js';\nimport { createHash } from 'node:crypto';\nimport { toPascalCase, toCamelCase, cleanSchemaName, stripListItemMarkers } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport {\n schemaToTypeRef,\n buildFieldFromSchema,\n nameInlineVariant,\n resolveSchemaName,\n nonEmptyExamples,\n resolveExamples,\n resolveComponentSchemaRef,\n extractConstraints,\n constraintsEntry,\n} from './schemas.js';\nimport { collectProperties, extractInlineModelsFromProperties } from './inline-models.js';\nimport { detectPagination } from './pagination.js';\nimport { classifyAndExtractResponse } from './responses.js';\nimport { extractSecurityRequirements, type RawSecurityRequirements } from './security.js';\nimport { resolveEnvelopeCompanionNames, type EnvelopeCompanion } from './envelope-companion-names.js';\n\ninterface PathItem {\n get?: OperationObject;\n post?: OperationObject;\n put?: OperationObject;\n patch?: OperationObject;\n delete?: OperationObject;\n head?: OperationObject;\n options?: OperationObject;\n trace?: OperationObject;\n parameters?: RawParameterObject[];\n}\n\ninterface ParameterGroupExtension {\n optional: boolean;\n variants: Record<string, string[]>;\n /** Per-variant names that may be omitted when the variant is used. */\n optionalFields?: Record<string, string[]>;\n}\n\ninterface OperationObject {\n operationId?: string;\n summary?: string;\n description?: string;\n tags?: string[];\n parameters?: RawParameterObject[];\n requestBody?: RawRequestBodyObject;\n responses?: Record<string, ResponseObject>;\n deprecated?: boolean;\n 'x-oagen-async'?: boolean;\n security?: RawSecurityRequirements;\n 'x-mutually-exclusive-parameter-groups'?: Record<string, ParameterGroupExtension>;\n 'x-mutually-exclusive-body-groups'?: Record<string, ParameterGroupExtension>;\n}\n\n/**\n * An OAS Example Object, as the entries of a parameter's `examples` map and\n * of `components.examples`. Only `value` is read: a `$ref` entry is first\n * resolved against `components.examples` (see `resolveExampleRef`), and an\n * entry that carries `externalValue` instead has no inline value to surface.\n */\ninterface ExampleObject {\n summary?: string;\n description?: string;\n value?: unknown;\n externalValue?: string;\n $ref?: string;\n}\n\ninterface ParameterObject {\n name: string;\n in: 'path' | 'query' | 'header' | 'cookie';\n required?: boolean;\n description?: string;\n schema?: SchemaObject;\n deprecated?: boolean;\n example?: unknown;\n /** Parameter-level examples: a map of Example Objects, not a JSON Schema list. */\n examples?: Record<string, ExampleObject>;\n style?: string;\n explode?: boolean;\n}\n\n/**\n * A parameter entry as it appears in an operation's (or path item's) raw\n * `parameters` array: either an inline Parameter Object, or a Reference\n * Object (`{ $ref: '#/components/parameters/X' }`). The bundler\n * (`refs.ts`) runs with `dereference: false`, so refs to\n * `components/parameters` are never inlined — they arrive here exactly as\n * written in the spec and must be resolved before use.\n */\ntype RawParameterObject = ParameterObject | { $ref: string };\n\n/**\n * Resolve a raw parameter entry to a concrete Parameter Object, following\n * `$ref`s into `components/parameters` when present. Follows chains of refs\n * (a component that itself is a `$ref` to another component), with a cycle\n * guard for a spec that refs itself.\n *\n * Throws when a `$ref` can't be resolved so a malformed spec fails loudly at\n * parse time instead of silently losing the parameter (see `extractParams`,\n * which used to drop any entry with no `in` field — every `$ref` object has\n * none).\n */\nfunction resolveParameterRef(\n raw: RawParameterObject,\n componentParameters: Record<string, Record<string, unknown>> | undefined,\n operationContext: string,\n): ParameterObject {\n const seenRefs = new Set<string>();\n let current: RawParameterObject = raw;\n\n while ('$ref' in current) {\n if (seenRefs.has(current.$ref)) {\n throw new Error(`Circular parameter $ref chain starting at \"${current.$ref}\" in ${operationContext}.`);\n }\n seenRefs.add(current.$ref);\n\n // Match the whole pointer, not just its last token: a ref into any other\n // section must not resolve off a same-named parameter component.\n const match = /^#\\/components\\/parameters\\/(.+)$/.exec(current.$ref);\n // JSON Pointer escapes (RFC 6901 §4): `~1` -> `/`, then `~0` -> `~`, in that order.\n const refName = match?.[1].replace(/~1/g, '/').replace(/~0/g, '~');\n const resolved = refName ? componentParameters?.[refName] : undefined;\n if (!resolved) {\n throw new Error(\n `Unresolved parameter $ref \"${current.$ref}\" in ${operationContext}: no matching entry under components/parameters.`,\n );\n }\n current = resolved as unknown as RawParameterObject;\n }\n\n return current;\n}\n\ninterface RequestBodyObject {\n required?: boolean;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\n/**\n * A request body as written in the spec: an inline Request Body Object or a\n * Reference Object into `components/requestBodies`. The bundler never inlines\n * those refs (`dereference: false`), so they must be resolved before use.\n */\ntype RawRequestBodyObject = RequestBodyObject | { $ref: string };\n\n/**\n * Resolve a raw request body to a concrete Request Body Object, following\n * `$ref` chains into `components/requestBodies` with a cycle guard. Throws on\n * an unresolvable ref so a malformed spec fails at parse time instead of\n * silently losing the body — and with it the body-ownership rule that keeps\n * duplicated secrets out of the query string.\n */\nfunction resolveRequestBodyRef(\n raw: RawRequestBodyObject | undefined,\n componentRequestBodies: Record<string, Record<string, unknown>> | undefined,\n operationContext: string,\n): RequestBodyObject | undefined {\n if (!raw) return undefined;\n const seenRefs = new Set<string>();\n let current: RawRequestBodyObject = raw;\n\n while ('$ref' in current) {\n if (seenRefs.has(current.$ref)) {\n throw new Error(`Circular request body $ref chain starting at \"${current.$ref}\" in ${operationContext}.`);\n }\n seenRefs.add(current.$ref);\n\n const match = /^#\\/components\\/requestBodies\\/(.+)$/.exec(current.$ref);\n // JSON Pointer escapes (RFC 6901 §4): `~1` -> `/`, then `~0` -> `~`, in that order.\n const refName = match?.[1].replace(/~1/g, '/').replace(/~0/g, '~');\n const resolved = refName ? componentRequestBodies?.[refName] : undefined;\n if (!resolved) {\n throw new Error(\n `Unresolved request body $ref \"${current.$ref}\" in ${operationContext}: no matching entry under components/requestBodies.`,\n );\n }\n current = resolved as unknown as RawRequestBodyObject;\n }\n\n return current;\n}\n\n/**\n * A Header Object as it appears in a Response Object's `headers` map. Per OAS\n * it carries either `schema` or a single-entry `content` map, never both.\n */\ninterface HeaderObject {\n description?: string;\n required?: boolean;\n deprecated?: boolean;\n schema?: SchemaObject;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\n/**\n * A header entry as written in the spec: an inline Header Object or a\n * Reference Object into `components/headers`. The bundler never inlines those\n * refs (`dereference: false`), so they must be resolved before use. In OAS 3.1\n * a Reference Object may carry its own `description`, which overrides the\n * referenced component's.\n */\ntype RawHeaderObject = HeaderObject | { $ref: string; description?: string };\n\n/**\n * Resolve a raw response header to a concrete Header Object, following `$ref`\n * chains into `components/headers` with a cycle guard.\n *\n * Unlike parameters and request bodies, a header that cannot be resolved is\n * warned about and dropped rather than failing the parse: a response header\n * is informational, so losing one costs an emitter a typed accessor, not a\n * wire contract, and should not block generating the rest of the SDK.\n */\nfunction resolveHeaderRef(\n raw: RawHeaderObject,\n componentHeaders: Record<string, Record<string, unknown>> | undefined,\n headerName: string,\n operationContext: string,\n): HeaderObject | undefined {\n const seenRefs = new Set<string>();\n let current: RawHeaderObject = raw;\n // Each ref in a chain overrides whatever it points at, so the outermost\n // sibling `description` wins over any inner one and over the component's.\n let description: string | undefined;\n\n while ('$ref' in current) {\n if (description === undefined && typeof current.description === 'string') description = current.description;\n if (seenRefs.has(current.$ref)) {\n console.warn(\n `[oagen] Warning: Circular header $ref chain starting at \"${current.$ref}\" for response header ` +\n `\"${headerName}\" in ${operationContext}. Skipping the header.`,\n );\n return undefined;\n }\n seenRefs.add(current.$ref);\n\n // Match the whole pointer, not just its last token: a ref into any other\n // section must not resolve off a same-named header component.\n const match = /^#\\/components\\/headers\\/(.+)$/.exec(current.$ref);\n // JSON Pointer escapes (RFC 6901 §4): `~1` -> `/`, then `~0` -> `~`, in that order.\n const refName = match?.[1].replace(/~1/g, '/').replace(/~0/g, '~');\n const resolved = refName ? componentHeaders?.[refName] : undefined;\n if (!resolved) {\n console.warn(\n `[oagen] Warning: Unresolved header $ref \"${current.$ref}\" for response header \"${headerName}\" ` +\n `in ${operationContext}: no matching entry under components/headers. Skipping the header.`,\n );\n return undefined;\n }\n current = resolved as unknown as RawHeaderObject;\n }\n\n return description === undefined ? current : { ...current, description };\n}\n\ninterface ResponseObject {\n description?: string;\n headers?: Record<string, RawHeaderObject>;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\nexport interface OperationExtractionResult {\n services: Service[];\n inlineModels: Model[];\n}\n\n/** A top-level `tags[]` entry as it appears in the OpenAPI document. */\nexport interface TagObject {\n name?: string;\n description?: string;\n}\n\nexport function extractOperations(\n paths: Record<string, PathItem> | undefined,\n operationIdTransform?: (id: string) => string,\n componentSchemas?: Record<string, SchemaObject>,\n componentParameters?: Record<string, Record<string, unknown>>,\n componentRequestBodies?: Record<string, Record<string, unknown>>,\n componentModels?: Model[],\n documentTags?: TagObject[],\n componentExamples?: Record<string, Record<string, unknown>>,\n componentHeaders?: Record<string, Record<string, unknown>>,\n): OperationExtractionResult {\n if (!paths) return { services: [], inlineModels: [] };\n\n // Operations without an operationId name their inline models from the\n // path, and two distinct paths — or a path and an operationId or component\n // schema — can produce the same name, so the prefix for every such\n // operation is decided up front (see resolvePathModelBaseNames).\n const pathModelBaseNames = resolvePathModelBaseNames(paths, componentModels, componentRequestBodies);\n\n const serviceMap = new Map<string, Operation[]>();\n const inlineModels: Model[] = [];\n const envelopeCompanions: EnvelopeCompanion[] = [];\n // Service name each tagged operation was grouped under, keyed by operation\n // identity. The path-prefix split below moves operations between services,\n // so this is how a split-off service is traced back to the tag it came from.\n const tagServiceByOperation = new Map<Operation, string>();\n // One registry for the whole spec, seeded with the component models: a\n // header model's name must not collide with a differently shaped component\n // (a request body may already use `DocumentsXMeta`) or with another\n // operation's header model, or the later merge would overwrite the first.\n const headerModelRegistry: HeaderModelRegistry = new Map(\n (componentModels ?? []).map((model) => [model.name, { fingerprint: modelFingerprint(model) }]),\n );\n\n for (const [path, pathItem] of Object.entries(paths)) {\n const pathLevelParams = pathItem.parameters ?? [];\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const tag = op.tags?.[0];\n const serviceName = inferServiceName(path, tag);\n const pathModelBaseName = pathModelBaseNames.get(`${method} ${path}`) ?? derivePathModelBaseName(path, method);\n\n const {\n operation,\n inlineModels: opModels,\n envelopeCompanions: opCompanions,\n } = buildOperation(\n method,\n path,\n op,\n pathLevelParams,\n pathModelBaseName,\n operationIdTransform,\n serviceName,\n componentSchemas,\n componentParameters,\n componentRequestBodies,\n componentExamples,\n componentHeaders,\n headerModelRegistry,\n );\n inlineModels.push(...opModels);\n if (opCompanions) envelopeCompanions.push(...opCompanions);\n // Same truthiness check as inferServiceName: for a tagged operation the\n // service name *is* the normalized tag, so it doubles as the lookup key.\n if (tag) tagServiceByOperation.set(operation, serviceName);\n const ops = serviceMap.get(serviceName) ?? [];\n ops.push(operation);\n serviceMap.set(serviceName, ops);\n }\n }\n\n // Companion models of list envelopes are named once every list operation is\n // known, so copies of one envelope shape can share a model.\n inlineModels.push(...resolveEnvelopeCompanionNames(envelopeCompanions, componentModels));\n\n // Split services when a single tag groups operations from multiple path prefixes.\n // Example: /organizations and /organization_domains both tagged \"organizations\"\n // should become separate services based on their first path segment.\n for (const [serviceName, operations] of serviceMap) {\n const pathGroups = new Map<string, Operation[]>();\n for (const op of operations) {\n const firstSeg = op.path.split('/').filter(Boolean)[0] ?? '';\n const groupKey = firstSeg.startsWith('{') ? serviceName : toPascalCase(firstSeg);\n const group = pathGroups.get(groupKey) ?? [];\n group.push(op);\n pathGroups.set(groupKey, group);\n }\n // Only split if there are multiple distinct path-prefix groups AND\n // at least one group name differs from the current service name\n if (pathGroups.size > 1) {\n const needsSplit = [...pathGroups.keys()].some((k) => k !== serviceName);\n if (needsSplit) {\n serviceMap.delete(serviceName);\n for (const [groupName, groupOps] of pathGroups) {\n const existing = serviceMap.get(groupName) ?? [];\n existing.push(...groupOps);\n serviceMap.set(groupName, existing);\n }\n }\n }\n }\n\n // Disambiguate operation names within each service.\n // Multiple operations can get the same name (e.g., several \"list\" endpoints\n // in UserManagement for users, invitations, auth factors, etc.).\n for (const [, operations] of serviceMap) {\n disambiguateOperationNames(operations);\n }\n\n const declaredTags = indexDocumentTags(documentTags);\n const services: Service[] = Array.from(serviceMap.entries()).map(([name, operations]) => {\n const description = resolveServiceDescription(name, operations, tagServiceByOperation, declaredTags);\n // Omit the key entirely when no tag describes the service so the IR shape\n // is unchanged for documents without tag descriptions.\n return description === undefined ? { name, operations } : { name, description, operations };\n });\n\n return { services, inlineModels };\n}\n\n/**\n * Index the document's top-level `tags[]` by the service name each tag\n * produces, so a tag spelled `user_management`, `User Management`, or\n * `user-management` all map to the `UserManagement` service. Every named tag\n * is indexed — with its description when it declares a non-blank one, and\n * `undefined` otherwise — because a declared-but-undescribed tag still marks\n * its service as one that must not borrow another tag's wording. When several\n * tags normalize to the same service name, the first described one wins.\n *\n * `parseSpec` ignored `tags` entirely before descriptions were read, so a\n * document with a malformed value — `tags` written as an object, a `null`\n * entry, a numeric `name` — used to parse and must keep parsing. Anything\n * that cannot be matched is skipped rather than thrown on.\n */\nfunction indexDocumentTags(documentTags: unknown): Map<string, string | undefined> {\n const index = new Map<string, string | undefined>();\n if (!Array.isArray(documentTags)) return index;\n for (const tag of documentTags as unknown[]) {\n if (typeof tag !== 'object' || tag === null) continue;\n const { name, description } = tag as TagObject;\n if (typeof name !== 'string' || name === '') continue;\n const serviceName = toPascalCase(name);\n if (index.get(serviceName) !== undefined) continue;\n const described = typeof description === 'string' && description.trim() !== '';\n index.set(serviceName, described ? description : undefined);\n }\n return index;\n}\n\n/**\n * Pick a service's description from the document's tags.\n *\n * A service whose own name is a declared tag is described by that tag alone:\n * its description when it has one, nothing otherwise. Another tag's wording is\n * never borrowed for it — operations tagged `api_keys` that the path-prefix\n * split merges into `UserManagement` must not label that service \"API keys\".\n *\n * A service whose own name is not declared is one the split carved out of a\n * tag (e.g. `OrganizationDomains` from operations tagged `organizations`); it\n * inherits the description of the first described tag its operations carry.\n * Path-named services whose operations have no tag carry nothing and stay\n * undescribed.\n */\nfunction resolveServiceDescription(\n serviceName: string,\n operations: Operation[],\n tagServiceByOperation: Map<Operation, string>,\n declaredTags: Map<string, string | undefined>,\n): string | undefined {\n if (declaredTags.has(serviceName)) return declaredTags.get(serviceName);\n for (const op of operations) {\n const tagService = tagServiceByOperation.get(op);\n if (tagService === undefined) continue;\n const description = declaredTags.get(tagService);\n if (description !== undefined) return description;\n }\n return undefined;\n}\n\nfunction inferServiceName(path: string, tag?: string): string {\n // Prefer OpenAPI tag when available — tags represent the logical grouping\n // (e.g., \"multi-factor-auth\" for /auth/factors/* endpoints).\n if (tag) {\n return toPascalCase(tag);\n }\n // Fallback: extract first meaningful path segment: /widgets/{id}/sub → \"Widgets\"\n const segments = path.split('/').filter(Boolean);\n const first = segments[0] ?? 'Default';\n // Skip path params\n if (first.startsWith('{')) return 'Default';\n return toPascalCase(first);\n}\n\n/**\n * Strip overload indices (e.g. NestJS emits `Foo_bar[0]` when a controller\n * method handles multiple routes) from an operationId so derived names never\n * leak the bracketed digit. Without this, `authenticate[0]` would surface as\n * `authenticate0` in method names and `Authenticate0Request` in body model\n * names. Brackets at the end (or with trailing whitespace) are common in\n * NestJS-style backends; this regex is intentionally narrow to avoid eating\n * legitimate digits like `oauth2`.\n */\nfunction normalizeOperationIdForNaming(operationId: string): string {\n return operationId.replace(/\\[\\d+\\]\\s*$/, '');\n}\n\n/**\n * The inline request body or response model name of an operation that has an\n * `operationId`. The single source of that name: extractRequestBody and\n * deriveResponseName use it to name, resolvePathModelBaseNames to reserve.\n */\nfunction operationIdModelName(operationId: string, suffix: 'Request' | 'Response'): string {\n return cleanSchemaName(toPascalCase(normalizeOperationIdForNaming(operationId)) + suffix);\n}\n\n/**\n * The stem every model derived from an `operationId` starts with: its\n * `Request` and `Response` models, a list's `Item`, nested inline models under\n * those (`…ResponseOwner`) and envelope companions (`…ListMetadata`). Every\n * step of cleanSchemaName is a global replace or acts on the leading word, so\n * this is a true prefix of each of those names. Used to reserve them all.\n */\nfunction operationIdModelBase(operationId: string): string {\n return cleanSchemaName(toPascalCase(normalizeOperationIdForNaming(operationId)));\n}\n\nfunction inferOperationName(\n method: HttpMethod,\n path: string,\n operationId?: string,\n operationIdTransform?: (id: string) => string,\n): string {\n if (operationId) {\n const normalized = normalizeOperationIdForNaming(operationId);\n if (operationIdTransform) {\n return operationIdTransform(normalized);\n }\n return toCamelCase(normalized);\n }\n\n // Fallback when no operationId is available — use method + path to build\n // a descriptive name like \"listUsers\", \"getOrganization\", \"deleteAuthFactor\"\n const verb = inferVerb(method, path);\n const resource = inferResourceFromPath(path);\n return resource ? toCamelCase(`${verb}_${resource}`) : verb;\n}\n\n/**\n * Infer the CRUD verb from HTTP method and path shape.\n */\nfunction inferVerb(method: HttpMethod, path: string): string {\n const segments = path.split('/').filter(Boolean);\n const hasTrailingParam = segments.length > 0 && segments[segments.length - 1].startsWith('{');\n\n switch (method) {\n case 'get':\n return hasTrailingParam ? 'get' : 'list';\n case 'post':\n return 'create';\n case 'put':\n case 'patch':\n return 'update';\n case 'delete':\n return 'delete';\n case 'head':\n return 'check';\n case 'options':\n return 'options';\n case 'trace':\n return 'trace';\n default:\n return method;\n }\n}\n\n/**\n * Extract a resource noun from the path for operation naming.\n * Uses the last non-param segment (the resource being operated on).\n *\n * Examples:\n * /accounts/users → \"Users\"\n * /accounts/users/{id} → \"User\" (singular for item operations)\n * /accounts/users/{id}/auth_factors → \"AuthFactors\"\n * /organizations/{id}/api_keys → \"ApiKeys\"\n * /auth/authorize → \"Authorize\" (action endpoint)\n */\nfunction inferResourceFromPath(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n if (segments.length <= 1) return null;\n\n // Find the last meaningful (non-param) segment\n let resourceSegment: string | null = null;\n for (let i = segments.length - 1; i >= 0; i--) {\n if (!segments[i].startsWith('{')) {\n resourceSegment = segments[i];\n break;\n }\n }\n\n if (!resourceSegment) return null;\n // Skip the service name (first segment) — it would be redundant\n if (resourceSegment === segments[0]) return null;\n\n return toPascalCase(resourceSegment);\n}\n\n/**\n * Detect and resolve name collisions within a service's operations.\n *\n * When multiple operations share the same name (e.g., several \"list\" from\n * different sub-resources), disambiguate by appending the resource noun\n * from the path. Only renames operations on DIFFERENT paths — same-name\n * operations on the same path (e.g., PUT + PATCH both \"update\") are left as-is\n * since they represent the same logical resource.\n */\nfunction disambiguateOperationNames(operations: Operation[]): void {\n // Group by name\n const byName = new Map<string, Operation[]>();\n for (const op of operations) {\n const group = byName.get(op.name) ?? [];\n group.push(op);\n byName.set(op.name, group);\n }\n\n for (const [name, group] of byName) {\n if (group.length <= 1) continue;\n\n // Check if these are genuinely different resources (different paths)\n // vs the same resource with different methods (PUT + PATCH)\n const uniquePaths = new Set(group.map((op) => op.path));\n if (uniquePaths.size <= 1) continue; // same path, different methods — no disambiguation needed\n\n for (const op of group) {\n const resource = inferResourceFromPath(op.path);\n if (resource) {\n const newName = toCamelCase(`${name}_${resource}`);\n (op as { name: string }).name = newName;\n }\n }\n\n // If disambiguation still left collisions (same sub-resource),\n // use the full distinguishing path segment chain\n const renamed = new Map<string, Operation[]>();\n for (const op of group) {\n const rGroup = renamed.get(op.name) ?? [];\n rGroup.push(op);\n renamed.set(op.name, rGroup);\n }\n for (const [, rGroup] of renamed) {\n if (rGroup.length <= 1) continue;\n // Still colliding — different paths map to same resource name.\n // Use deeper path context to disambiguate.\n for (const op of rGroup) {\n const deeper = inferDeeperContext(op.path);\n if (deeper) {\n (op as { name: string }).name = toCamelCase(`${op.name}_${deeper}`);\n }\n }\n }\n }\n}\n\n/**\n * Extract a deeper disambiguation context from the path when the last\n * segment isn't unique enough. Uses the second-to-last non-param segment.\n *\n * /users/{id}/auth_factors → already captured as \"AuthFactors\"\n * /users/external_id/{external_id} → \"ExternalId\" (special path, not a sub-resource)\n */\nfunction inferDeeperContext(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n const nonParams = segments.filter((s) => !s.startsWith('{'));\n // Skip first (service) and last (already used) — use the middle ones\n if (nonParams.length >= 3) {\n return toPascalCase(nonParams.slice(1, -1).join('_'));\n }\n return null;\n}\n\n/**\n * Extract mutually-exclusive parameter groups from the `x-mutually-exclusive-parameter-groups`\n * operation extension. Cross-references grouped parameter names against the already-extracted\n * IR parameter arrays so emitters get object-identity references.\n */\nfunction extractParameterGroups(\n op: OperationObject,\n allIRParams: Parameter[],\n operationContext: string,\n): ParameterGroup[] | undefined {\n const raw = op['x-mutually-exclusive-parameter-groups'];\n if (!raw || typeof raw !== 'object') return undefined;\n\n const paramByName = new Map<string, Parameter>();\n for (const p of allIRParams) {\n paramByName.set(p.name, p);\n }\n\n const groups: ParameterGroup[] = [];\n\n for (const [groupName, groupDef] of Object.entries(raw)) {\n if (!groupDef || typeof groupDef !== 'object') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: expected an object with \"optional\" and \"variants\".`,\n );\n }\n\n if (typeof groupDef.optional !== 'boolean') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.optional in ${operationContext}: expected a boolean.`,\n );\n }\n\n if (!groupDef.variants || typeof groupDef.variants !== 'object') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants in ${operationContext}: expected an object mapping variant names to parameter name arrays.`,\n );\n }\n\n if (Object.keys(groupDef.variants).length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: group has zero variants.`,\n );\n }\n\n const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n if (!Array.isArray(paramNames) || paramNames.length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n );\n }\n const parameters: Parameter[] = paramNames.map((pName) => {\n const irParam = paramByName.get(pName);\n if (!irParam) {\n throw new Error(\n `x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} references parameter \"${pName}\" which does not exist in the operation's parameters[] (${operationContext}).`,\n );\n }\n return irParam;\n });\n return { name: variantName, parameters };\n });\n\n groups.push({\n name: groupName,\n optional: groupDef.optional,\n variants,\n });\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\n/**\n * Extract mutually-exclusive body parameter groups from the\n * `x-mutually-exclusive-body-groups` operation extension. Unlike query\n * parameter groups (whose parameters live in operation.queryParams), body\n * group parameters are synthetic — built from the oneOf variant schemas in\n * the request body. Emitters use the group's presence to generate sum-type\n * interfaces and custom JSON marshalling instead of flat optional fields.\n */\nfunction extractBodyParameterGroups(\n op: OperationObject,\n requestBody: RequestBodyObject | undefined,\n operationContext: string,\n componentSchemas?: Record<string, SchemaObject>,\n): ParameterGroup[] | undefined {\n const raw = op['x-mutually-exclusive-body-groups'];\n if (!raw || typeof raw !== 'object') return undefined;\n\n // Collect the body schema's oneOf variant fields so we can resolve types.\n // The body schema has been structurally rewritten to allOf: [base, { oneOf: [...] }]\n // by the spec generator; the variant properties live inside oneOf branches.\n const bodySchema = requestBody?.content?.['application/json']?.schema;\n const variantFieldSchemas = collectVariantFieldSchemas(bodySchema, componentSchemas);\n\n const groups: ParameterGroup[] = [];\n\n for (const [groupName, groupDef] of Object.entries(raw)) {\n if (!groupDef || typeof groupDef !== 'object') continue;\n if (typeof groupDef.optional !== 'boolean') continue;\n if (!groupDef.variants || typeof groupDef.variants !== 'object') continue;\n if (Object.keys(groupDef.variants).length === 0) continue;\n\n const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n if (!Array.isArray(paramNames) || paramNames.length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n );\n }\n const parameters: Parameter[] = paramNames.map((pName) => {\n const entry = variantFieldSchemas.get(pName);\n const fieldSchema = entry?.schema;\n // No schema found means the body's oneOf branches don't declare this\n // member. Falling back to `string` silently produces an SDK that\n // type-checks against itself but misrepresents the wire contract\n // (object-valued members become plain strings), so say so loudly.\n if (!fieldSchema) {\n console.warn(\n `[oagen] Warning: x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} ` +\n `references \"${pName}\" in ${operationContext}, but no oneOf branch of the request body ` +\n `declares that property. Falling back to type: string.`,\n );\n }\n const fieldType: TypeRef = fieldSchema\n ? schemaToTypeRef(fieldSchema, toPascalCase(pName), entry?.owner)\n : { kind: 'primitive', type: 'string' };\n return {\n name: pName,\n type: fieldType,\n required: false, // group variant fields are always optional at the struct level\n description: fieldSchema?.description,\n };\n });\n\n // Optional variant membership: fields the caller may omit when using\n // this variant. Only names that actually belong to the variant count —\n // anything else in the extension is ignored rather than fatal.\n const rawOptionalFields =\n groupDef.optionalFields && typeof groupDef.optionalFields === 'object'\n ? groupDef.optionalFields[variantName]\n : undefined;\n const optionalParameters = Array.isArray(rawOptionalFields)\n ? rawOptionalFields.filter((name): name is string => typeof name === 'string' && paramNames.includes(name))\n : [];\n\n return {\n name: variantName,\n parameters,\n ...(optionalParameters.length > 0 ? { optionalParameters } : {}),\n };\n });\n\n groups.push({\n name: groupName,\n optional: groupDef.optional,\n variants,\n });\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\nfunction buildOperation(\n method: HttpMethod,\n path: string,\n op: OperationObject,\n pathLevelParams: RawParameterObject[],\n pathModelBaseName: string,\n operationIdTransform?: (id: string) => string,\n serviceName?: string,\n componentSchemas?: Record<string, SchemaObject>,\n componentParameters?: Record<string, Record<string, unknown>>,\n componentRequestBodies?: Record<string, Record<string, unknown>>,\n componentExamples?: Record<string, Record<string, unknown>>,\n componentHeaders?: Record<string, Record<string, unknown>>,\n headerModelRegistry: HeaderModelRegistry = new Map(),\n): { operation: Operation; inlineModels: Model[]; envelopeCompanions?: EnvelopeCompanion[] } {\n const opLabel = operationLabel(op, path, method);\n const operationName = inferOperationName(method, path, op.operationId, operationIdTransform);\n // Resolve a `components/requestBodies` ref up front so body extraction, body\n // parameter groups, and the body-ownership rule below all read one object.\n const requestBodyObject = resolveRequestBodyRef(op.requestBody, componentRequestBodies, opLabel);\n // An operation-level parameter overrides a path-level one with the same\n // (name, in) identity rather than adding a second entry. Operation params come\n // last, so last-write-wins; Map.set keeps the original insertion position, so\n // path-level parameter ordering is preserved.\n const paramsByIdentity = new Map<string, ParameterObject>();\n for (const raw of [...pathLevelParams, ...(op.parameters ?? [])]) {\n const param = resolveParameterRef(raw, componentParameters, opLabel);\n paramsByIdentity.set(`${param.in}:${param.name}`, param);\n }\n const allParams = [...paramsByIdentity.values()];\n\n const hasIdempotencyHeader = allParams.some((p) => p.in === 'header' && p.name.toLowerCase() === 'idempotency-key');\n\n // A parameter the spec declares both as `in: query` and as a request-body\n // property is one value with two wire locations. On a body-carrying method\n // it travels in the body only: duplicating it into the URL puts body-grade\n // material (OAuth codes, client secrets) into access logs and exception\n // traces, and emitters that surface both copies grow a second public\n // parameter for the same field. RFC 6749 §4.1.3 puts token-request\n // parameters in the body for the same reason. GET/DELETE keep every\n // declared query parameter — they have no body to prefer.\n //\n // One carve-out: a query parameter named by `x-mutually-exclusive-parameter-groups`\n // stays a parameter. The extension models it as one, the group resolver\n // below looks it up in the parameter arrays, and emitters already route\n // groups into the body on body-carrying methods, so nothing reaches the URL.\n const groupedQueryNames = collectParameterGroupMemberNames(op);\n const bodyOwnedNames = new Set<string>();\n if (BODY_CARRYING_METHODS.has(method)) {\n const bodySchema = selectRequestBodyContent(requestBodyObject).schema;\n for (const name of collectBodyPropertyNames(bodySchema, componentSchemas)) {\n if (!groupedQueryNames.has(name)) bodyOwnedNames.add(name);\n }\n }\n const wireParams =\n bodyOwnedNames.size > 0 ? allParams.filter((p) => !(p.in === 'query' && bodyOwnedNames.has(p.name))) : allParams;\n\n // Use the service name as context so inline parameter enums get qualified\n // names. e.g., service \"Auth\" + param \"provider\" → \"AuthProvider\".\n const opContext = serviceName;\n const pathParams = extractParams(wireParams, 'path', opContext, componentSchemas, componentExamples, opLabel);\n const queryParams = extractParams(wireParams, 'query', opContext, componentSchemas, componentExamples, opLabel);\n const headerParams = extractParams(\n wireParams,\n 'header',\n opContext,\n componentSchemas,\n componentExamples,\n opLabel,\n ).filter((p) => p.name.toLowerCase() !== 'idempotency-key');\n const cookieParams = extractParams(wireParams, 'cookie', opContext, componentSchemas, componentExamples, opLabel);\n // Keep the body-owned declarations on the operation so downstream passes\n // (inline-enum collection, the compat surface) still see what the spec\n // declared, even though no emitter serializes them to the URL.\n const bodyOwnedQueryParams =\n bodyOwnedNames.size > 0\n ? extractParams(\n allParams.filter((p) => p.in === 'query' && bodyOwnedNames.has(p.name)),\n 'query',\n opContext,\n componentSchemas,\n componentExamples,\n opLabel,\n )\n : [];\n\n const reqBodyModels: Model[] = [];\n const { body: requestBody, encoding: requestBodyEncoding } = extractRequestBody(\n requestBodyObject,\n op,\n pathModelBaseName,\n reqBodyModels,\n componentSchemas,\n );\n const {\n response,\n responseHeaders,\n successResponses,\n errors,\n inlineModels,\n isPaginated,\n dataPath: responseDataPath,\n itemType: responseItemType,\n envelopeFields,\n envelopeCompanions,\n } = extractResponses(op.responses, op, pathModelBaseName, path, method, componentSchemas, {\n componentHeaders,\n componentSchemas,\n serviceName: opContext,\n operationQualifier: toPascalCase(operationName),\n registry: headerModelRegistry,\n });\n inlineModels.push(...reqBodyModels);\n\n // Build structured pagination metadata from response classification and query param detection\n const paginationFromParams = detectPagination(response, queryParams, responseDataPath);\n let pagination: PaginationMeta | undefined;\n if (isPaginated) {\n const itemType = responseItemType ?? (response.kind === 'array' ? response.items : response);\n pagination = {\n strategy: paginationFromParams?.strategy ?? 'cursor',\n param: paginationFromParams?.param ?? 'after',\n limitParam: paginationFromParams?.limitParam,\n dataPath: responseDataPath ?? paginationFromParams?.dataPath,\n itemType,\n envelopeFields,\n };\n } else if (paginationFromParams) {\n pagination = paginationFromParams;\n }\n\n // Per-operation security requirements; undefined means \"inherit ApiSpec.security\"\n const security = extractSecurityRequirements(op.security, opLabel);\n\n // Extract mutually-exclusive parameter groups (query/path/header/cookie)\n const allIRParams = [...pathParams, ...queryParams, ...headerParams, ...cookieParams];\n const queryParamGroups = extractParameterGroups(op, allIRParams, opLabel);\n\n // Extract mutually-exclusive body parameter groups\n const bodyParamGroups = extractBodyParameterGroups(op, requestBodyObject, opLabel, componentSchemas);\n\n // Merge both sources into a single parameterGroups array\n const parameterGroups =\n queryParamGroups || bodyParamGroups ? [...(queryParamGroups ?? []), ...(bodyParamGroups ?? [])] : undefined;\n\n // An empty or whitespace-only summary counts as absent, so it neither gets\n // its own field nor leaks into the description as a blank first paragraph.\n const summary = presentText(op.summary);\n\n return {\n operation: {\n name: operationName,\n // Keep the summary on its own so emitters can tell it apart from the\n // description; the key is omitted (not set to undefined) when absent.\n ...(summary !== undefined ? { summary } : {}),\n description: buildDescription(summary, op.description),\n httpMethod: method,\n path,\n pathParams,\n queryParams,\n bodyOwnedQueryParams: bodyOwnedQueryParams.length > 0 ? bodyOwnedQueryParams : undefined,\n headerParams,\n cookieParams: cookieParams.length > 0 ? cookieParams : undefined,\n requestBody,\n requestBodyEncoding,\n response,\n // Added only when present so operations without headers keep their shape.\n ...(responseHeaders && { responseHeaders }),\n successResponses,\n errors,\n pagination,\n injectIdempotencyKey: hasIdempotencyHeader,\n deprecated: op.deprecated || undefined,\n async: op['x-oagen-async'],\n security,\n parameterGroups,\n },\n inlineModels,\n envelopeCompanions,\n };\n}\n\n/**\n * Combine an operation's `summary` and `description` into one doc text.\n * Empty or whitespace-only text counts as absent, so `summary: \"List pets\"`\n * with `description: \"\"` yields `\"List pets\"` rather than `\"\"`. Text that has\n * content is kept verbatim, surrounding whitespace included.\n */\nfunction buildDescription(summary: string | undefined, description: string | undefined): string | undefined {\n const presentSummary = presentText(summary);\n const presentDescription = presentText(description);\n if (presentSummary && presentDescription && presentSummary !== presentDescription) {\n return `${presentSummary}\\n\\n${presentDescription}`;\n }\n return presentDescription ?? presentSummary;\n}\n\n/** The text itself when it has non-whitespace content, otherwise `undefined`. */\nfunction presentText(text: string | undefined): string | undefined {\n return typeof text === 'string' && text.trim() !== '' ? text : undefined;\n}\n\nfunction extractParams(\n params: ParameterObject[],\n location: 'path' | 'query' | 'header' | 'cookie',\n operationContext?: string,\n componentSchemas?: Record<string, SchemaObject>,\n componentExamples?: Record<string, Record<string, unknown>>,\n opLabel?: string,\n): Parameter[] {\n return params\n .filter((p) => p.in === location)\n .map((p) => {\n const refTarget = resolveComponentSchemaRef(p.schema, componentSchemas);\n // Each level is resolved on its own — the parameter's declaration, its\n // inline schema, then the component the schema refs — so a schema-level\n // `example` can't mask the parameter's own `examples` map, and an\n // explicit `null` at any level is kept rather than fallen through.\n const { example, examples } = resolveExamples([\n {\n example: p.example,\n examples: exampleObjectValues(\n p.examples,\n componentExamples,\n `parameter \"${p.name}\" in ${opLabel ?? location}`,\n ),\n },\n { example: p.schema?.example, examples: nonEmptyExamples(p.schema?.examples) },\n { example: refTarget?.example, examples: nonEmptyExamples(refTarget?.examples) },\n ]);\n // Like default/example, fall back per value: the `$ref` target's keywords\n // sit under the parameter's own, so `{ $ref: Limit, minimum: 5 }` narrows\n // one bound without discarding the target's others. The alias also becomes\n // a fieldless model, but a parameter should be readable on its own.\n const own = p.schema ? extractConstraints(p.schema) : undefined;\n const inherited = refTarget ? extractConstraints(refTarget) : undefined;\n const constraints = own && inherited ? { ...inherited, ...own } : (own ?? inherited);\n return {\n name: p.name,\n type: p.schema\n ? schemaToTypeRef(p.schema, p.name, operationContext ? toPascalCase(operationContext) : undefined)\n : ({ kind: 'primitive', type: 'string' } as TypeRef),\n required: p.required ?? false,\n description: firstDescription(p.description, p.schema?.description, refTarget?.description),\n deprecated: p.deprecated || p.schema?.deprecated || refTarget?.deprecated || undefined,\n default: p.schema?.default ?? refTarget?.default,\n example,\n ...(examples ? { examples } : {}),\n style: p.style as Parameter['style'],\n explode: p.explode,\n ...(constraints ? { constraints } : {}),\n };\n });\n}\n\n/**\n * First non-empty description in precedence order. A parameter that declares\n * `description: \"\"` is treated as undocumented so its schema's text still\n * surfaces, and the result is `undefined` rather than `\"\"` when nothing in\n * the chain is documented.\n */\nfunction firstDescription(...candidates: Array<string | undefined>): string | undefined {\n return candidates.find((candidate) => typeof candidate === 'string' && candidate.length > 0);\n}\n\n/**\n * Flatten a parameter's `examples` map of Example Objects to the inline\n * values it carries, in document order. A `$ref` entry is resolved against\n * `components.examples` first (see `resolveExampleRef`). Entries that point\n * elsewhere (`externalValue`) or have no `value` are skipped; `null` is a\n * legitimate value and kept. Returns undefined when nothing remains so the\n * caller can fall through to the schema's `examples`.\n */\nfunction exampleObjectValues(\n examples: Record<string, ExampleObject> | undefined,\n componentExamples: Record<string, Record<string, unknown>> | undefined,\n context: string,\n): unknown[] | undefined {\n if (!examples || typeof examples !== 'object' || Array.isArray(examples)) return undefined;\n const values: unknown[] = [];\n for (const raw of Object.values(examples)) {\n const entry = resolveExampleRef(raw, componentExamples, context);\n if (!entry || typeof entry !== 'object') continue;\n if (entry.externalValue !== undefined || entry.value === undefined) continue;\n values.push(entry.value);\n }\n return values.length > 0 ? values : undefined;\n}\n\n/**\n * Follow an Example Object's `$ref` into `components.examples`, including a\n * component that is itself a `$ref`, with a cycle guard. The bundler keeps\n * refs (`dereference: false`), so without this every `$ref` entry would be\n * dropped and a map made only of refs would silently yield nothing — the\n * parameter would then take its `examples` from the schema instead of the\n * values the document points at. A ref that can't be resolved is skipped\n * with a warning rather than failing the parse: a missing example is a doc\n * gap, not a broken API surface.\n */\nfunction resolveExampleRef(\n raw: ExampleObject | undefined,\n componentExamples: Record<string, Record<string, unknown>> | undefined,\n context: string,\n): ExampleObject | undefined {\n const seenRefs = new Set<string>();\n let current = raw;\n while (current && typeof current === 'object' && current.$ref !== undefined) {\n const ref = current.$ref;\n if (seenRefs.has(ref)) {\n console.warn(`[oagen] Warning: Circular example $ref chain starting at \"${ref}\" on ${context}; skipping`);\n return undefined;\n }\n seenRefs.add(ref);\n const match = /^#\\/components\\/examples\\/(.+)$/.exec(ref);\n // JSON Pointer escapes (RFC 6901 §4): `~1` -> `/`, then `~0` -> `~`, in that order.\n const refName = match?.[1].replace(/~1/g, '/').replace(/~0/g, '~');\n const resolved = refName ? componentExamples?.[refName] : undefined;\n if (!resolved) {\n console.warn(`[oagen] Warning: Unresolved example $ref \"${ref}\" on ${context}; skipping`);\n return undefined;\n }\n current = resolved as ExampleObject;\n }\n return current;\n}\n\n/**\n * Collect the property schemas of every `oneOf` branch reachable from a request\n * body schema, keyed by property name. These are the candidate members of a\n * mutually-exclusive body group.\n *\n * The bundler runs with `dereference: false`, so the body schema is very often\n * a bare `{ $ref: '#/components/schemas/XDto' }` and the `allOf`/`oneOf`\n * composition that actually declares the variant properties lives on the\n * component. Walking without resolving refs finds nothing, and every group\n * member then falls back to `string` — an SDK that compiles but types\n * object-valued members (e.g. a connection's `saml_options`) as plain strings.\n *\n * Composition keywords nest and may themselves be refs, so resolve and recurse\n * at each level. `seen` guards against a schema that (directly or transitively)\n * refs itself.\n */\nfunction collectVariantFieldSchemas(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n owner: string | undefined = undefined,\n out: Map<string, VariantFieldSchema> = new Map(),\n seen: Set<string> = new Set(),\n): Map<string, VariantFieldSchema> {\n if (!schema) return out;\n\n const ref = (schema as { $ref?: string }).$ref;\n if (ref) {\n if (seen.has(ref)) return out;\n seen.add(ref);\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n const target = match && componentSchemas ? componentSchemas[match[1]] : undefined;\n // Descending into a component makes it the owner of everything below, so\n // inline members get the same synthesized names the model emitter gives\n // them (`CreateUser` + `password_hash_type` -> CreateUserPasswordHashType).\n const nextOwner = match ? resolveSchemaName(match[1]) : owner;\n return collectVariantFieldSchemas(target, componentSchemas, nextOwner, out, seen);\n }\n\n // A `oneOf` branch is the group-variant carrier: its properties are the\n // members. Record them, then keep descending — branches nest in real specs.\n for (const variant of schema.oneOf ?? []) {\n const variantRef = (variant as { $ref?: string }).$ref;\n const refMatch = variantRef ? /^#\\/components\\/schemas\\/(.+)$/.exec(variantRef) : null;\n const resolved = resolveSchemaRefObject(variant, componentSchemas) ?? variant;\n const variantOwner = refMatch ? resolveSchemaName(refMatch[1]) : owner;\n for (const [name, fieldSchema] of Object.entries(resolved.properties ?? {})) {\n if (fieldSchema) out.set(name, { schema: fieldSchema, owner: variantOwner });\n }\n collectVariantFieldSchemas(variant, componentSchemas, owner, out, seen);\n }\n\n for (const sub of schema.allOf ?? []) collectVariantFieldSchemas(sub, componentSchemas, owner, out, seen);\n for (const sub of schema.anyOf ?? []) collectVariantFieldSchemas(sub, componentSchemas, owner, out, seen);\n\n return out;\n}\n\n/** A group member's schema plus the component that owns it, for inline naming. */\ninterface VariantFieldSchema {\n schema: SchemaObject;\n owner: string | undefined;\n}\n\n/** Resolve `{ $ref: '#/components/schemas/X' }` to its component, else undefined. */\nfunction resolveSchemaRefObject(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n): SchemaObject | undefined {\n if (!schema || !componentSchemas) return undefined;\n const ref = (schema as { $ref?: string }).$ref;\n if (!ref) return undefined;\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n if (!match) return undefined;\n return componentSchemas[match[1]];\n}\n\ntype RequestBodyEncoding = 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n\n/** HTTP methods whose request body is the primary parameter carrier. */\nconst BODY_CARRYING_METHODS: ReadonlySet<HttpMethod> = new Set<HttpMethod>(['post', 'put', 'patch']);\n\n/**\n * Pick the request body's schema and wire encoding from its content map, in\n * priority order. JSON wins over form encodings; binary and text bodies may\n * legitimately carry no schema at all.\n */\nfunction selectRequestBodyContent(body: RequestBodyObject | undefined): {\n encoding: RequestBodyEncoding;\n schema?: SchemaObject;\n} {\n const content = body?.content;\n if (!content) return { encoding: 'json' };\n if (content['application/json']?.schema) {\n return { encoding: 'json', schema: content['application/json'].schema };\n }\n if (content['multipart/form-data']?.schema) {\n return { encoding: 'form-data', schema: content['multipart/form-data'].schema };\n }\n if (content['application/x-www-form-urlencoded']?.schema) {\n return { encoding: 'form-urlencoded', schema: content['application/x-www-form-urlencoded'].schema };\n }\n if (content['application/octet-stream']) {\n return { encoding: 'binary', schema: content['application/octet-stream'].schema };\n }\n if (content['text/plain']) {\n return { encoding: 'text', schema: content['text/plain'].schema };\n }\n return { encoding: 'json' };\n}\n\n/** Parameter names referenced by any `x-mutually-exclusive-parameter-groups` variant. */\nfunction collectParameterGroupMemberNames(op: OperationObject): Set<string> {\n const names = new Set<string>();\n const raw = op['x-mutually-exclusive-parameter-groups'];\n if (!raw || typeof raw !== 'object') return names;\n // Malformed shapes are left for extractParameterGroups to report.\n for (const groupDef of Object.values(raw)) {\n const variants = groupDef && typeof groupDef === 'object' ? groupDef.variants : undefined;\n if (!variants || typeof variants !== 'object') continue;\n for (const members of Object.values(variants)) {\n if (!Array.isArray(members)) continue;\n for (const member of members) if (typeof member === 'string') names.add(member);\n }\n }\n return names;\n}\n\n/**\n * Every property name a request body is guaranteed to accept, following\n * `$ref`s and descending through composition. `allOf` members all apply, so\n * their properties union. `oneOf` / `anyOf` alternatives are choices, so only\n * a property every non-null alternative declares counts — otherwise a caller\n * on another branch would have no slot for the value in either the body or\n * the query. Used to decide which `in: query` declarations are body-owned.\n */\nfunction collectBodyPropertyNames(\n schema: SchemaObject | undefined,\n componentSchemas: Record<string, SchemaObject> | undefined,\n seen: ReadonlySet<string> = new Set(),\n): Set<string> {\n if (!schema) return new Set();\n\n const ref = (schema as { $ref?: string }).$ref;\n if (ref) {\n // Cycle guard is per path: the same component may legitimately appear in\n // sibling branches and must count for each of them.\n if (seen.has(ref)) return new Set();\n return collectBodyPropertyNames(\n resolveSchemaRefObject(schema, componentSchemas),\n componentSchemas,\n new Set([...seen, ref]),\n );\n }\n\n const names = new Set(Object.keys(schema.properties ?? {}));\n for (const sub of schema.allOf ?? []) {\n for (const name of collectBodyPropertyNames(sub, componentSchemas, seen)) names.add(name);\n }\n for (const alternatives of [schema.oneOf, schema.anyOf]) {\n const branches = (alternatives ?? []).filter((alt) => alt.type !== 'null');\n if (branches.length === 0) continue;\n let common: Set<string> | undefined;\n for (const branch of branches) {\n const branchNames = collectBodyPropertyNames(branch, componentSchemas, seen);\n common = common ? new Set([...common].filter((name) => branchNames.has(name))) : branchNames;\n }\n for (const name of common ?? []) names.add(name);\n }\n return names;\n}\n\nfunction extractRequestBody(\n body: RequestBodyObject | undefined,\n op: OperationObject | undefined,\n pathModelBaseName: string,\n inlineModels: Model[],\n componentSchemas?: Record<string, SchemaObject>,\n): { body?: TypeRef; encoding?: RequestBodyEncoding } {\n if (!body?.content) return {};\n\n const selected = selectRequestBodyContent(body);\n const encoding = selected.encoding;\n let schema = selected.schema;\n\n if (!schema) {\n // For binary/text, a schema is optional — produce a primitive TypeRef\n if (encoding === 'binary') {\n return { body: { kind: 'primitive', type: 'string', format: 'binary' }, encoding };\n }\n if (encoding === 'text') {\n return { body: { kind: 'primitive', type: 'string' }, encoding };\n }\n return {};\n }\n\n // Without an operationId, name the body from the operation's path-derived\n // prefix (see derivePathModelBaseName) so two operations don't share one\n // inline body model. Every operationId-less body used to be `RequestBody`,\n // and only the largest survived deduplication — every other operation was\n // left pointing at a model with someone else's fields.\n const contextName = op?.operationId ? operationIdModelName(op.operationId, 'Request') : pathModelBaseName + 'Request';\n\n // A discriminated-union request body (`oneOf` + an explicit `discriminator`)\n // compiles to a `oneOf` that code generators can't spread into named method\n // arguments — the caller is handed an opaque union and the generated snippets\n // carry no body fields. When every variant is an inline object pinned by a\n // string-const discriminator, the union is equivalent to a single object, so\n // fold it into that object and let the normal object path below emit\n // ergonomic, spread-able arguments. See flattenDiscriminatedUnionBody.\n if (schema.oneOf && schema.discriminator) {\n const merged = flattenDiscriminatedUnionBody(schema);\n if (merged) schema = merged;\n }\n\n // If the request body is an inline object with properties, extract it as a model\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const siblings = collectProperties(schema);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, contextName, requiredSet, componentSchemas, siblings));\n }\n inlineModels.push({ name: contextName, description: undefined, fields, ...constraintsEntry(schema) });\n // Nested inline objects (e.g. a `user` property that is itself an inline\n // object) are referenced by name from the fields above but are not emitted\n // by this branch. Recurse to materialize them, matching how component\n // schemas are handled in extractInlineModelsFromSchemas — otherwise the\n // generated body model references a model that never gets generated.\n extractInlineModelsFromProperties(schema, inlineModels, contextName, componentSchemas);\n return { body: { kind: 'model', name: contextName }, encoding };\n }\n\n // If the request body is a oneOf, extract each variant as an inline model\n // and build a union type pointing to them by name.\n if (schema.oneOf) {\n const variants: TypeRef[] = [];\n // The inline object variants of this union and the names its const-less\n // variants have taken so far, for `deriveOneOfVariantName`.\n const inlineObjectVariants = schema.oneOf.filter(\n (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n );\n const contentNamed: string[] = [];\n\n for (const variant of schema.oneOf) {\n if (variant.$ref) {\n const ref = schemaToTypeRef(variant, contextName);\n variants.push(ref);\n } else if (variant.type === 'null') {\n // skip null variant in union, handle separately\n } else if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const named = deriveOneOfVariantName(\n variant,\n contextName,\n inlineModels,\n inlineObjectVariants,\n contentNamed,\n Boolean(op?.operationId),\n );\n const variantName = named.name;\n if (named.fromContent) contentNamed.push(variantName);\n const requiredSet = new Set(variant.required ?? []);\n const siblings = collectProperties(variant);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema) continue;\n fields.push(\n buildFieldFromSchema(fieldName, fieldSchema, variantName, requiredSet, componentSchemas, siblings),\n );\n }\n inlineModels.push({\n name: variantName,\n description: variant.description,\n fields,\n ...constraintsEntry(variant),\n });\n extractInlineModelsFromProperties(variant, inlineModels, variantName, componentSchemas);\n variants.push({ kind: 'model', name: variantName });\n } else {\n variants.push(schemaToTypeRef(variant, contextName));\n }\n }\n\n const hasNull = schema.oneOf.some(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n const union: TypeRef = {\n kind: 'union',\n variants,\n ...(schema.discriminator\n ? {\n discriminator: { property: schema.discriminator.propertyName, mapping: schema.discriminator.mapping ?? {} },\n }\n : {}),\n };\n const body = hasNull ? ({ kind: 'nullable', inner: union } as TypeRef) : union;\n return { body, encoding };\n }\n\n return { body: schemaToTypeRef(schema, contextName), encoding };\n}\n\n/**\n * Fold a discriminated-union request body into the equivalent single object so\n * its fields can be spread into method arguments instead of forcing callers to\n * construct an opaque union.\n *\n * The result is the union of every variant's properties: the discriminator is\n * collapsed to an enum of the pinned const values, and any field that isn't\n * present-and-required in *every* variant becomes optional (it varies by\n * branch, so it can't be unconditionally required). The discriminator itself is\n * always required. This mirrors what a spec author would write by hand to model\n * the same shape as a flat object.\n *\n * Returns null — leaving the union intact — unless the body is a clean\n * inline-object discriminated union: a variant that is a `$ref`, a non-object,\n * or that doesn't pin the discriminator to a string const can't be safely\n * merged. Gating on an *explicit* `discriminator` keeps undiscriminated `oneOf`\n * bodies untouched.\n */\nfunction flattenDiscriminatedUnionBody(schema: SchemaObject): SchemaObject | null {\n const discProp = schema.discriminator?.propertyName;\n if (!discProp || !Array.isArray(schema.oneOf) || schema.oneOf.length === 0) return null;\n\n const variants = schema.oneOf as SchemaObject[];\n const discValues: string[] = [];\n let discPropSchema: SchemaObject | undefined;\n\n for (const variant of variants) {\n // Every variant must be an inline object that pins the discriminator to a\n // string const (or single-value enum); anything else can't be merged.\n if (variant.$ref || !variant.properties || !(variant.type === 'object' || variant.type === undefined)) {\n return null;\n }\n const dp = variant.properties[discProp] as SchemaObject | undefined;\n const constVal =\n typeof dp?.const === 'string'\n ? dp.const\n : Array.isArray(dp?.enum) && dp.enum.length === 1 && typeof dp.enum[0] === 'string'\n ? dp.enum[0]\n : undefined;\n if (constVal === undefined) return null;\n if (!discValues.includes(constVal)) discValues.push(constVal);\n if (!discPropSchema) discPropSchema = dp;\n }\n\n const variantCount = variants.length;\n const mergedProps: Record<string, SchemaObject> = {};\n const requiredCounts: Record<string, number> = {};\n const order: string[] = [discProp]; // discriminator leads the merged object\n\n for (const variant of variants) {\n const required = new Set(variant.required ?? []);\n for (const [name, propSchema] of Object.entries(variant.properties!)) {\n if (name === discProp || !propSchema) continue;\n if (!(name in mergedProps)) {\n mergedProps[name] = propSchema as SchemaObject;\n order.push(name);\n }\n if (required.has(name)) requiredCounts[name] = (requiredCounts[name] ?? 0) + 1;\n }\n }\n\n // The discriminator collapses to an enum of the pinned values.\n mergedProps[discProp] = {\n type: 'string',\n enum: discValues,\n ...(discPropSchema?.description ? { description: discPropSchema.description } : {}),\n };\n\n const properties: Record<string, SchemaObject> = {};\n for (const name of order) properties[name] = mergedProps[name];\n\n // Required only when required in every variant; the discriminator is always\n // required.\n const requiredFields = order.filter((name) => name === discProp || requiredCounts[name] === variantCount);\n\n return {\n type: 'object',\n properties,\n required: requiredFields,\n ...(schema.description ? { description: schema.description } : {}),\n // The wrapper's own keywords bind every branch, so they ride along; the\n // variants' keywords are alternatives and are not carried.\n ...extractConstraints(schema),\n };\n}\n\n/**\n * Derive a unique variant name for a request-body `oneOf` inline model.\n *\n * A variant with a string-const property is named after it\n * (`RadarEmailChallengeCodeSessionAuthenticateRequest`). Any other variant is\n * named from its content by the same rule every inline union variant follows\n * (`nameInlineVariant`): the first const-less variant keeps the body's name\n * (or its title, when every inline variant of the union is titled), and each\n * later one takes its title, a distinguishing property\n * (`CreateThingRequestWithB`) or, when its property set repeats an earlier\n * variant's, the position counter (`CreateThingRequest2`). `siblings` are the\n * union's inline object variants and `contentNamed` the names its const-less\n * variants have taken so far; `fromContent` tells the caller to record this\n * one there. A clash with a model minted elsewhere still bumps the counter:\n * on the base for a content-named variant (`CreateThingRequest2`), on the\n * const-derived name for a const-named one (`FooCreateThingRequest2`) — so a\n * variant titled `Foo` and a later one pinning `kind: foo` in the same body\n * never share a model.\n *\n * `fromOperationId` says where `baseName` came from. An operationId-derived\n * base is already in cleanSchemaName form and its variants go through\n * resolveSchemaName, so they follow the same project-level naming policy as\n * component schemas. A path-derived base is used verbatim: it is deliberately\n * not cleaned (see derivePathModelBaseName) and resolvePathModelBaseNames\n * reserves names by that exact prefix, so cleaning a variant here would let it\n * slip past the reservation — `NotesPostRequest` became `NotePostRequest` and\n * collided with a component of that name.\n */\nfunction deriveOneOfVariantName(\n variant: SchemaObject,\n baseName: string,\n existingModels: Model[],\n siblings: readonly SchemaObject[],\n contentNamed: readonly string[],\n fromOperationId: boolean,\n): { name: string; fromContent: boolean } {\n const finalize = (name: string): string => (fromOperationId ? resolveSchemaName(name) : name);\n const existingNames = new Set(existingModels.map((m) => m.name));\n // `name`, or `<stem><n>` counting from 2 while a model of that name exists.\n const unique = (name: string, stem: string): string => {\n let candidate = name;\n for (let suffix = 2; existingNames.has(candidate); suffix++) candidate = `${stem}${suffix}`;\n return candidate;\n };\n // Try to use a distinguishing property (e.g., \"grant_type\" field's const/enum value)\n if (variant.properties) {\n for (const [, propSchema] of Object.entries(variant.properties)) {\n if (propSchema?.const && typeof propSchema.const === 'string') {\n const derivedName = finalize(toPascalCase(propSchema.const) + baseName.replace(/Request$/, '') + 'Request');\n return { name: unique(derivedName, derivedName), fromContent: false };\n }\n }\n }\n // Finalize before naming so every candidate stays in the same namespace as\n // the rest of the IR.\n const finalBaseName = finalize(baseName);\n const name = unique(nameInlineVariant(variant, siblings, finalBaseName, contentNamed, null), finalBaseName);\n return { name, fromContent: true };\n}\n\n/** Human-readable label for an operation in diagnostics: its operationId, else `METHOD /path`. */\nfunction operationLabel(op: OperationObject | undefined, path: string, method: HttpMethod): string {\n return op?.operationId ?? `${method.toUpperCase()} ${path}`;\n}\n\n/**\n * Spec-wide record of every model name a header model must not silently\n * reuse: the component models (seeded up front) and each inline header model\n * materialized so far. The value carries the model's shape fingerprint, so a\n * header whose shape matches can share the name, and — for header models —\n * which operation produced it, so a collision inside one operation can be\n * told apart from one across operations.\n */\ntype HeaderModelRegistry = Map<string, { fingerprint: string; operation?: string }>;\n\n/** What response-header extraction needs from the operation and the spec. */\ninterface HeaderExtractionContext {\n componentHeaders?: Record<string, Record<string, unknown>>;\n /** Lets header models resolve `$ref` siblings and augmentations the way fields do. */\n componentSchemas?: Record<string, SchemaObject>;\n /** Qualifies header model and enum names: `Documents` + `X-Meta` → `DocumentsXMeta`. */\n serviceName?: string;\n /** PascalCase operation name, e.g. `CreateDocument`; qualifies a name taken across operations. */\n operationQualifier: string;\n registry: HeaderModelRegistry;\n}\n\n/** Shape of a model, independent of field order: name, requiredness, and type of every field. */\nfunction modelFingerprint(model: Model): string {\n return model.fields\n .map((f) => `${f.name}${f.required ? '!' : '?'}:${stableStringify(f.type)}`)\n .sort()\n .join('|');\n}\n\n/** `JSON.stringify` with object keys sorted, so equal shapes serialize equally. */\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n if (value !== null && typeof value === 'object') {\n const record = value as Record<string, unknown>;\n const entries = Object.keys(record)\n .sort()\n .map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`);\n return `{${entries.join(',')}}`;\n }\n return JSON.stringify(value) ?? 'undefined';\n}\n\n/**\n * Type a header's schema and materialize the inline models it names, under a\n * property name that does not collide with a different shape anywhere in the\n * spec.\n *\n * Header models are named from the service and header name alone, so an\n * inline `X-Meta` on a `Documents` operation is `DocumentsXMeta` — the same\n * name a component schema, or the same header on a 429 or on another\n * `Documents` operation, may already own with a different shape. Left alone,\n * the later merge keeps one definition for the name and every other\n * reference silently gets the wrong fields (a request body using the\n * component would even change type without any emitter reading headers).\n *\n * The first owner of a name keeps it: component models are seeded before any\n * operation, operations are visited in path order, and a single operation's\n * responses in ascending status-code order (integer-like keys iterate that\n * way), so the lowest code wins regardless of where it appears in the\n * document. A later header with a different shape — at any depth, a nested\n * object that differs counts — is re-derived under the first free candidate:\n *\n * 1. the bare header name `DocumentsXMeta`\n * 2. when the name is taken inside this operation, the status code\n * (`DocumentsXMeta429`); when taken by a component or another\n * operation, the operation (`DocumentsCreateDocumentXMeta`)\n * 3. the other of those two\n * 4. operation and status code `DocumentsCreateDocumentXMeta429`\n * 5. a numeric suffix `DocumentsXMeta2`, `DocumentsXMeta3`, ...\n *\n * Both the type and the models come from the same property name, so nested\n * models (`DocumentsXMeta429Origin`) line up by construction. A shape\n * identical to the name's current owner shares it and materializes nothing\n * new, which is also how a header reuses a matching component model.\n *\n * Treating the header as a one-property object reuses the field-level\n * extractor, whose names come from the same `qualifyInlineModelName(name,\n * parent)` rule `schemaToTypeRef` applies — the trick the inline request-body\n * path uses.\n */\nfunction typeHeaderSchema(\n schema: SchemaObject,\n name: string,\n statusCode: number,\n ctx: HeaderExtractionContext,\n models: Model[],\n): TypeRef {\n const parentName = ctx.serviceName ? toPascalCase(ctx.serviceName) : undefined;\n const byStatus = `${name}${statusCode}`;\n const byOperation = `${ctx.operationQualifier}${name}`;\n const byBoth = `${ctx.operationQualifier}${name}${statusCode}`;\n let candidates = [name, byStatus, byOperation, byBoth];\n\n for (let attempt = 0; ; attempt++) {\n const propertyName =\n attempt < candidates.length ? candidates[attempt] : `${name}${attempt - candidates.length + 2}`;\n const trial: Model[] = [];\n extractInlineModelsFromProperties(\n { properties: { [propertyName]: schema } },\n trial,\n parentName,\n ctx.componentSchemas,\n );\n\n const fingerprints = trial.map((model) => [model, modelFingerprint(model)] as const);\n const collisions = fingerprints.flatMap(([model, fingerprint]) => {\n const registered = ctx.registry.get(model.name);\n return registered !== undefined && registered.fingerprint !== fingerprint ? [registered] : [];\n });\n if (collisions.length > 0) {\n // Decide the preference between candidates 2 and 3 from the bare name's\n // owner: a clash within this operation reads best by status code, one\n // with a component or another operation by operation name.\n if (attempt === 0 && !collisions.every((c) => c.operation === ctx.operationQualifier)) {\n candidates = [name, byOperation, byStatus, byBoth];\n }\n continue;\n }\n\n for (const [model, fingerprint] of fingerprints) {\n if (ctx.registry.has(model.name)) continue;\n ctx.registry.set(model.name, { fingerprint, operation: ctx.operationQualifier });\n models.push(model);\n }\n return schemaToTypeRef(schema, propertyName, parentName);\n }\n}\n\n/**\n * Read a Response Object's `headers` map into IR response headers, resolving\n * `components/headers` refs. Returns `undefined` rather than `[]` when nothing\n * survives so callers can leave the `headers` key off entirely.\n *\n * An object-shaped header schema (directly, inside an array, or as a oneOf\n * variant) becomes a `ModelRef`, so the model it names is appended to\n * `models` — otherwise the ref would dangle with nothing to emit.\n */\nfunction extractResponseHeaders(\n headers: Record<string, RawHeaderObject> | undefined,\n operationLabel: string,\n statusCode: number,\n ctx: HeaderExtractionContext,\n models: Model[],\n): ResponseHeader[] | undefined {\n if (!headers) return undefined;\n\n const result: ResponseHeader[] = [];\n for (const [name, raw] of Object.entries(headers)) {\n // OAS 3.x: a response header named `Content-Type` SHALL be ignored; the\n // media type is already carried by the response's `content` map.\n if (name.toLowerCase() === 'content-type') continue;\n\n const header = resolveHeaderRef(raw, ctx.componentHeaders, name, operationLabel);\n if (!header) continue;\n\n // A Header Object declares `schema` or a single-entry `content` map; with\n // `content`, the first (only) media type's schema types the header.\n const contentSchema = header.content ? Object.values(header.content)[0]?.schema : undefined;\n const schema = header.schema ?? contentSchema;\n const type: TypeRef = schema\n ? typeHeaderSchema(schema, name, statusCode, ctx, models)\n : { kind: 'primitive', type: 'string' };\n\n result.push({\n name,\n type,\n required: header.required ?? false,\n description: header.description,\n deprecated: header.deprecated || undefined,\n });\n }\n\n return result.length > 0 ? result : undefined;\n}\n\n/**\n * Build the prefix (`NotesByIdPinPost`) that names both inline models — the\n * request body (`…Request`) and the response (`…Response`) — of an operation\n * that has no `operationId`, from the only thing that identifies it: its path\n * and method.\n *\n * Every non-parameter segment is PascalCased in order and every parameter\n * segment becomes `By` + PascalCase(param name); then the optional\n * disambiguator and the method are appended. The whole is normalized with\n * toPascalCase so it is a fixed point of that function: responses.ts re-cases\n * the response name in `deriveModelName`, and without this step `POST /a/b`\n * named its body `ABPostRequest` but its response `AbPostResponse`.\n *\n * GET /widgets → WidgetsGet\n * POST /notes → NotesPost\n * POST /notes/{id}/pin → NotesByIdPinPost\n * GET /users/{user_id}/sessions → UsersByUserIdSessionsGet\n *\n * This tells the common path shapes apart (list vs. item, sibling and nested\n * sub-resources) but is not unique by construction: `/foo-bar` and `/foo/bar`,\n * `/notes/by-id` and `/notes/{id}`, `/notes` and `/notes/` all flatten to the\n * same words. `resolvePathModelBaseNames` detects such collisions: the path\n * spelled most plainly keeps the plain name and every other one gets a\n * `disambiguator` derived from its raw path.\n *\n * A single-segment path keeps the name the old first-segment rule produced.\n * The result is deliberately not passed through cleanSchemaName (the old\n * fallback wasn't either): the segments are the resource names as the API\n * spells them.\n */\nexport function derivePathModelBaseName(path: string, method: HttpMethod, disambiguator = ''): string {\n const segments = path.split('/').filter(Boolean);\n const parts = segments.map((segment) =>\n segment.startsWith('{') ? 'By' + toPascalCase(segment.replace(/[{}]/g, '')) : toPascalCase(segment),\n );\n const resource = parts.length > 0 ? parts.join('') : 'Unknown';\n // `_` separators guarantee a word boundary on each side of the disambiguator\n // and the method, whatever the resource ends with; splitWords drops them.\n return toPascalCase([resource, disambiguator, method].filter(Boolean).join('_'));\n}\n\n/** `derivePathModelBaseName` plus the `Request` / `Response` suffix. */\nexport function derivePathBasedName(\n path: string,\n method: HttpMethod,\n suffix: 'Request' | 'Response',\n disambiguator = '',\n): string {\n return derivePathModelBaseName(path, method, disambiguator) + suffix;\n}\n\n/**\n * Decide the path-derived model prefix of every operation that has no\n * `operationId`, keyed by `${method} ${path}`.\n *\n * A prefix collides when two distinct raw paths with the same method flatten\n * to it (see derivePathModelBaseName), or when a reserved name starts with\n * it. The reserved names are every resolved component model name and, for\n * every operation with an `operationId`, its model stem\n * (operationIdModelBase). A prefix is the stem of several emitted names —\n * `…Request`, `…Response`, a list's `…Item`, nested inline models such as\n * `…ResponseOwner`, envelope companions such as `…ListMetadata` — so the\n * check is on the stem, not on an enumeration of suffixes: an unnamed\n * `GET /audit/events` must not overwrite `components/schemas/AuditEventsGetItem`\n * any more than an unnamed `POST /audit/events` may overwrite the models of\n * a `POST /legacy-audit` whose operationId is `auditEventsPost`. Reserved\n * names never change.\n *\n * This is deliberately a superset: a component named `AuditEventsGetter`, or\n * an operationId `auditEventsGetSummary`, also pushes `GET /audit/events`\n * onto a hashed name although no emitted name would coincide. Determinism\n * and never sharing a name wrongly matter more than the rare extra hash, and\n * the reservation is unconditional — an inline body is never merged into a\n * same-named component even when the shapes agree — so the rule stays\n * simple and order-free. Every name derived from a path-based prefix uses it\n * verbatim (body `oneOf` variants included; see deriveOneOfVariantName), and\n * as a second line of defence the check also runs on the cleaned spellings\n * of the prefix (see prefixSpellings), so `GET /notes` yields to a component\n * `NoteGetItem` although its own item model is `NotesGetItem`. Names that\n * embed the prefix behind a const value — a body `oneOf` variant pinning\n * `kind: email` is `EmailTagsPostRequest`, a nested variant\n * `<Const><Parent><Field>` — are checked too, with each const the operation\n * can mint prepended to every spelling (see collectOperationConstPrefixes);\n * the hash then lands inside those names as well (`EmailTags151Dd5PostRequest`).\n *\n * These names are types SDK users read and import, so a collision costs the\n * plain name only where it must. Within a group of paths that flatten to one\n * prefix, the path spelled most plainly (see pathDeviation: no trailing\n * slash, `{id}` rather than a literal `by-id`) is canonical and keeps the\n * plain prefix; every other path gets a six-character disambiguator, the\n * start of the SHA-1 of its raw path, inserted before the method\n * (`POST /foo-bar` next to `POST /foo/bar` → `FooBar546F12Post`). When two\n * paths tie for plainest, or the prefix is reserved, nobody is canonical and\n * every path in the group is disambiguated. The outcome depends only on the\n * document's paths, operationIds and component names, never on their order,\n * and a path that stops colliding returns to its plain name.\n */\nfunction resolvePathModelBaseNames(\n paths: Record<string, PathItem>,\n componentModels?: Model[],\n componentRequestBodies?: Record<string, Record<string, unknown>>,\n): Map<string, string> {\n const candidates: Array<{ key: string; path: string; method: HttpMethod; plain: string }> = [];\n const rawPathsByPlainName = new Map<string, Set<string>>();\n const constPrefixesByPlainName = new Map<string, Set<string>>();\n const reservedNames = new Set<string>();\n\n for (const model of componentModels ?? []) {\n reservedNames.add(model.name);\n }\n\n for (const [path, pathItem] of Object.entries(paths)) {\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n if (op.operationId) {\n reservedNames.add(operationIdModelBase(op.operationId));\n continue;\n }\n const plain = derivePathModelBaseName(path, method);\n candidates.push({ key: `${method} ${path}`, path, method, plain });\n const rawPaths = rawPathsByPlainName.get(plain) ?? new Set<string>();\n rawPaths.add(path);\n rawPathsByPlainName.set(plain, rawPaths);\n const constPrefixes = constPrefixesByPlainName.get(plain) ?? new Set<string>();\n for (const prefix of collectOperationConstPrefixes(\n op,\n componentRequestBodies,\n operationLabel(op, path, method),\n )) {\n constPrefixes.add(prefix);\n }\n constPrefixesByPlainName.set(plain, constPrefixes);\n }\n }\n\n const reservedList = [...reservedNames];\n const canonicalByPlainName = new Map<string, string | undefined>();\n for (const [plain, rawPaths] of rawPathsByPlainName) {\n // Every stem a name minted from this prefix can start with: the prefix in\n // each of its cleaned spellings, and each const value the operation can\n // prepend to it (`EmailTagsPostRequest` is `Email` + `TagsPost…`).\n const spellings = prefixSpellings(plain);\n const constPrefixes = ['', ...(constPrefixesByPlainName.get(plain) ?? [])];\n const stems = constPrefixes.flatMap((constPrefix) => spellings.map((spelling) => constPrefix + spelling));\n const reserved = stems.some((stem) => reservedList.some((name) => name.startsWith(stem)));\n canonicalByPlainName.set(plain, reserved ? undefined : canonicalPath(rawPaths));\n }\n\n const resolved = new Map<string, string>();\n for (const { key, path, method, plain } of candidates) {\n const keepsPlainName = canonicalByPlainName.get(plain) === path;\n resolved.set(key, keepsPlainName ? plain : derivePathModelBaseName(path, method, pathDisambiguator(path)));\n }\n return resolved;\n}\n\n/**\n * The one path in a group that is spelled most plainly by pathDeviation, or\n * undefined when two or more tie for it, so the choice never depends on the\n * order the paths were written in.\n */\nfunction canonicalPath(rawPaths: Iterable<string>): string | undefined {\n let best: string | undefined;\n let bestScore: [number, number] | undefined;\n let tied = false;\n for (const path of rawPaths) {\n const score = pathDeviation(path);\n const cmp = bestScore ? compareDeviation(score, bestScore) : -1;\n if (cmp < 0) {\n best = path;\n bestScore = score;\n tied = false;\n } else if (cmp === 0) {\n tied = true;\n }\n }\n return tied ? undefined : best;\n}\n\n/**\n * How far a raw path's spelling is from the plain prefix it flattens to:\n * `[trailing slash, literal segments with any character outside a-z0-9]`,\n * compared lexicographically. `/notes` scores [0, 0] and `/notes/` [1, 0];\n * `/notes/{id}` scores [0, 0] and `/notes/by-id` [0, 1].\n */\nfunction pathDeviation(rawPath: string): [number, number] {\n const trailingSlash = rawPath.length > 1 && rawPath.endsWith('/') ? 1 : 0;\n const irregularSegments = rawPath\n .split('/')\n .filter(Boolean)\n .filter((segment) => !segment.startsWith('{') && /[^a-z0-9]/.test(segment)).length;\n return [trailingSlash, irregularSegments];\n}\n\nfunction compareDeviation(a: [number, number], b: [number, number]): number {\n return a[0] - b[0] || a[1] - b[1];\n}\n\n/** The first six hex characters of the SHA-1 of a raw path. */\nfunction pathDisambiguator(rawPath: string): string {\n return createHash('sha1').update(rawPath).digest('hex').slice(0, 6);\n}\n\n/**\n * The spellings a path-based prefix could take if a name derived from it were\n * run through one of the parser's cleaning steps: the prefix itself (every\n * path-derived name uses it verbatim), cleanSchemaName's form (lead-word\n * singularization plus backend and ListItem-marker stripping),\n * resolveSchemaName's form (the same plus the project's schemaNameTransform),\n * and stripListItemMarkers alone, which nested-model and inline-enum\n * qualification apply to a parent name. Reserving by every spelling is the\n * second line of defence behind \"use the base verbatim\": a cleaning step added\n * later cannot let a derived name slip past the reservation. Empty spellings\n * are dropped so a degenerate prefix cannot match every reserved name.\n */\nfunction prefixSpellings(prefix: string): string[] {\n const spellings = [prefix, cleanSchemaName(prefix), resolveSchemaName(prefix), stripListItemMarkers(prefix)];\n return [...new Set(spellings)].filter((spelling) => spelling.length > 0);\n}\n\n/**\n * The PascalCase const values an operationId-less operation can prepend to a\n * name minted from its prefix, read from the schemas its request body and 2xx\n * responses declare inline. A body `oneOf` variant pinning `kind: email`\n * yields `EmailTagsPostRequest` (deriveOneOfVariantName); a nested\n * `oneOf`/`anyOf` object variant yields `<Const><Parent><Field>`\n * (nameOneOfVariant, nameVariantModel). Every string const or single-value\n * enum of every inline object variant is collected, top level and nested — a\n * superset of whichever property each of those picks as the discriminator, so\n * the reservation can never be narrower than the naming. `$ref` targets are\n * components with names of their own and are not followed. A request body\n * `$ref` that cannot be resolved is left for buildOperation to report.\n *\n * Names that do not embed the prefix at all — a response `oneOf` variant\n * named from its bare const (`Email`, see deriveModelName in responses.ts)\n * or a `title`-mapped variant — are outside what a disambiguator can\n * separate and are not reserved here.\n */\nfunction collectOperationConstPrefixes(\n op: OperationObject,\n componentRequestBodies: Record<string, Record<string, unknown>> | undefined,\n opLabel: string,\n): Set<string> {\n const prefixes = new Set<string>();\n let body: RequestBodyObject | undefined;\n try {\n body = resolveRequestBodyRef(op.requestBody, componentRequestBodies, opLabel);\n } catch {\n body = undefined;\n }\n collectConstPrefixes(selectRequestBodyContent(body).schema, prefixes, 0);\n for (const [statusCode, response] of Object.entries(op.responses ?? {})) {\n const code = parseInt(statusCode, 10);\n if (code < 200 || code >= 300) continue;\n for (const media of Object.values(response.content ?? {})) {\n collectConstPrefixes(media?.schema, prefixes, 0);\n }\n }\n return prefixes;\n}\n\nfunction collectConstPrefixes(schema: SchemaObject | undefined, out: Set<string>, depth: number): void {\n if (!schema || schema.$ref || depth > 16) return;\n for (const variants of [schema.oneOf, schema.anyOf]) {\n for (const variant of variants ?? []) {\n if (variant.$ref || !variant.properties) continue;\n for (const property of Object.values(variant.properties)) {\n const value = constStringOf(property);\n const prefix = value === null ? '' : toPascalCase(value);\n if (prefix) out.add(prefix);\n }\n }\n }\n const children: Array<SchemaObject | undefined> = [\n ...(schema.oneOf ?? []),\n ...(schema.anyOf ?? []),\n ...(schema.allOf ?? []),\n schema.items,\n ...Object.values(schema.properties ?? {}),\n typeof schema.additionalProperties === 'object' ? schema.additionalProperties : undefined,\n ];\n for (const child of children) {\n collectConstPrefixes(child, out, depth + 1);\n }\n}\n\n/** A property's pinned string value: a string `const`, or a single-value string `enum`. */\nfunction constStringOf(property: SchemaObject | undefined): string | null {\n if (!property) return null;\n if (typeof property.const === 'string') return property.const;\n if (Array.isArray(property.enum) && property.enum.length === 1 && typeof property.enum[0] === 'string') {\n return property.enum[0];\n }\n return null;\n}\n\nfunction deriveResponseName(op: OperationObject | undefined, pathModelBaseName: string): string {\n if (op?.operationId) {\n return operationIdModelName(op.operationId, 'Response');\n }\n return pathModelBaseName + 'Response';\n}\n\nfunction extractResponses(\n responses: Record<string, ResponseObject> | undefined,\n op: OperationObject | undefined,\n pathModelBaseName: string,\n path?: string,\n method?: HttpMethod,\n componentSchemas?: Record<string, SchemaObject>,\n headerContext: HeaderExtractionContext = { operationQualifier: '', registry: new Map() },\n): {\n response: TypeRef;\n responseHeaders?: ResponseHeader[];\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n inlineModels: Model[];\n isPaginated: boolean;\n dataPath?: string;\n itemType?: TypeRef;\n envelopeFields?: Field[];\n envelopeCompanions?: EnvelopeCompanion[];\n} {\n const errors: ErrorResponse[] = [];\n let response: TypeRef = { kind: 'primitive', type: 'string' };\n let responseHeaders: ResponseHeader[] | undefined;\n let inlineModels: Model[] = [];\n let isPaginated = false;\n let dataPath: string | undefined;\n let itemType: TypeRef | undefined;\n let envelopeFields: Field[] | undefined;\n let envelopeCompanions: EnvelopeCompanion[] | undefined;\n\n if (!responses) return { response, errors, inlineModels, isPaginated };\n\n const allSuccessResponses: SuccessResponse[] = [];\n const opLabel = operationLabel(op, path ?? '/', method ?? 'get');\n // Kept apart from `inlineModels`, which the latest 2xx body replaces\n // wholesale below; merged once every status code has been read.\n const headerModels: Model[] = [];\n\n for (const [statusCode, resp] of Object.entries(responses)) {\n const code = parseInt(statusCode, 10);\n // Headers belong to the status code they are declared on, success or\n // error alike: `Location` on a 201/302, `Retry-After` on a 429. A\n // response no branch below keeps (`default`, 1xx) declares none worth\n // materializing models for.\n const headers =\n code >= 200 ? extractResponseHeaders(resp.headers, opLabel, code, headerContext, headerModels) : undefined;\n\n if (code >= 200 && code < 300) {\n let extractedType: TypeRef = { kind: 'primitive', type: 'unknown' };\n const jsonContent = resp.content?.['application/json'];\n if (jsonContent?.schema) {\n const contextName = deriveResponseName(op, pathModelBaseName);\n const result = classifyAndExtractResponse(jsonContent.schema, contextName, componentSchemas);\n extractedType = result.response;\n // Keep track of inline models and pagination from the latest 2xx with a schema\n inlineModels = result.inlineModels;\n isPaginated = result.isPaginated;\n dataPath = result.dataPath;\n itemType = result.itemType;\n envelopeFields = result.envelopeFields;\n envelopeCompanions = result.envelopeCompanions;\n } else if (resp.content) {\n // Handle non-JSON response content types (text/plain, binary, XML, etc.)\n if (resp.content['application/octet-stream'] || resp.content['application/pdf']) {\n extractedType = { kind: 'primitive', type: 'string', format: 'binary' };\n } else if (\n resp.content['text/plain'] ||\n resp.content['text/html'] ||\n resp.content['text/xml'] ||\n resp.content['application/xml']\n ) {\n extractedType = { kind: 'primitive', type: 'string' };\n } else {\n // Try the first available content type's schema\n const firstKey = Object.keys(resp.content)[0];\n if (firstKey) {\n const firstContent = resp.content[firstKey];\n if (firstContent?.schema) {\n extractedType = schemaToTypeRef(firstContent.schema, deriveResponseName(op, pathModelBaseName));\n }\n }\n }\n }\n allSuccessResponses.push({ statusCode: code, type: extractedType, ...(headers && { headers }) });\n } else if (code >= 300 && code < 400) {\n // 3xx redirects — include so emitter can detect redirect endpoints\n allSuccessResponses.push({\n statusCode: code,\n type: { kind: 'primitive', type: 'unknown' },\n ...(headers && { headers }),\n });\n } else if (code >= 400) {\n const jsonContent = resp.content?.['application/json'];\n const type = jsonContent?.schema ? schemaToTypeRef(jsonContent.schema, `Error${code}`) : undefined;\n errors.push({ statusCode: code, type, ...(headers && { headers }) });\n }\n }\n\n // Primary response = lowest 2xx with a body schema, falling back to first 2xx\n if (allSuccessResponses.length > 0) {\n const sorted = [...allSuccessResponses].sort((a, b) => a.statusCode - b.statusCode);\n const primary =\n sorted.find((r) => r.type.kind !== 'primitive' || (r.type as { type: string }).type !== 'unknown') ?? sorted[0];\n response = primary.type;\n responseHeaders = primary.headers;\n }\n\n const successResponses = allSuccessResponses.length > 1 ? allSuccessResponses : undefined;\n if (headerModels.length > 0) inlineModels = [...inlineModels, ...headerModels];\n\n return {\n response,\n responseHeaders,\n successResponses,\n errors,\n inlineModels,\n isPaginated,\n dataPath,\n itemType,\n envelopeFields,\n envelopeCompanions,\n };\n}\n","import type { Model, Service, TypeRef } from '../ir/types.js';\nimport { walkTypeRef, collectResponseHeaders } from '../ir/types.js';\n\nfunction keepLargestByName(models: Model[]): Model[] {\n const byName = new Map<string, Model>();\n for (const model of models) {\n const existing = byName.get(model.name);\n if (existing && !haveSameFields(existing, model)) {\n // Two inline models resolved to one name but describe different shapes\n // (e.g. two operationIds that PascalCase to the same word). Only one can\n // survive, so say which, instead of silently handing every other\n // reference a model with someone else's fields.\n const kept =\n model.fields.length === existing.fields.length\n ? 'keeping the first definition'\n : 'keeping the one with more fields';\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has more than one definition with different fields or field types (${model.fields.length} vs ${existing.fields.length}) — ${kept}`,\n );\n }\n if (!existing || model.fields.length > existing.fields.length) {\n byName.set(model.name, model);\n }\n }\n return [...byName.values()];\n}\n\n/**\n * Same field names with the same types, in any order. Types are compared by\n * their JSON serialization: the parser builds a given shape's TypeRef with the\n * same key order every time, so equal shapes serialize identically.\n */\nfunction haveSameFields(a: Model, b: Model): boolean {\n const signatures = (m: Model) => new Set(m.fields.map((f) => `${f.name}:${JSON.stringify(f.type)}`));\n const aSignatures = signatures(a);\n const bSignatures = signatures(b);\n return aSignatures.size === bSignatures.size && [...aSignatures].every((s) => bSignatures.has(s));\n}\n\nfunction rewriteModelRef(ref: TypeRef, oldName: string, newName: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (r.name === oldName) (r as { name: string }).name = newName;\n },\n });\n}\n\nfunction rewriteModelRefs(models: Model[], services: Service[], oldName: string, newName: string): void {\n for (const model of models) {\n for (const field of model.fields) {\n rewriteModelRef(field.type, oldName, newName);\n }\n }\n for (const service of services) {\n for (const op of service.operations) {\n rewriteModelRef(op.response, oldName, newName);\n if (op.requestBody) {\n rewriteModelRef(op.requestBody, oldName, newName);\n }\n for (const field of op.pagination?.envelopeFields ?? []) {\n rewriteModelRef(field.type, oldName, newName);\n }\n for (const header of collectResponseHeaders(op)) {\n rewriteModelRef(header.type, oldName, newName);\n }\n }\n }\n}\n\nexport function mergeInlineResponseModels(schemaModels: Model[], inlineModels: Model[]): Model[] {\n const mergedSchemaModels = [...schemaModels];\n const schemaModelNames = new Set(mergedSchemaModels.map((m) => m.name));\n const schemaModelsByName = new Map(mergedSchemaModels.map((m) => [m.name, m]));\n\n const deduplicatedInlineModels = inlineModels.filter((model) => {\n if (!schemaModelNames.has(model.name)) return true;\n\n const existing = schemaModelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference && model.fields.length > existing.fields.length) {\n const idx = mergedSchemaModels.indexOf(existing);\n if (idx !== -1) mergedSchemaModels[idx] = model;\n schemaModelsByName.set(model.name, model);\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has more fields than component schema (${model.fields.length} vs ${existing.fields.length}) — using inline response model`,\n );\n } else if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...mergedSchemaModels, ...keepLargestByName(deduplicatedInlineModels)];\n}\n\n/**\n * Fold the field extractor's inline models into the models gathered so far,\n * keeping the earlier definition on a name clash. `componentNames` tells a\n * clash with a real component schema apart from one between two inline\n * models, so the warning can say which happened and name both shapes.\n */\nexport function mergeFieldInlineModels(\n existingModels: Model[],\n fieldInlineModels: Model[],\n componentNames?: Set<string>,\n): Model[] {\n const modelNames = new Set(existingModels.map((m) => m.name));\n const modelsByName = new Map(existingModels.map((m) => [m.name, m]));\n const fieldList = (m: Model): string => m.fields.map((f) => f.name).join(', ') || '(no fields)';\n\n const deduplicatedFieldModels = fieldInlineModels.filter((model) => {\n if (!modelNames.has(model.name)) return true;\n\n const existing = modelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference) {\n if (componentNames && !componentNames.has(model.name)) {\n console.warn(\n `[oagen] Warning: Two inline models are named \"${model.name}\" (fields: ${fieldList(existing)} | ${fieldList(model)}) — keeping the first, the second is dropped`,\n );\n } else {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n }\n\n return false;\n });\n\n return [...existingModels, ...keepLargestByName(deduplicatedFieldModels)];\n}\n\nfunction hasModelConstDiscriminant(model: Model): boolean {\n return model.fields.some(\n (f) => (f.name === 'object' || f.name === 'type') && f.type.kind === 'literal' && typeof f.type.value === 'string',\n );\n}\n\nfunction isModelReferencedByOthers(name: string, models: Model[], excludeNames: Set<string>): boolean {\n for (const model of models) {\n if (excludeNames.has(model.name)) continue;\n for (const field of model.fields) {\n let found = false;\n walkTypeRef(field.type, {\n model: (r) => {\n if (r.name === name) found = true;\n },\n });\n if (found) return true;\n }\n }\n return false;\n}\n\nexport function collapseJsonSuffixModels(models: Model[], services: Service[]): Model[] {\n const normalizedModels = [...models];\n const byName = new Map(normalizedModels.map((m) => [m.name, m]));\n\n // Pass 1: collect merge candidates\n const mergeCandidates: Array<{ jsonModel: Model; baseModel: Model }> = [];\n for (const model of normalizedModels) {\n if (!model.name.endsWith('Json')) continue;\n\n const baseName = model.name.slice(0, -4);\n const baseModel = byName.get(baseName);\n if (!baseModel || model.fields.length <= baseModel.fields.length) continue;\n\n const isSuperset = baseModel.fields.every((f) => model.fields.some((mf) => mf.name === f.name));\n if (!isSuperset) continue;\n\n // Guard: both models have a const discriminant — they are distinct entities\n if (hasModelConstDiscriminant(model) && hasModelConstDiscriminant(baseModel)) continue;\n\n // Guard: a third model explicitly references the Json-suffix model\n if (isModelReferencedByOthers(model.name, normalizedModels, new Set([model.name, baseName]))) continue;\n\n mergeCandidates.push({ jsonModel: model, baseModel });\n }\n\n // Pass 2: apply merges\n const toRemove = new Set<string>();\n for (const { jsonModel, baseModel } of mergeCandidates) {\n baseModel.fields = jsonModel.fields;\n // The base model now describes the Json schema's shape, so carry that\n // schema's own limits (minProperties, dependentRequired, ...) with the\n // fields; the base's keywords fill in wherever the Json model is silent.\n if (jsonModel.constraints || baseModel.constraints) {\n baseModel.constraints = { ...baseModel.constraints, ...jsonModel.constraints };\n }\n toRemove.add(jsonModel.name);\n rewriteModelRefs(normalizedModels, services, jsonModel.name, baseModel.name);\n console.warn(\n `[oagen] Merged \"${jsonModel.name}\" into \"${baseModel.name}\" (${jsonModel.fields.length} fields, superset)`,\n );\n }\n\n // Pass 3: cascade renames to inline children of collapsed Json-suffix models.\n // e.g. when AuditLogSchemaJson → AuditLogSchema, also rename\n // AuditLogSchemaJsonTarget → AuditLogSchemaTarget.\n for (const { jsonModel, baseModel } of mergeCandidates) {\n const jsonPrefix = jsonModel.name;\n const basePrefix = baseModel.name;\n\n for (const model of normalizedModels) {\n if (toRemove.has(model.name)) continue;\n if (model.name.length <= jsonPrefix.length) continue;\n if (!model.name.startsWith(jsonPrefix)) continue;\n\n const newName = basePrefix + model.name.slice(jsonPrefix.length);\n const existing = byName.get(newName);\n\n if (existing && !toRemove.has(existing.name)) {\n toRemove.add(model.name);\n rewriteModelRefs(normalizedModels, services, model.name, newName);\n console.warn(`[oagen] Collapsed child \"${model.name}\" into existing \"${newName}\"`);\n } else {\n rewriteModelRefs(normalizedModels, services, model.name, newName);\n model.name = newName;\n byName.set(newName, model);\n console.warn(`[oagen] Renamed child \"${jsonPrefix}…\" → \"${newName}\"`);\n }\n }\n }\n\n return normalizedModels.filter((m) => !toRemove.has(m.name));\n}\n","import type { Enum, Model, Operation, ResponseHeader, Service } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport { collectInlineEnumFromRef } from './schemas.js';\n\nexport function collectInlineEnumsFromModels(models: Model[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const model of models) {\n for (const field of model.fields) {\n collectInlineEnumFromRef(field.type, enums, enumNames);\n }\n }\n}\n\n/**\n * Collect inline enum definitions from operation parameters (query, path, header)\n * list-envelope companion fields, and response headers, and promote them to\n * top-level enums so emitters can generate typed enum files.\n */\nexport function collectInlineEnumsFromOperations(services: Service[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const service of services) {\n for (const op of service.operations) {\n for (const param of [\n ...op.pathParams,\n ...op.queryParams,\n ...(op.bodyOwnedQueryParams ?? []),\n ...op.headerParams,\n ...(op.cookieParams ?? []),\n ]) {\n collectInlineEnumFromRef(param.type, enums, enumNames);\n }\n for (const field of op.pagination?.envelopeFields ?? []) {\n collectInlineEnumFromRef(field.type, enums, enumNames);\n }\n // Response headers are typed like parameters, so an inline enum declared\n // on one must reach `spec.enums` the same way or the IR would point at\n // an enum no emitter ever generates.\n for (const { headers, qualifier } of responseHeaderGroups(op)) {\n for (const header of headers) collectHeaderEnums(header, qualifier, enums, enumNames);\n }\n }\n }\n}\n\n/**\n * Header lists to walk, each with the status-code qualifier that keeps a\n * colliding enum name apart. When `successResponses` exists the primary list\n * is the same array as its entry there, so the entries are walked with their\n * own codes instead of `responseHeaders`; a lone 2xx carries no status code\n * in the IR, so its headers get no qualifier.\n */\nfunction responseHeaderGroups(op: Operation): Array<{ headers: ResponseHeader[]; qualifier?: string }> {\n const groups: Array<{ headers: ResponseHeader[]; qualifier?: string }> = [];\n if (op.successResponses) {\n for (const entry of op.successResponses) {\n if (entry.headers) groups.push({ headers: entry.headers, qualifier: String(entry.statusCode) });\n }\n } else if (op.responseHeaders) {\n groups.push({ headers: op.responseHeaders });\n }\n for (const error of op.errors) {\n if (error.headers) groups.push({ headers: error.headers, qualifier: String(error.statusCode) });\n }\n return groups;\n}\n\n/**\n * Promote a header's inline enums. A header enum is named from the service\n * and header name alone, so `X-Policy` allowing `fast`/`slow` on a 200 and\n * `retry`/`stop` on a 429 would share one name and whichever was collected\n * first would silently win; a request parameter named like the header\n * collides the same way. When the name is already taken by a different value\n * set, the header's ref is renamed to a distinct name before it is promoted.\n * A taken name with the same values is shared, as before.\n */\nfunction collectHeaderEnums(\n header: ResponseHeader,\n qualifier: string | undefined,\n enums: Enum[],\n enumNames: Set<string>,\n): void {\n walkTypeRef(header.type, {\n enum: (ref) => {\n if (!ref.values) return;\n const existing = enums.find((e) => e.name === ref.name);\n if (existing && !sameEnumValues(existing, ref.values)) {\n ref.name = distinctEnumName(ref.name, ref.values, qualifier, enums);\n }\n collectInlineEnumFromRef(ref, enums, enumNames);\n },\n });\n}\n\n/** Order-insensitive: a reordering of the same members is the same type. */\nfunction sameEnumValues(existing: Enum, values: (string | number)[]): boolean {\n if (existing.values.length !== values.length) return false;\n const have = new Set(existing.values.map((v) => v.value));\n return values.every((v) => have.has(v));\n}\n\n/**\n * The first name not taken by a different value set: the base qualified by\n * the status code (`DocumentsXPolicy429`), then numeric suffixes\n * (`DocumentsXPolicy2`, `DocumentsXPolicy3`, ...). Deterministic for a given\n * spec, since it depends only on declaration order.\n */\nfunction distinctEnumName(\n base: string,\n values: (string | number)[],\n qualifier: string | undefined,\n enums: Enum[],\n): string {\n const isUsable = (name: string): boolean => {\n const taken = enums.find((e) => e.name === name);\n return !taken || sameEnumValues(taken, values);\n };\n if (qualifier && isUsable(`${base}${qualifier}`)) return `${base}${qualifier}`;\n let suffix = 2;\n while (!isUsable(`${base}${suffix}`)) suffix++;\n return `${base}${suffix}`;\n}\n","import type {\n ApiSpec,\n Enum,\n Model,\n Operation,\n Parameter,\n ParameterGroup,\n ParameterGroupVariant,\n Service,\n TypeRef,\n} from '../ir/types.js';\n\n/**\n * Assign `ParameterGroup.wrapperName` across the whole spec.\n *\n * Emitters derive a group's generated wrapper type name from the group name\n * alone, so two operations sharing a group name (create and update both\n * declare `protocol_options`) collapse onto a single type. That is only sound\n * while the two declarations carry the same members. Where they differ, one\n * operation ends up typed with the other's member — e.g. a connection update\n * forced to pass `CreateConnectionSAMLOptions`, which accepts three fields the\n * PATCH endpoint rejects.\n *\n * This pass fingerprints every group's members structurally and qualifies the\n * wrapper name with the operation name only for groups that genuinely diverge.\n * Groups whose declarations agree keep the bare group name, so wrapper types\n * already published in the SDKs are never renamed.\n */\nexport function assignParameterGroupWrapperNames(spec: ApiSpec): void {\n const modelMap = new Map(spec.models.map((m) => [m.name, m]));\n const enumMap = new Map(spec.enums.map((e) => [e.name, e]));\n\n // group name -> the distinct structural fingerprints seen for it\n const fingerprints = new Map<string, Set<string>>();\n const occurrences: Occurrence[] = [];\n\n for (const service of spec.services) {\n for (const op of service.operations) {\n for (const group of op.parameterGroups ?? []) {\n const fp = fingerprintGroup(group, modelMap, enumMap);\n let seen = fingerprints.get(group.name);\n if (!seen) {\n seen = new Set();\n fingerprints.set(group.name, seen);\n }\n seen.add(fp);\n occurrences.push({ service, op, group, fingerprint: fp });\n }\n }\n }\n\n for (const { op, group } of occurrences) {\n const diverges = (fingerprints.get(group.name)?.size ?? 0) > 1;\n group.wrapperName = diverges ? `${op.name}_${group.name}` : group.name;\n }\n\n qualifyResidualCollisions(occurrences);\n reconcileSharedGroups(occurrences.map((o) => o.group));\n}\n\ninterface Occurrence {\n service: Service;\n op: Operation;\n group: ParameterGroup;\n fingerprint: string;\n}\n\n/**\n * Break the collisions the operation-qualified name can still leave behind.\n *\n * `${op.name}_${group.name}` is not a unique key, for two separate reasons:\n *\n * - `disambiguateOperationNames` makes operation names unique only *within* a\n * service, so two services that each own an operation named `create`, both\n * declaring a `password` group with different members, both land on\n * `create_password`.\n * - Within one service it deliberately leaves same-name operations alone when\n * they share a path (see the `uniquePaths.size <= 1` guard — \"same path,\n * different methods\"), so `PUT` and `PATCH` on one path both stay `update`\n * and a service prefix alone still produces one name for both.\n *\n * Either way `reconcileSharedGroups` would then fuse two incompatible\n * declarations into a single type — the exact failure this pass exists to\n * prevent — and it does not drop the surplus member, so the wrapper would\n * expose a field one of the operations rejects.\n *\n * So escalate in rounds, adding a qualifier at a time and re-testing what still\n * collides. `(service, path, method)` identifies an operation uniquely, and a\n * same-name collision within a service implies a shared path, so service then\n * method is sufficient to separate every case.\n *\n * Each round only touches names that *still* group differing fingerprints, so a\n * name whose sharers agree is never renamed: sharing one wrapper is exactly what\n * should happen there, and renaming it would move a type the SDKs already\n * publish. On a spec where no qualified name collides — the WorkOS spec today —\n * the whole pass is a no-op.\n */\nfunction qualifyResidualCollisions(occurrences: Occurrence[]): void {\n // Prepended in order, matching how the operation and group names already\n // compose, so a fully-escalated name reads `<method>_<service>_<op>_<group>`.\n const qualifiers: ((o: Occurrence) => string)[] = [(o) => o.service.name, (o) => o.op.httpMethod];\n\n for (const qualify of qualifiers) {\n for (const sharers of collidingCandidates(occurrences)) {\n // A declaration still holding its group's own bare name owns that name.\n // A qualified name can land on some *other* group's literal name — an\n // `update` operation's `parent` group qualifies to `update_parent`, which\n // may already be a group called `update_parent` — and that group is\n // internally consistent, never diverged, and already published under it.\n // Move only the declarations that have already been escalated; anything\n // left fused falls through to the terminal round.\n //\n // This cannot strand a collision. Two groups sharing a literal name with\n // differing structures always diverge on that name and are both qualified\n // in the first assignment, so at most one member of a colliding set can\n // still be bare. When one is, moving the rest separates them; in the\n // degenerate case where none are movable, nothing moves here and the\n // terminal round separates by structure regardless.\n const movable = sharers.filter((o) => o.group.wrapperName !== o.group.name);\n for (const o of movable) {\n o.group.wrapperName = `${qualify(o)}_${o.group.wrapperName ?? o.group.name}`;\n }\n }\n }\n\n separateRemainingByStructure(occurrences);\n}\n\n/**\n * Terminal round: separate whatever the operation attributes could not.\n *\n * No combination of operation attributes is unique by construction. Two\n * operations in one service can share a name, a method *and* differ only by\n * path — `normalizeOperationIdForNaming` strips the `[N]` suffix, so a NestJS\n * controller method bound to several routes derives one name for all of them.\n * The WorkOS spec already contains such a pair (`Authorization`'s\n * `listRoleAssignments` on two paths); it declares no parameter groups today,\n * so nothing is wrong in the SDKs, but the shape is present rather than\n * hypothetical. Adding `path` as a fourth qualifier would only move the\n * boundary again.\n *\n * So stop enumerating attributes and separate by the thing that actually\n * matters: a name still fusing distinct structures gets one wrapper per\n * distinct fingerprint. That makes \"same `wrapperName` implies same structure\"\n * hold unconditionally, which is the invariant every emitter relies on.\n *\n * Suffixes are keyed on the fingerprint, not on a per-occurrence counter, so\n * declarations that agree keep sharing a wrapper.\n *\n * Ordering is by first appearance, not by sorted fingerprint: the structure\n * declared first keeps the unsuffixed name. Sorting by fingerprint would be\n * equally deterministic but less stable in the way that matters — adding a\n * member to one operation changes its fingerprint and could swap which of two\n * published wrappers holds the bare name. Under first-appearance order only\n * reordering the operations themselves can shift a name, which is both rarer\n * and visible in the spec diff.\n *\n * Either way this is a no-op wherever an earlier round already sufficed —\n * including the WorkOS spec, which never reaches this round at all.\n */\nfunction separateRemainingByStructure(occurrences: Occurrence[]): void {\n const taken = new Set(occurrences.map((o) => o.group.wrapperName ?? o.group.name));\n\n for (const sharers of collidingCandidates(occurrences)) {\n const base = sharers[0].group.wrapperName ?? sharers[0].group.name;\n\n // First fingerprint seen keeps `base`; each new one takes the next free\n // `base_N`, skipping any name already spoken for elsewhere in the spec.\n const nameFor = new Map<string, string>();\n let n = 2;\n for (const o of sharers) {\n if (nameFor.has(o.fingerprint)) continue;\n if (nameFor.size === 0) {\n nameFor.set(o.fingerprint, base);\n continue;\n }\n while (taken.has(`${base}_${n}`)) n++;\n const name = `${base}_${n}`;\n taken.add(name);\n nameFor.set(o.fingerprint, name);\n n++;\n }\n\n for (const o of sharers) o.group.wrapperName = nameFor.get(o.fingerprint)!;\n }\n}\n\n/**\n * Candidate wrapper names shared by declarations that do not agree — the only\n * ones an escalation round may rename.\n */\nfunction collidingCandidates(occurrences: Occurrence[]): Occurrence[][] {\n const byCandidate = new Map<string, Occurrence[]>();\n for (const o of occurrences) {\n const key = o.group.wrapperName ?? o.group.name;\n const list = byCandidate.get(key);\n if (list) list.push(o);\n else byCandidate.set(key, [o]);\n }\n return [...byCandidate.values()].filter(\n (sharers) => sharers.length > 1 && new Set(sharers.map((o) => o.fingerprint)).size > 1,\n );\n}\n\n/**\n * Make every group that shares a `wrapperName` describe literally the same\n * type.\n *\n * Deciding two declarations may share one wrapper is only half the job. The\n * fingerprint deliberately ignores nullability and member order, so sharers can\n * still disagree on both — and each emitter renders the wrapper from whichever\n * operation it happens to reach first while rendering call sites from their own\n * operation. Kotlin showed the consequence: `ParentResource.ById.id` emitted as\n * `String` from one operation, while the Java-friendly overload built from\n * another passed a `String?` into it, and the SDK stopped compiling.\n *\n * So normalize the two axes the fingerprint waived:\n * - a member the sharers disagree on settles as non-nullable. Widening to\n * nullable instead reads as the friendlier choice, but the nullable form\n * doesn't survive every emitter's group paths (Kotlin's query dispatch\n * builds a `Pair<String, String>` from the member, which a `String?` can't\n * satisfy), and non-nullable is what all sharers carried before group\n * member types were resolved at all — so it changes no published surface.\n * A member every sharer agrees is nullable stays nullable.\n *\n * The cost: an operation whose spec really does accept null for a member\n * (`PATCH` on a resource may clear `parent_resource_id`) can't express that\n * through the shared wrapper. It never could — the member used to be a flat\n * `string` everywhere — so nothing regresses, but the limitation is real and\n * removing it means letting that group's wrapper split per operation.\n * - member order follows the first sharer, so positional constructors and\n * their call sites agree.\n */\nfunction reconcileSharedGroups(groups: ParameterGroup[]): void {\n const byWrapper = new Map<string, ParameterGroup[]>();\n for (const group of groups) {\n const key = group.wrapperName ?? group.name;\n const list = byWrapper.get(key);\n if (list) list.push(group);\n else byWrapper.set(key, [group]);\n }\n\n for (const sharers of byWrapper.values()) {\n if (sharers.length < 2) continue;\n\n for (const variant of sharers[0].variants) {\n const peers = sharers\n .slice(1)\n .map((g) => g.variants.find((v) => v.name === variant.name))\n .filter((v): v is ParameterGroupVariant => v !== undefined);\n if (peers.length === 0) continue;\n\n // Settle nullability: unanimously-nullable members stay nullable, and any\n // member the sharers disagree on drops to non-nullable in all of them.\n for (const member of variant.parameters) {\n const all = [member, ...peers.map((p) => p.parameters.find((q) => q.name === member.name)).filter(isParameter)];\n if (all.every((p) => p.type.kind === 'nullable')) continue;\n for (const p of all) {\n if (p.type.kind === 'nullable') p.type = p.type.inner;\n }\n }\n\n // Align order on the first sharer's, leaving any member it doesn't\n // declare in place at the end rather than dropping it.\n const canonical = variant.parameters.map((p) => p.name);\n for (const peer of peers) {\n peer.parameters.sort((a, b) => {\n const ia = canonical.indexOf(a.name);\n const ib = canonical.indexOf(b.name);\n if (ia === -1 && ib === -1) return 0;\n if (ia === -1) return 1;\n if (ib === -1) return -1;\n return ia - ib;\n });\n }\n }\n }\n}\n\nfunction isParameter(p: Parameter | undefined): p is Parameter {\n return p !== undefined;\n}\n\n/**\n * Structural fingerprint of a group: its variants, their members, and each\n * member's resolved shape. Two declarations with the same fingerprint can\n * safely share one generated wrapper type.\n */\nfunction fingerprintGroup(group: ParameterGroup, modelMap: Map<string, Model>, enumMap: Map<string, Enum>): string {\n const variants = group.variants.map((v) => {\n // Members are sorted by name: every emitter renders the wrapper as a\n // named-field type (dataclass, data class, readonly promoted properties,\n // struct variant), so two operations listing the same members in a\n // different order still describe the same type and must keep sharing one\n // wrapper rather than being renamed apart.\n const members = [...v.parameters]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((p) => `${p.name}:${fingerprintType(p.type, modelMap, enumMap, new Set())}`);\n const optional = [...(v.optionalParameters ?? [])].sort();\n return `${v.name}(${members.join(',')})[${optional.join(',')}]`;\n });\n // `optional` is deliberately excluded: whether the group as a whole may be\n // omitted is a property of the operation's signature, not of the wrapper\n // type, and create/update legitimately differ there (required vs optional)\n // while sharing an identical wrapper.\n return variants.join('|');\n}\n\n/**\n * Fingerprint a type by shape rather than by name.\n *\n * Names cannot be compared directly because the parser synthesizes a separate\n * name per declaration site for inline schemas: `create_user` and `update_user`\n * each get their own `PasswordHashType` enum, spelled `CreateUserPasswordHashType`\n * and `UpdateUserPasswordHashType`, though their values are identical. Comparing\n * names would report divergence and rename a wrapper for no reason.\n *\n * Nullability is also stripped: an update declaring a member nullable while\n * create declares it plain is not a reason to split the wrapper type.\n */\nfunction fingerprintType(\n ref: TypeRef,\n modelMap: Map<string, Model>,\n enumMap: Map<string, Enum>,\n visiting: Set<string>,\n): string {\n switch (ref.kind) {\n case 'nullable':\n // Widening only — a nullable and a non-nullable member are compatible.\n return fingerprintType(ref.inner, modelMap, enumMap, visiting);\n case 'primitive':\n return `p:${ref.type}`;\n case 'literal':\n return `l:${typeof ref.value}:${String(ref.value)}`;\n case 'array':\n return `a<${fingerprintType(ref.items, modelMap, enumMap, visiting)}>`;\n case 'map':\n return `m<${fingerprintType(ref.valueType, modelMap, enumMap, visiting)}>`;\n case 'union':\n // Sorted, like enum values and model fields: a union accepts the same set\n // of types whichever order the branches are written in, so two operations\n // listing equivalent branches differently describe the same type and must\n // keep sharing a wrapper rather than renaming a published one apart.\n return `u<${ref.variants\n .map((v) => fingerprintType(v, modelMap, enumMap, visiting))\n .sort()\n .join(',')}>`;\n case 'enum': {\n const e = enumMap.get(ref.name);\n if (!e) return `e:${ref.name}`;\n // Values, not the synthesized name — two inline copies of one enum are\n // the same type for wrapper-sharing purposes. The value's primitive type\n // is part of the fingerprint (as it is for `literal`): the IR keeps\n // numeric `5` and string `\"5\"` distinct, and so do the emitters, so two\n // enums that stringify alike are still different types.\n //\n // Sorted, like model fields and group members above: declaration order of\n // enum values does not change which values the member accepts, so two\n // inline enums listing one set in different orders must keep sharing a\n // wrapper rather than renaming an already-published type apart.\n return `e<${e.values\n .map((v) => `${typeof v.value}:${String(v.value)}`)\n .sort()\n .join(',')}>`;\n }\n case 'model': {\n const m = modelMap.get(ref.name);\n if (!m) return `M:${ref.name}`;\n // Recursion guard: a model reachable from itself fingerprints by name at\n // the point of recurrence, which is enough to distinguish shapes.\n if (visiting.has(ref.name)) return `M:${ref.name}`;\n const next = new Set(visiting).add(ref.name);\n const fields = [...m.fields]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((f) => `${f.name}${f.required ? '!' : '?'}:${fingerprintType(f.type, modelMap, enumMap, next)}`);\n return `M<${fields.join(',')}>`;\n }\n default:\n return 'unknown';\n }\n}\n","import type { ApiSpec, TypeRef } from '../ir/types.js';\nimport { walkTypeRef, collectResponseHeaders } from '../ir/types.js';\n\nexport function validateModelRefs(spec: ApiSpec): void {\n const knownNames = new Set<string>();\n for (const m of spec.models) knownNames.add(m.name);\n for (const e of spec.enums) knownNames.add(e.name);\n\n function walkRef(ref: TypeRef, context: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (!knownNames.has(r.name)) {\n console.warn(`[oagen] Warning: Unresolved model reference \"${r.name}\" (context: ${context})`);\n }\n },\n });\n }\n\n for (const model of spec.models) {\n for (const field of model.fields) {\n walkRef(field.type, `${model.name}.${field.name}`);\n }\n }\n\n for (const service of spec.services) {\n for (const op of service.operations) {\n for (const p of [...op.pathParams, ...op.queryParams, ...(op.bodyOwnedQueryParams ?? []), ...op.headerParams]) {\n walkRef(p.type, `${service.name}.${op.name}.${p.name}`);\n }\n if (op.requestBody) walkRef(op.requestBody, `${service.name}.${op.name}.requestBody`);\n walkRef(op.response, `${service.name}.${op.name}.response`);\n for (const field of op.pagination?.envelopeFields ?? []) {\n walkRef(field.type, `${service.name}.${op.name}.pagination.${field.name}`);\n }\n for (const header of collectResponseHeaders(op)) {\n walkRef(header.type, `${service.name}.${op.name}.headers.${header.name}`);\n }\n }\n }\n}\n","import type { ApiSpec, AuthScheme, ServerEntry } from '../ir/types.js';\nimport { defaultSdkBehavior } from '../ir/sdk-behavior.js';\nimport { SpecParseError } from '../errors.js';\nimport { loadAndBundleSpec } from './refs.js';\nimport {\n extractSchemas,\n extractInlineModelsFromSchemas,\n clearSchemaNameTransform,\n resolveSchemaName,\n} from './schemas.js';\nimport { extractOperations } from './operations.js';\nimport {\n mergeInlineResponseModels,\n collapseJsonSuffixModels,\n mergeFieldInlineModels,\n} from './normalize-inline-models.js';\nimport { collectInlineEnumsFromModels, collectInlineEnumsFromOperations } from './collect-inline-enums.js';\nimport { assignParameterGroupWrapperNames } from './parameter-group-names.js';\nimport { validateModelRefs } from './normalize-model-refs.js';\nimport { extractSecurityRequirements, type RawSecurityRequirements } from './security.js';\nimport type { SchemaNameTransform } from './schemas.js';\n\n/**\n * A bundled OpenAPI document, post-`$ref` resolution but pre-IR extraction.\n *\n * This is the shape the spec author wrote, with external refs inlined and\n * internal refs left intact. It is intentionally loose (`Record<string,\n * unknown>`) so `transformSpec` can reach arbitrary spec extensions without\n * fighting types — narrow with `as` at use sites.\n */\nexport type OpenApiDocument = Record<string, unknown>;\n\nexport interface ParseOptions {\n operationIdTransform?: (id: string) => string;\n /**\n * Custom transform for schema (model/enum) names. Receives the cleaned\n * PascalCase name and, for component schemas, the original name as spelled\n * in the document. Returning `originalName` opts out of normalization.\n * See `SchemaExtractionOptions.schemaNameTransform`.\n */\n schemaNameTransform?: SchemaNameTransform;\n /**\n * Domain-facing field-name overrides, keyed by IR model name then wire field\n * name: `{ Connection: { connection_type: 'type' } }`. Sets `Field.domainName`\n * so emitters expose the field under the friendlier name while keeping the\n * wire key. Language-agnostic — honored by any emitter that reads `domainName`.\n */\n fieldHints?: Record<string, Record<string, string>>;\n /**\n * Pre-IR overlay applied to the bundled OpenAPI document before any IR\n * extraction runs. Use this when the upstream spec can't be changed but you\n * need to patch around a spec quirk that would otherwise emit a breaking SDK\n * change — e.g. rewriting a path's response `$ref` back to its prior schema,\n * merging the new fields onto the prior schema, and dropping the fork.\n *\n * The function may mutate the document in place and return it, or return a\n * new object; the returned value is what the rest of oagen sees.\n *\n * Runs once, after `$ref` bundling and before schema/operation extraction.\n * If you need to inspect the resulting IR instead, post-process the\n * `ApiSpec` returned by `parseSpec`.\n */\n transformSpec?: (spec: OpenApiDocument) => OpenApiDocument;\n}\n\nexport async function parseSpec(specPath: string, options?: ParseOptions): Promise<ApiSpec> {\n const { parsed } = await loadAndBundleSpec(specPath);\n const transformed = options?.transformSpec ? options.transformSpec(parsed) : parsed;\n\n const spec = transformed as {\n openapi?: string;\n info?: { title?: string; version?: string; description?: string };\n servers?: Array<{ url?: string; description?: string }>;\n security?: RawSecurityRequirements;\n tags?: Array<{ name?: string; description?: string }>;\n paths?: Record<string, unknown>;\n components?: {\n schemas?: Record<string, unknown>;\n parameters?: Record<string, unknown>;\n requestBodies?: Record<string, unknown>;\n examples?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n securitySchemes?: Record<string, SecuritySchemeObject>;\n };\n };\n\n // Validate OpenAPI version\n const version = spec.openapi ?? '';\n if (!version.startsWith('3.')) {\n throw new SpecParseError(\n `Unsupported OpenAPI version: ${version}. oagen requires OpenAPI 3.x`,\n `Update the spec to OpenAPI 3.0 or 3.1. If you are using Swagger 2.x, convert it first with \\`npx swagger2openapi ${specPath}\\`.`,\n );\n }\n\n const { models, enums } = extractSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n { schemaNameTransform: options?.schemaNameTransform },\n );\n\n const { services, inlineModels } = extractOperations(\n spec.paths as Record<string, Record<string, unknown>> | undefined,\n options?.operationIdTransform,\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n spec.components?.parameters as Record<string, Record<string, unknown>> | undefined,\n spec.components?.requestBodies as Record<string, Record<string, unknown>> | undefined,\n models,\n spec.tags,\n spec.components?.examples as Record<string, Record<string, unknown>> | undefined,\n spec.components?.headers as Record<string, Record<string, unknown>> | undefined,\n );\n\n const responseNormalizedModels = mergeInlineResponseModels(models, inlineModels);\n\n // Extract inline models from model field definitions (objects/arrays with properties).\n // schemaNameTransform is kept active so inline child names use the\n // transformed parent name (e.g. AuditLogSchemaJson→AuditLogSchema yields\n // AuditLogSchemaTarget, not AuditLogSchemaJsonTarget).\n const fieldInlineModels = extractInlineModelsFromSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n );\n // Resolved while the transform is still active so the names match the\n // models'; lets the merge tell a clash with a component schema from one\n // between two inline models.\n const componentNames = new Set(\n Object.keys(spec.components?.schemas ?? {}).map((schemaName) => resolveSchemaName(schemaName)),\n );\n clearSchemaNameTransform();\n const fieldMergedModels = mergeFieldInlineModels(responseNormalizedModels, fieldInlineModels, componentNames);\n const finalModels = collapseJsonSuffixModels(fieldMergedModels, services);\n applyFieldHints(finalModels, options?.fieldHints);\n collectInlineEnumsFromModels(finalModels, enums);\n collectInlineEnumsFromOperations(services, enums);\n\n const auth = extractAuthSchemes(spec.components?.securitySchemes);\n\n const serverEntries: ServerEntry[] = (spec.servers ?? [])\n .map((s) => ({ url: s.url ?? '', description: s.description }))\n .filter((s) => s.url);\n\n const result: ApiSpec = {\n name: spec.info?.title ?? 'Unknown API',\n version: spec.info?.version ?? '0.0.0',\n description: spec.info?.description,\n baseUrl: serverEntries[0]?.url ?? '',\n servers: serverEntries.length > 0 ? serverEntries : undefined,\n services,\n models: finalModels,\n enums,\n auth,\n security: extractSecurityRequirements(spec.security, 'the document'),\n sdk: defaultSdkBehavior(),\n };\n\n // Needs the finished models and enums: divergence is decided on member\n // shape, so this can only run once every referenced type is resolvable.\n assignParameterGroupWrapperNames(result);\n\n validateModelRefs(result);\n\n return result;\n}\n/**\n * Apply `fieldHints` onto the built models, setting `Field.domainName` for each\n * matching (model name, wire field name) pair. Serialization still uses\n * `Field.name`; only the domain-facing identifier changes.\n */\nfunction applyFieldHints(\n models: import('../ir/types.js').Model[],\n fieldHints: Record<string, Record<string, string>> | undefined,\n): void {\n if (!fieldHints) return;\n for (const model of models) {\n const hints = fieldHints[model.name];\n if (!hints) continue;\n for (const field of model.fields) {\n const domainName = hints[field.name];\n if (domainName) field.domainName = domainName;\n }\n }\n}\n\n/** A `components.securitySchemes` entry as it appears in the OpenAPI document. */\ninterface SecuritySchemeObject {\n type: string;\n description?: string;\n scheme?: string;\n in?: string;\n name?: string;\n flows?: Record<string, unknown>;\n}\n\n/**\n * Extract authentication schemes from OpenAPI securitySchemes.\n *\n * Document order is preserved. Each entry carries its `securitySchemes` key as\n * `schemeName` so emitters can join the requirements under `ApiSpec.security`\n * and `Operation.security` back to it.\n * Schemes the IR cannot represent are omitted with a warning rather than silently.\n */\nfunction extractAuthSchemes(securitySchemes?: Record<string, SecuritySchemeObject>): AuthScheme[] | undefined {\n if (!securitySchemes) return undefined;\n const schemes: AuthScheme[] = [];\n for (const [schemeName, scheme] of Object.entries(securitySchemes)) {\n // Omit `description` entirely (rather than setting it to undefined) when the\n // document does not declare one. An explicit empty string is a declared value\n // and is kept, so consumers can tell \"empty\" from \"missing\".\n const common = scheme.description !== undefined ? { schemeName, description: scheme.description } : { schemeName };\n // HTTP authentication scheme names are case-insensitive (RFC 9110 §11.1).\n const httpScheme = scheme.type === 'http' ? scheme.scheme?.toLowerCase() : undefined;\n if (httpScheme === 'bearer') {\n schemes.push({ kind: 'bearer', ...common });\n } else if (httpScheme === 'basic') {\n schemes.push({ kind: 'basic', ...common });\n } else if (scheme.type === 'apiKey' && scheme.in && scheme.name) {\n schemes.push({ kind: 'apiKey', ...common, in: scheme.in as 'header' | 'query' | 'cookie', name: scheme.name });\n } else if (scheme.type === 'oauth2' && scheme.flows) {\n schemes.push({ kind: 'oauth2', ...common, flows: scheme.flows });\n } else {\n // Other http schemes (digest, ...), openIdConnect, mutualTLS, and malformed\n // entries have no IR representation; say so instead of dropping them silently.\n const detail = scheme.type === 'http' ? `type: http, scheme: ${scheme.scheme}` : `type: ${scheme.type}`;\n console.warn(`[oagen] Warning: Unsupported security scheme \"${schemeName}\" (${detail}) omitted from spec.auth`);\n }\n }\n return schemes.length > 0 ? schemes : undefined;\n}\n","/**\n * Shared infrastructure for smoke tests.\n *\n * Types, operation planning, payload generation, ID registry, and capture format\n * used by both raw HTTP and SDK smoke test scripts.\n */\n\nimport 'dotenv/config';\nimport { readFileSync } from 'node:fs';\nimport type { ApiSpec, Operation, Parameter, TypeRef } from '../../src/ir/types.js';\nimport { toSnakeCase, toCamelCase } from '../../src/utils/naming.js';\n\n// Re-export types and functions that external smoke runners need from oagen core.\n// External runners import from '@workos/oagen/smoke' which bundles this module.\nexport { parseSpec } from '../../src/parser/parse.js';\nexport { toCamelCase, toSnakeCase } from '../../src/utils/naming.js';\n\n// ---------------------------------------------------------------------------\n// Capture format\n// ---------------------------------------------------------------------------\n\nexport interface ExchangeProvenance {\n resolutionTier: 'exact' | 'crud-prefix' | 'fuzzy' | 'manifest';\n resolutionConfidence: number;\n sdkMethodName: string;\n captureIndex: number;\n totalCaptures: number;\n}\n\nexport interface CapturedExchange {\n operationId: string;\n service: string;\n operationName: string;\n request: {\n method: string;\n path: string;\n queryParams: Record<string, string>;\n body: unknown | null;\n };\n response: {\n status: number;\n body: unknown | null;\n };\n outcome: 'success' | 'api-error' | 'skipped';\n error?: string;\n /** True when the response status code is not declared in the OpenAPI spec for this operation */\n unexpectedStatus?: boolean;\n /** Status codes declared in the OpenAPI spec (success + error codes) */\n expectedStatusCodes?: number[];\n durationMs: number;\n /** How the SDK method was resolved and which capture was selected */\n provenance?: ExchangeProvenance;\n}\n\nexport interface SmokeResults {\n source: 'raw' | 'spec-baseline' | `sdk-${string}`;\n timestamp: string;\n specVersion: string;\n exchanges: CapturedExchange[];\n}\n\n// ---------------------------------------------------------------------------\n// Operation planning\n// ---------------------------------------------------------------------------\n\nexport interface PlannedOperation {\n service: string;\n operation: Operation;\n}\n\nexport interface PlannedGroup {\n service: string;\n operations: PlannedOperation[];\n}\n\n// ---------------------------------------------------------------------------\n// Smoke config — mutable state populated by loadSmokeConfig()\n// ---------------------------------------------------------------------------\n\n/** Operations that require complex preconditions and can't be auto-tested */\nexport let SKIP_OPERATIONS = new Set<string>();\n\n/** Services to skip entirely */\nexport let SKIP_SERVICES = new Set<string>();\n\n/**\n * Services that produce IDs other services depend on should run first.\n * Lower number = runs earlier. Unlisted services default to 50.\n */\nlet SERVICE_PRIORITY: Record<string, number> = {};\n\n/**\n * Map IR service names to SDK property names on the client object.\n * Empty = use toCamelCase(serviceName) as fallback.\n */\nexport let SERVICE_PROPERTY_MAP: Record<string, string> = {};\n\nexport interface SmokeConfig {\n skipOperations: string[];\n skipServices: string[];\n servicePriority: Record<string, number>;\n servicePropertyMap: Record<string, string>;\n}\n\n/** Load smoke test configuration from a JSON file */\nexport function loadSmokeConfig(configPath?: string): void {\n if (!configPath) return;\n const raw = readFileSync(configPath, 'utf-8');\n const config: SmokeConfig = JSON.parse(raw);\n\n if (config.skipOperations) SKIP_OPERATIONS = new Set(config.skipOperations);\n if (config.skipServices) SKIP_SERVICES = new Set(config.skipServices);\n if (config.servicePriority) SERVICE_PRIORITY = config.servicePriority;\n if (config.servicePropertyMap) SERVICE_PROPERTY_MAP = config.servicePropertyMap;\n}\n\n/** Return the current smoke config values (for diff.ts to consume) */\nexport function getSmokeConfig() {\n return {\n skipOperations: SKIP_OPERATIONS,\n skipServices: SKIP_SERVICES,\n servicePriority: SERVICE_PRIORITY,\n servicePropertyMap: SERVICE_PROPERTY_MAP,\n };\n}\n\n/**\n * Assign a numeric sort key to an operation so that ID-producing operations\n * (parameterless creates and lists) run before ID-consuming ones.\n */\nfunction operationSortKey(op: Operation): number {\n const hasParams = op.pathParams.length > 0;\n const method = op.httpMethod;\n\n if (method === 'post' && !hasParams) return 0; // top-level create\n if (method === 'get' && !hasParams && op.pagination) return 1; // top-level list\n if (method === 'get' && !hasParams) return 2; // top-level singular GET\n if (method === 'post' && hasParams) return 3; // sub-entity create\n if (method === 'get' && hasParams && op.pagination) return 4; // sub-entity list\n if (method === 'get' && hasParams) return 5; // singular GET by ID\n if (method === 'put' || method === 'patch') return 6; // update\n if (method === 'delete') return 7; // delete\n return 99;\n}\n\nexport function planOperations(spec: ApiSpec): PlannedGroup[] {\n const groups: PlannedGroup[] = [];\n\n for (const service of spec.services) {\n if (SKIP_SERVICES.has(service.name)) continue;\n\n const ops: PlannedOperation[] = [];\n for (const op of service.operations) {\n if (SKIP_OPERATIONS.has(op.name)) continue;\n\n ops.push({ service: service.name, operation: op });\n }\n\n if (ops.length === 0) continue;\n\n // Sort to maximize ID availability:\n // 1. Parameterless POSTs (create new top-level entities → produce IDs)\n // 2. Parameterless list GETs (discover existing IDs)\n // 3. Parameterized POSTs (create sub-entities, need parent IDs)\n // 4. Parameterized list GETs\n // 5. Parameterized singular GETs (retrieve by ID)\n // 6. PUT/PATCH (update)\n // 7. DELETE\n ops.sort((a, b) => {\n return operationSortKey(a.operation) - operationSortKey(b.operation);\n });\n\n groups.push({ service: service.name, operations: ops });\n }\n\n // Sort service groups so ID-producing services run first\n groups.sort((a, b) => {\n const aPri = SERVICE_PRIORITY[a.service] ?? 50;\n const bPri = SERVICE_PRIORITY[b.service] ?? 50;\n return aPri - bPri;\n });\n\n return groups;\n}\n\n// ---------------------------------------------------------------------------\n// Wave-based operation planning for batched runners\n// ---------------------------------------------------------------------------\n\n/**\n * A single wave of operations that can be planned and executed together.\n * Wave 0 contains parameterless operations. Subsequent waves contain\n * operations whose path params became resolvable after earlier waves ran.\n */\nexport interface OperationWave {\n /** Operations in this wave, with pre-resolved path params */\n calls: Array<{\n op: Operation;\n irService: string;\n pathParams: Record<string, string>;\n }>;\n}\n\n/**\n * Plan operations in waves so that batched runners can execute each wave,\n * extract IDs from responses, then plan the next wave.\n *\n * Returns an iterator that yields one wave at a time. The caller must\n * execute each wave and populate the IdRegistry before calling next().\n *\n * @param groups - service groups from planOperations()\n * @param ids - the IdRegistry (mutated by the caller between waves)\n * @param resolveMethod - optional filter; return null to skip an operation\n */\nexport function* planWaves(\n groups: PlannedGroup[],\n ids: IdRegistry,\n resolveMethod?: (op: Operation, irService: string) => boolean,\n): Generator<OperationWave, PlannedOperation[], void> {\n // Flatten all operations into a single ordered list\n const remaining: PlannedOperation[] = [];\n for (const group of groups) {\n for (const planned of group.operations) {\n remaining.push(planned);\n }\n }\n\n // Track which operations have been emitted\n const emitted = new Set<number>();\n const skipped: PlannedOperation[] = [];\n\n // Pre-filter: mark operations that fail the resolveMethod check as skipped\n for (let i = 0; i < remaining.length; i++) {\n const { operation: op, service: irService } = remaining[i];\n if (resolveMethod && !resolveMethod(op, irService)) {\n emitted.add(i);\n skipped.push(remaining[i]);\n }\n }\n\n // Wave 0: operations with no path params\n let wave: OperationWave = { calls: [] };\n for (let i = 0; i < remaining.length; i++) {\n if (emitted.has(i)) continue;\n const { operation: op, service: irService } = remaining[i];\n if (op.pathParams.length === 0) {\n wave.calls.push({ op, irService, pathParams: {} });\n emitted.add(i);\n }\n }\n\n if (wave.calls.length > 0) {\n yield wave;\n }\n\n // Subsequent waves: try to resolve remaining operations\n let madeProgress = true;\n while (madeProgress) {\n madeProgress = false;\n wave = { calls: [] };\n\n for (let i = 0; i < remaining.length; i++) {\n if (emitted.has(i)) continue;\n const { operation: op, service: irService } = remaining[i];\n\n const resolved = ids.resolvePathParams(op, irService);\n if (resolved) {\n wave.calls.push({ op, irService, pathParams: resolved });\n emitted.add(i);\n madeProgress = true;\n }\n }\n\n if (wave.calls.length > 0) {\n yield wave;\n }\n }\n\n // Collect truly unresolvable operations for the caller to mark as skipped\n const unresolved: PlannedOperation[] = [];\n for (let i = 0; i < remaining.length; i++) {\n if (!emitted.has(i)) {\n unresolved.push(remaining[i]);\n }\n }\n return unresolved;\n}\n\n// ---------------------------------------------------------------------------\n// Payload generation\n// ---------------------------------------------------------------------------\n\nexport function generateFixtureValue(typeRef: TypeRef, fieldName: string, spec: ApiSpec): unknown {\n switch (typeRef.kind) {\n case 'primitive':\n return generatePrimitiveFixture(typeRef.type, typeRef.format, fieldName);\n case 'array':\n return [generateFixtureValue(typeRef.items, fieldName, spec)];\n case 'model': {\n const model = spec.models.find((m) => m.name === typeRef.name);\n if (model) {\n const obj: Record<string, unknown> = {};\n for (const field of model.fields) {\n if (field.required) {\n obj[toSnakeCase(field.name)] = generateFixtureValue(field.type, field.name, spec);\n }\n }\n return obj;\n }\n return {};\n }\n case 'enum': {\n const e = spec.enums.find((en) => en.name === typeRef.name);\n return e?.values[0]?.value ?? 'unknown';\n }\n case 'nullable':\n return generateFixtureValue(typeRef.inner, fieldName, spec);\n case 'union':\n if (typeRef.variants.length > 0) {\n return generateFixtureValue(typeRef.variants[0], fieldName, spec);\n }\n return null;\n }\n}\n\nfunction generatePrimitiveFixture(type: string, format: string | undefined, fieldName: string): unknown {\n if (type === 'string') {\n if (format === 'uuid') return '550e8400-e29b-41d4-a716-446655440000';\n if (format === 'date') return '2024-01-01';\n if (format === 'date-time') return '2024-01-01T00:00:00Z';\n if (format === 'email') return 'test@example.com';\n if (format === 'uri' || format === 'url') return 'https://example.com';\n return `test_${toSnakeCase(fieldName)}`;\n }\n if (type === 'integer') return 1;\n if (type === 'number') return 1.0;\n if (type === 'boolean') return true;\n return null;\n}\n\n/** Generate a snake_case request body payload from an operation's requestBody type */\nexport function generatePayload(op: Operation, spec: ApiSpec): Record<string, unknown> | null {\n if (!op.requestBody) return null;\n\n const bodyType = op.requestBody;\n if (bodyType.kind === 'model') {\n const model = spec.models.find((m) => m.name === bodyType.name);\n if (!model) return {};\n\n const payload: Record<string, unknown> = {};\n for (const field of model.fields) {\n if (!field.required) continue;\n const key = toSnakeCase(field.name);\n let value = generateFixtureValue(field.type, field.name, spec);\n\n // Inject uniqueness markers for name/slug fields\n if ((key === 'name' || key === 'slug') && typeof value === 'string') {\n value = `smoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n payload[key] = value;\n }\n return payload;\n }\n\n // Fallback for non-model body types\n return {};\n}\n\n/** Generate a fixture value with SDK-friendly types (e.g. Date objects for date-time) */\nfunction generateSDKFixtureValue(typeRef: TypeRef, fieldName: string, spec: ApiSpec): unknown {\n const value = generateFixtureValue(typeRef, fieldName, spec);\n // SDK methods expect Date objects for date-time fields, not ISO strings\n if (typeRef.kind === 'primitive' && typeRef.format === 'date-time' && typeof value === 'string') {\n return new Date(value);\n }\n return value;\n}\n\n/** Generate a camelCase payload for SDK method calls */\nexport function generateCamelPayload(op: Operation, spec: ApiSpec): Record<string, unknown> | null {\n if (!op.requestBody) return null;\n\n const bodyType = op.requestBody;\n if (bodyType.kind === 'model') {\n const model = spec.models.find((m) => m.name === bodyType.name);\n if (!model) return {};\n\n const payload: Record<string, unknown> = {};\n for (const field of model.fields) {\n if (!field.required) continue;\n const key = toCamelCase(field.name);\n let value = generateSDKFixtureValue(field.type, field.name, spec);\n\n if ((field.name === 'name' || field.name === 'slug') && typeof value === 'string') {\n value = `smoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n payload[key] = value;\n }\n return payload;\n }\n\n return {};\n}\n\n/** Generate query params for an operation (required params only, plus limit=1 for lists) */\nexport function generateQueryParams(op: Operation, spec: ApiSpec): Record<string, string> {\n const params: Record<string, string> = {};\n\n if (op.pagination) {\n params['limit'] = '1';\n }\n\n for (const p of op.queryParams) {\n if (!p.required) continue;\n const value = generateFixtureValue(p.type, p.name, spec);\n params[toSnakeCase(p.name)] = String(value);\n }\n\n // Sort by key\n const sorted: Record<string, string> = {};\n for (const key of Object.keys(params).sort()) {\n sorted[key] = params[key];\n }\n return sorted;\n}\n\n/** Generate camelCase query params for SDK method calls */\nexport function generateCamelQueryParams(op: Operation, spec: ApiSpec): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (op.pagination) {\n params['limit'] = 1;\n }\n\n for (const p of op.queryParams) {\n if (!p.required) continue;\n const value = generateFixtureValue(p.type, p.name, spec);\n params[toCamelCase(p.name)] = value;\n }\n\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// ID Registry\n// ---------------------------------------------------------------------------\n\nexport class IdRegistry {\n private ids = new Map<string, string>();\n\n set(service: string, field: string, value: string): void {\n this.ids.set(`${service}.${field}`, value);\n }\n\n get(service: string, field: string): string | undefined {\n return this.ids.get(`${service}.${field}`);\n }\n\n /** Resolve path parameters for an operation using stored IDs */\n resolvePathParams(op: Operation, service: string): Record<string, string> | null {\n const resolved: Record<string, string> = {};\n for (const p of op.pathParams) {\n const value =\n this.get(service, p.name) ||\n this.get(service, 'id') ||\n this.findAcrossServices(p.name) ||\n this.resolveFromParamName(p.name) ||\n this.resolveFromExample(p);\n\n if (!value) return null;\n resolved[p.name] = value;\n }\n return resolved;\n }\n\n /** Try to find a param value across all services */\n private findAcrossServices(field: string): string | undefined {\n for (const [key, value] of this.ids.entries()) {\n if (key.endsWith(`.${field}`)) return value;\n }\n // Also try snake_case variant: \"organizationId\" → \"organization_id\"\n const snakeField = toSnakeCase(field);\n if (snakeField !== field) {\n for (const [key, value] of this.ids.entries()) {\n if (key.endsWith(`.${snakeField}`)) return value;\n }\n }\n return undefined;\n }\n\n /**\n * Resolve a path param like \"organizationId\" by mapping it to the\n * service that stores that entity's ID (e.g. Organizations.id).\n * Also handles snake_case suffixed with _id by stripping the suffix\n * and looking up the pluralized service name.\n */\n private resolveFromParamName(paramName: string): string | undefined {\n // Infer from param name: \"resource_id\" → \"Resources\", \"role_assignment_id\" → \"RoleAssignments\"\n // Handle snake_case: strip trailing _id, PascalCase+pluralize the rest\n if (paramName.endsWith('_id')) {\n const base = paramName.slice(0, -3); // e.g. \"resource_type\" from \"resource_type_id\"\n const pascal = base\n .split('_')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join('');\n const plural = pascal.endsWith('s') ? pascal : pascal + 's';\n const val = this.get(plural, 'id') || this.get(plural, 'slug');\n if (val) return val;\n\n // Fallback: find any service whose name ends with the plural suffix\n // e.g. \"user_id\" → \"Users\" not found → try \"UserManagementUsers\"\n const suffixVal = this.findByServiceSuffix(plural, 'id') || this.findByServiceSuffix(plural, 'slug');\n if (suffixVal) return suffixVal;\n }\n\n // Handle camelCase: \"resourceId\" → strip \"Id\", pluralize → \"Resources\"\n if (paramName.endsWith('Id') && paramName.length > 2) {\n const base = paramName.slice(0, -2); // e.g. \"organization\"\n const pascal = base.charAt(0).toUpperCase() + base.slice(1);\n const plural = pascal.endsWith('s') ? pascal : pascal + 's';\n const val = this.get(plural, 'id') || this.get(plural, 'slug');\n if (val) return val;\n\n // Fallback: find any service whose name ends with the plural suffix\n const suffixVal = this.findByServiceSuffix(plural, 'id') || this.findByServiceSuffix(plural, 'slug');\n if (suffixVal) return suffixVal;\n }\n\n return undefined;\n }\n\n /**\n * Find a value by looking for any service name that ends with the given suffix.\n * e.g. suffix \"Users\" matches \"UserManagementUsers.id\"\n */\n private findByServiceSuffix(suffix: string, field: string): string | undefined {\n for (const [key, value] of this.ids.entries()) {\n if (key.endsWith(`.${field}`)) {\n const servicePart = key.slice(0, -(field.length + 1));\n if (servicePart.endsWith(suffix)) {\n return value;\n }\n }\n }\n return undefined;\n }\n\n /**\n * Last-resort fallback: use the spec's example or default value for a parameter.\n * Many path params (e.g. actionName, slug, type) have example values in the spec.\n */\n private resolveFromExample(param: Parameter): string | undefined {\n const value = param.example ?? param.default;\n if (value !== undefined && value !== null) {\n return String(value);\n }\n return undefined;\n }\n\n /**\n * Extract IDs from a response body and store them.\n * @param isTopLevel - true for operations without path params (their `id` belongs to this service).\n * false for sub-resource operations (their `id` is a child entity, don't overwrite).\n */\n extractAndStore(service: string, responseBody: unknown, isTopLevel = true): void {\n if (!responseBody || typeof responseBody !== 'object') return;\n\n const body = responseBody as Record<string, unknown>;\n\n // Only store direct ID from top-level operations to avoid overwriting\n // e.g. Organizations.id with an API key ID from /organizations/{id}/api_keys\n if (isTopLevel) {\n if (typeof body.id === 'string') {\n this.set(service, 'id', body.id);\n }\n\n // List response: extract from first item\n if (Array.isArray(body.data) && body.data.length > 0) {\n const first = body.data[0] as Record<string, unknown> | undefined;\n if (first && typeof first === 'object') {\n if (typeof first.id === 'string') {\n this.set(service, 'id', first.id);\n }\n this.extractNestedIds(service, first);\n }\n }\n\n if (typeof body.slug === 'string') this.set(service, 'slug', body.slug);\n if (typeof body.key === 'string') this.set(service, 'key', body.key);\n }\n\n // Always extract nested reference IDs (e.g. organization_id, connection_id)\n this.extractNestedIds(service, body);\n if (Array.isArray(body.data) && body.data.length > 0) {\n const first = body.data[0] as Record<string, unknown> | undefined;\n if (first && typeof first === 'object') {\n this.extractNestedIds(service, first);\n }\n }\n }\n\n /** Extract fields ending in _id or Id and store them for cross-service resolution */\n private extractNestedIds(service: string, obj: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value !== 'string') continue;\n if (key === 'id') continue; // already handled\n // Store fields like \"organization_id\", \"connection_id\" directly\n if (key.endsWith('_id') || (key.endsWith('Id') && key.length > 2)) {\n this.set(service, key, value);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Status code checking\n// ---------------------------------------------------------------------------\n\n/** Get the set of status codes declared in the spec for an operation (success + errors) */\nexport function getExpectedStatusCodes(op: Operation): number[] {\n const codes: number[] = [];\n // The success response code is implied by HTTP method if not explicit in errors\n // Common defaults: POST→201, GET→200, PUT→200, PATCH→200, DELETE→204\n const defaultSuccess: Record<string, number> = {\n post: 201,\n get: 200,\n put: 200,\n patch: 200,\n delete: 204,\n };\n codes.push(defaultSuccess[op.httpMethod] ?? 200);\n // Add declared error codes from the spec\n for (const err of op.errors) {\n if (!codes.includes(err.statusCode)) {\n codes.push(err.statusCode);\n }\n }\n return codes.sort((a, b) => a - b);\n}\n\n/** Check if a status code is unexpected (not declared in the spec) */\nexport function isUnexpectedStatus(status: number, op: Operation): boolean {\n if (status === 0) return false; // skipped or network error, not a status mismatch\n const expected = getExpectedStatusCodes(op);\n return !expected.includes(status);\n}\n\n// ---------------------------------------------------------------------------\n// Path resolution\n// ---------------------------------------------------------------------------\n\nexport function resolvePath(op: Operation, pathParams: Record<string, string>): string {\n let path = op.path;\n for (const [name, value] of Object.entries(pathParams)) {\n path = path.replace(`{${name}}`, value);\n }\n return path;\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\nexport function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function parseCliArgs(): { spec: string; sdkPath?: string; smokeConfig?: string } {\n const args = process.argv.slice(2);\n const specIdx = args.indexOf('--spec');\n const spec = specIdx !== -1 && args[specIdx + 1] ? args[specIdx + 1] : process.env.OPENAPI_SPEC_PATH;\n if (!spec) {\n console.error('OpenAPI spec path is required. Set OPENAPI_SPEC_PATH env var or pass --spec <path>.');\n process.exit(1);\n }\n const sdkPathIdx = args.indexOf('--sdk-path');\n const sdkPath = sdkPathIdx !== -1 && args[sdkPathIdx + 1] ? args[sdkPathIdx + 1] : undefined;\n const configIdx = args.indexOf('--smoke-config');\n const smokeConfig = configIdx !== -1 && args[configIdx + 1] ? args[configIdx + 1] : process.env.SMOKE_CONFIG;\n return { spec, sdkPath, smokeConfig };\n}\n"],"mappings":"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"}
|