@kubb/ast 5.0.0-beta.93 → 5.0.0-beta.94
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/dist/index.cjs +5 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/{types-Dno_xT4x.d.ts → types-CsAwiskn.d.ts} +9 -7
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["path"],"sources":["../src/constants.ts","../src/guards.ts","../src/defineNode.ts","../src/nodes/code.ts","../src/nodes/content.ts","../../../internals/utils/src/casing.ts","../../../internals/utils/src/fs.ts","../../../internals/utils/src/promise.ts","../src/utils/extractStringsFromNodes.ts","../src/utils/combineFileMembers.ts","../src/nodes/file.ts","../src/nodes/input.ts","../src/nodes/requestBody.ts","../src/nodes/operation.ts","../src/nodes/output.ts","../src/optionality.ts","../src/nodes/parameter.ts","../src/nodes/property.ts","../src/nodes/response.ts","../src/nodes/schema.ts","../src/registry.ts","../src/visitor.ts","../src/defineMacro.ts","../src/createPrinter.ts","../src/utils/mergeAdjacentSchemas.ts","../src/utils/refs.ts","../src/utils/schemaGraph.ts","../src/utils/schemaTraversal.ts","../src/macros/macroDiscriminatorEnum.ts","../src/macros/macroEnumName.ts","../src/macros/macroSimplifyUnion.ts","../src/factory.ts","../src/exports.ts"],"sourcesContent":["import type { SchemaType } from './nodes/schema.ts'\n\n/**\n * Traversal depth for AST visitor utilities.\n *\n * - `'shallow'` visits only the immediate node, skipping children.\n * - `'deep'` recursively visits all descendant nodes.\n */\nexport type VisitorDepth = 'shallow' | 'deep'\n\nexport const visitorDepths = {\n shallow: 'shallow',\n deep: 'deep',\n} as const satisfies Record<VisitorDepth, VisitorDepth>\n\n/**\n * Schema type discriminators used by all AST schema nodes.\n *\n * Each value is a stable discriminator across the AST (for example `schema.type === schemaTypes.object`).\n */\nexport const schemaTypes = {\n /**\n * Text value.\n */\n string: 'string',\n /**\n * Floating-point number (`float`, `double`).\n */\n number: 'number',\n /**\n * Whole number (`int32`). Use `bigint` for `int64`.\n */\n integer: 'integer',\n /**\n * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.\n */\n bigint: 'bigint',\n /**\n * Boolean value.\n */\n boolean: 'boolean',\n /**\n * Explicit null value.\n */\n null: 'null',\n /**\n * Any value (no type restriction).\n */\n any: 'any',\n /**\n * Unknown value (must be narrowed before usage).\n */\n unknown: 'unknown',\n /**\n * No return value (`void`).\n */\n void: 'void',\n /**\n * Object with named properties.\n */\n object: 'object',\n /**\n * Sequential list of items.\n */\n array: 'array',\n /**\n * Fixed-length list with position-specific items.\n */\n tuple: 'tuple',\n /**\n * \"One of\" multiple schema members.\n */\n union: 'union',\n /**\n * \"All of\" multiple schema members.\n */\n intersection: 'intersection',\n /**\n * Enum schema.\n */\n enum: 'enum',\n /**\n * Reference to another schema.\n */\n ref: 'ref',\n /**\n * Calendar date (for example `2026-03-24`).\n */\n date: 'date',\n /**\n * Date-time value (for example `2026-03-24T09:00:00Z`).\n */\n datetime: 'datetime',\n /**\n * Time-only value (for example `09:00:00`).\n */\n time: 'time',\n /**\n * UUID value.\n */\n uuid: 'uuid',\n /**\n * Email address value.\n */\n email: 'email',\n /**\n * URL value.\n */\n url: 'url',\n /**\n * IPv4 address value.\n */\n ipv4: 'ipv4',\n /**\n * IPv6 address value.\n */\n ipv6: 'ipv6',\n /**\n * Binary/blob value.\n */\n blob: 'blob',\n /**\n * Impossible value (`never`).\n */\n never: 'never',\n} as const satisfies Record<SchemaType, SchemaType>\n","import type { HttpOperationNode, OperationNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'\n\n/**\n * Narrows a `SchemaNode` to the variant that matches `type`.\n *\n * @example\n * ```ts\n * const schema = createSchema({ type: 'string' })\n * const stringNode = narrowSchema(schema, 'string') // StringSchemaNode | null\n * ```\n */\nexport function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | null {\n return node?.type === type ? (node as SchemaNodeByType[T]) : null\n}\n\n/**\n * Narrows an `OperationNode` to an `HttpOperationNode` so `method` and `path` are present.\n *\n * @example\n * ```ts\n * if (isHttpOperationNode(node)) {\n * console.log(node.method, node.path)\n * }\n * ```\n */\nexport function isHttpOperationNode(node: OperationNode): node is HttpOperationNode {\n return node.protocol === 'http' || (node.method !== undefined && node.path !== undefined)\n}\n","import type { BaseNode, NodeKind } from './nodes/base.ts'\n\n/**\n * Visitor callback names, one per traversable node kind, in traversal order.\n * Kept in sync with the keys of `Visitor` in `visitor.ts`.\n */\nexport const visitorKeys = ['input', 'output', 'operation', 'schema', 'property', 'parameter', 'response'] as const\n\n/**\n * One of the {@link visitorKeys} callback names.\n */\nexport type VisitorKey = (typeof visitorKeys)[number]\n\n/**\n * Distributive `Omit` that preserves each member of a union.\n *\n * @example\n * ```ts\n * type A = { kind: 'a'; keep: string; drop: number }\n * type B = { kind: 'b'; keep: boolean; drop: number }\n * type Result = DistributiveOmit<A | B, 'drop'>\n * // -> { kind: 'a'; keep: string } | { kind: 'b'; keep: boolean }\n * ```\n */\nexport type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Builds a type guard that matches nodes of the given `kind`.\n */\nfunction isKind<T extends BaseNode>(kind: NodeKind) {\n return (node: unknown): node is T => (node as BaseNode | undefined)?.kind === kind\n}\n\n/**\n * The single definition derived from one {@link defineNode} call: the node's\n * `create` builder, its `is` guard, and the traversal metadata the registry\n * collects into the visitor tables.\n */\nexport type NodeDef<TNode extends BaseNode = BaseNode, TInput = never> = {\n /**\n * Node discriminator this definition owns.\n */\n kind: NodeKind\n /**\n * Builds a node from its input, applying `defaults` and the optional `build` hook.\n */\n create: (input: TInput) => TNode\n /**\n * Type guard matching this node kind.\n */\n is: (node: unknown) => node is TNode\n /**\n * Child node fields in traversal order. Feeds `VISITOR_KEYS`.\n */\n children?: ReadonlyArray<string>\n /**\n * Visitor callback name. Feeds `VISITOR_KEY_BY_KIND`.\n */\n visitorKey?: VisitorKey\n}\n\ntype DefineNodeConfig<TNode extends BaseNode, TInput, TBuilt extends object> = {\n kind: TNode['kind']\n defaults?: Partial<TNode>\n build?: (input: TInput) => TBuilt\n children?: ReadonlyArray<string>\n visitorKey?: VisitorKey\n}\n\n/**\n * Defines a node once and derives its `create` builder, `is` guard, and traversal\n * metadata. `create` merges `defaults`, the `build` hook (or the raw input), and the\n * `kind`, so node construction lives in one place without scattered `as` casts.\n *\n * @example Simple node\n * ```ts\n * const importDef = defineNode<ImportNode>({ kind: 'Import' })\n * const createImport = importDef.create\n * ```\n *\n * @example Node with a build hook\n * ```ts\n * const propertyDef = defineNode<PropertyNode, UserPropertyNode>({\n * kind: 'Property',\n * build: (props) => ({ ...props, required: props.required ?? false }),\n * children: ['schema'],\n * visitorKey: 'property',\n * })\n * ```\n */\nexport function defineNode<TNode extends BaseNode, TInput = Omit<TNode, 'kind'>, TBuilt extends object = Omit<TNode, 'kind'>>(\n config: DefineNodeConfig<TNode, TInput, TBuilt>,\n): NodeDef<TNode, TInput> {\n const { kind, defaults, build, children, visitorKey } = config\n\n function create(input: TInput): TNode {\n const base = build ? build(input) : input\n // `kind` is written first so the discriminant lands at a fixed in-object offset for every node\n // of this kind. Hot dispatch paths (`transform`, `walk`, the parser printers) read `node.kind`\n // constantly; a trailing-only `kind` floats its offset with each node's field count and turns\n // those reads megamorphic. The post-spread reassignment keeps `kind` authoritative when an input\n // carries a (wrong) `kind`: it overwrites the offset-0 slot in place without reshaping the node.\n const node = { kind, ...defaults, ...(base as object) } as TNode\n node.kind = kind\n return node\n }\n\n return { kind, create, is: isKind<TNode>(kind), children, visitorKey }\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\n\n/**\n * JSDoc documentation metadata attached to code declarations.\n */\nexport type JSDocNode = {\n /**\n * JSDoc comment lines. `undefined` entries are filtered out during rendering.\n *\n * @example\n * ```ts\n * ['@description A pet resource', '@deprecated']\n * ```\n */\n comments?: Array<string | undefined>\n}\n\n/**\n * AST node representing a TypeScript `const` declaration.\n *\n * Mirrors the props of the `Const` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createConst({ name: 'pet', export: true, asConst: true })\n * // export const pet = ... as const\n * ```\n */\nexport type ConstNode = BaseNode & {\n kind: 'Const'\n /**\n * Name of the constant declaration.\n */\n name: string\n /**\n * Whether the declaration should be exported.\n */\n export?: boolean | null\n /**\n * Explicit type annotation.\n *\n * @example Type reference\n * `'Pet'`\n */\n type?: string | null\n /**\n * JSDoc documentation metadata.\n */\n JSDoc?: JSDocNode | null\n /**\n * Whether to append `as const` to the declaration.\n */\n asConst?: boolean | null\n /**\n * Child nodes representing the value of the constant (children of the `Const` component).\n * Each entry is a {@link CodeNode}. Use {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * AST node representing a TypeScript `type` alias declaration.\n *\n * Mirrors the props of the `Type` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createType({ name: 'Pet', export: true })\n * // export type Pet = ...\n * ```\n */\nexport type TypeNode = BaseNode & {\n kind: 'Type'\n /**\n * Name of the type alias.\n */\n name: string\n /**\n * Whether the declaration should be exported.\n */\n export?: boolean | null\n /**\n * JSDoc documentation metadata.\n */\n JSDoc?: JSDocNode | null\n /**\n * Child nodes representing the type body (children of the `Type` component).\n * Each entry is a {@link CodeNode}. Use {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * AST node representing a TypeScript `function` declaration.\n *\n * Mirrors the props of the `Function` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createFunctionDeclaration({ name: 'getPet', export: true, async: true, returnType: 'Pet' })\n * // export async function getPet(): Promise<Pet> { ... }\n * ```\n */\nexport type FunctionNode = BaseNode & {\n kind: 'Function'\n /**\n * Name of the function.\n */\n name: string\n /**\n * Whether the function is a default export.\n */\n default?: boolean | null\n /**\n * Function parameter list as a pre-rendered string, written verbatim between the parentheses.\n *\n * @example\n * `'id: string, config: Config = {}'`\n */\n params?: string | null\n /**\n * Whether the function should be exported.\n */\n export?: boolean | null\n /**\n * Whether the function is async. When `true`, the return type is wrapped in `Promise<>`.\n */\n async?: boolean | null\n /**\n * TypeScript generic type parameters.\n *\n * @example Constrained generics\n * `['T', 'U extends string']`\n */\n generics?: string | Array<string> | null\n /**\n * Return type annotation.\n *\n * @example Type reference\n * `'Pet'`\n */\n returnType?: string | null\n /**\n * JSDoc documentation metadata.\n */\n JSDoc?: JSDocNode | null\n /**\n * Child nodes representing the function body (children of the `Function` component).\n * Each entry is a {@link CodeNode}. Use {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * AST node representing a TypeScript arrow function (`const name = () => { ... }`).\n *\n * Mirrors the props of the `Function.Arrow` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createArrowFunctionDeclaration({ name: 'getPet', export: true, singleLine: true })\n * // export const getPet = () => ...\n * ```\n */\nexport type ArrowFunctionNode = Omit<FunctionNode, 'kind'> & {\n kind: 'ArrowFunction'\n /**\n * Render the arrow function body as a single-line expression.\n */\n singleLine?: boolean | null\n}\n\n/**\n * AST node representing a raw text/string fragment in the source output.\n *\n * Used instead of bare `string` values so that all entries in `nodes` arrays\n * are typed `CodeNode` objects rather than a mixed `CodeNode | string` union.\n *\n * @example\n * ```ts\n * createText('return fetch(id)')\n * // { kind: 'Text', value: 'return fetch(id)' }\n * ```\n */\nexport type TextNode = BaseNode & {\n kind: 'Text'\n /**\n * The raw string content.\n */\n value: string\n}\n\n/**\n * AST node representing a blank line in the source output.\n *\n * Corresponds to `<br/>` in JSX components. `printNodes` turns a `Break` between two\n * statements into one blank line. Consecutive breaks, and breaks at the start or end of\n * the list, are folded away, so a `Break` never produces more than one blank line.\n *\n * @example\n * ```ts\n * createBreak()\n * // { kind: 'Break' }\n * ```\n */\nexport type BreakNode = BaseNode & {\n kind: 'Break'\n}\n\n/**\n * AST node representing a raw JSX fragment in the source output.\n *\n * Mirrors the `Jsx` component from `@kubb/renderer-jsx`. Embeds raw JSX/TSX markup\n * (including fragments `<>…</>`) directly in generated code.\n *\n * @example\n * ```ts\n * createJsx('<>\\n <a href={href}>Open</a>\\n</>')\n * // { kind: 'Jsx', value: '<>\\n <a href={href}>Open</a>\\n</>' }\n * ```\n */\nexport type JsxNode = BaseNode & {\n kind: 'Jsx'\n /**\n * The raw JSX string content.\n */\n value: string\n}\n\n/**\n * Union of all code-generation AST nodes.\n *\n * These nodes mirror the JSX components from `@kubb/renderer-jsx` and are used as\n * structured children in {@link SourceNode.nodes}.\n */\nexport type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode | TextNode | BreakNode | JsxNode\n\n/**\n * Definition for the {@link ConstNode}.\n */\nexport const constDef = defineNode<ConstNode>({ kind: 'Const' })\n\n/**\n * Definition for the {@link TypeNode}.\n */\nexport const typeDef = defineNode<TypeNode>({ kind: 'Type' })\n\n/**\n * Definition for the {@link FunctionNode}.\n */\nexport const functionDef = defineNode<FunctionNode>({ kind: 'Function' })\n\n/**\n * Definition for the {@link ArrowFunctionNode}.\n */\nexport const arrowFunctionDef = defineNode<ArrowFunctionNode>({ kind: 'ArrowFunction' })\n\n/**\n * Definition for the {@link TextNode}.\n */\nexport const textDef = defineNode<TextNode, string>({ kind: 'Text', build: (value) => ({ value }) })\n\n/**\n * Definition for the {@link BreakNode}.\n */\nexport const breakDef = defineNode<BreakNode, void>({ kind: 'Break', build: () => ({}) })\n\n/**\n * Definition for the {@link JsxNode}.\n */\nexport const jsxDef = defineNode<JsxNode, string>({ kind: 'Jsx', build: (value) => ({ value }) })\n\n/**\n * Creates a `ConstNode` representing a TypeScript `const` declaration.\n *\n * @example Exported constant with type and `as const`\n * ```ts\n * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })\n * // export const pets: Pet[] = ... as const\n * ```\n */\nexport const createConst = constDef.create\n\n/**\n * Creates a `TypeNode` representing a TypeScript `type` alias declaration.\n *\n * @example\n * ```ts\n * createType({ name: 'Pet', export: true })\n * // export type Pet = ...\n * ```\n */\nexport const createType = typeDef.create\n\n/**\n * Creates a `FunctionNode` representing a TypeScript `function` declaration.\n *\n * @example\n * ```ts\n * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })\n * // export async function fetchPet(): Promise<Pet> { ... }\n * ```\n */\nexport const createFunction = functionDef.create\n\n/**\n * Creates an `ArrowFunctionNode` representing a TypeScript arrow function.\n *\n * @example\n * ```ts\n * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })\n * // export const double = (n: number) => ...\n * ```\n */\nexport const createArrowFunction = arrowFunctionDef.create\n\n/**\n * Creates a {@link TextNode} representing a raw string fragment in the source output.\n *\n * @example\n * ```ts\n * createText('return fetch(id)')\n * // { kind: 'Text', value: 'return fetch(id)' }\n * ```\n */\nexport const createText = textDef.create\n\n/**\n * Creates a {@link BreakNode} representing a line break in the source output.\n *\n * @example\n * ```ts\n * createBreak()\n * // { kind: 'Break' }\n * ```\n */\nexport function createBreak(): BreakNode {\n return breakDef.create()\n}\n\n/**\n * Creates a {@link JsxNode} representing a raw JSX fragment in the source output.\n *\n * @example\n * ```ts\n * createJsx('<>\\n <a href={href}>Open</a>\\n</>')\n * // { kind: 'Jsx', value: '<>\\n <a href={href}>Open</a>\\n</>' }\n * ```\n */\nexport const createJsx = jsxDef.create\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * AST node representing one content-type entry of a request body or response.\n *\n * There is one entry per content type declared in the spec (e.g. `application/json`,\n * `multipart/form-data`), and each entry holds its own body schema.\n *\n * @example\n * ```ts\n * const content: ContentNode = {\n * kind: 'Content',\n * contentType: 'application/json',\n * schema: createSchema({ type: 'string' }),\n * }\n * ```\n */\nexport type ContentNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Content'\n /**\n * The content type for this entry (e.g. `'application/json'`).\n */\n contentType: string\n /**\n * Body schema for this content type.\n */\n schema?: SchemaNode\n /**\n * Property keys to exclude from the generated type via `Omit<Type, Keys>`.\n * Set when a referenced schema has `readOnly`/`writeOnly` fields that should be omitted.\n */\n keysToOmit?: Array<string> | null\n}\n\n/**\n * Definition for the {@link ContentNode}.\n */\nexport const contentDef = defineNode<ContentNode>({\n kind: 'Content',\n children: ['schema'],\n})\n\n/**\n * Creates a `ContentNode` for a single request-body or response content type.\n */\nexport const createContent = contentDef.create\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n","import { existsSync } from 'node:fs'\nimport { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { dirname, join, posix, resolve } from 'node:path'\nimport { camelCase } from './casing.ts'\nimport { runtime } from './runtime.ts'\n\n/**\n * Walks up the directory tree from `cwd` (defaults to `process.cwd()`) and\n * returns the absolute path of the nearest `package.json`, or `null` when none\n * is found before reaching the filesystem root.\n *\n * @example\n * ```ts\n * const pkgPath = findPackageJSON('/home/user/project/src') // '/home/user/project/package.json'\n * ```\n */\nexport function findPackageJSON(cwd?: string): string | null {\n let dir = cwd ? resolve(cwd) : process.cwd()\n while (true) {\n const pkgPath = join(dir, 'package.json')\n if (existsSync(pkgPath)) return pkgPath\n const parent = dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n}\n\n/**\n * Converts all backslashes to forward slashes.\n * Extended-length Windows paths (`\\\\?\\...`) are left unchanged.\n */\nfunction toSlash(p: string): string {\n if (p.startsWith('\\\\\\\\?\\\\')) return p\n\n return p.replaceAll('\\\\', '/')\n}\n\n/**\n * Returns the relative path from `rootDir` to `filePath`, always using forward slashes\n * and prefixed with `./` when not already traversing upward.\n *\n * @example\n * ```ts\n * getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'\n * getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'\n * ```\n */\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = posix.relative(toSlash(rootDir), toSlash(filePath))\n\n return relativePath.startsWith('../') ? relativePath : `./${relativePath}`\n}\n\n/**\n * Resolves to `true` when the file or directory at `path` exists.\n * Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.\n *\n * @example\n * ```ts\n * if (await exists('./kubb.config.ts')) {\n * const content = await read('./kubb.config.ts')\n * }\n * ```\n */\nexport async function exists(path: string): Promise<boolean> {\n if (runtime.isBun) {\n return Bun.file(path).exists()\n }\n return access(path).then(\n () => true,\n () => false,\n )\n}\n\n/**\n * Reads the file at `path` as a UTF-8 string.\n * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.\n *\n * @example\n * ```ts\n * const source = await read('./src/Pet.ts')\n * ```\n */\nexport async function read(path: string): Promise<string> {\n if (runtime.isBun) {\n return Bun.file(path).text()\n }\n return readFile(path, { encoding: 'utf8' })\n}\n\ntype WriteOptions = {\n /**\n * When `true`, re-reads the file immediately after writing and throws if the\n * content does not match — useful for catching write failures on unreliable file systems.\n */\n sanity?: boolean\n}\n\n/**\n * Writes `data` to `path`, trimming leading/trailing whitespace before saving.\n * Skips the write when the trimmed content is empty or identical to what is already on disk.\n * Creates any missing parent directories automatically.\n * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.\n *\n * @example\n * ```ts\n * await write('./src/Pet.ts', source) // writes and returns trimmed content\n * await write('./src/Pet.ts', source) // null — file unchanged\n * await write('./src/Pet.ts', ' ') // null — empty content skipped\n * ```\n */\nexport async function write(path: string, data: string, options: WriteOptions = {}): Promise<string | null> {\n const trimmed = data.trim()\n if (trimmed === '') return null\n\n const resolved = resolve(path)\n\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n const oldContent = (await file.exists()) ? await file.text() : null\n if (oldContent === trimmed) return null\n await Bun.write(resolved, trimmed)\n return trimmed\n }\n\n try {\n const oldContent = await readFile(resolved, { encoding: 'utf-8' })\n if (oldContent === trimmed) return null\n } catch {\n /* file doesn't exist yet */\n }\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, trimmed, { encoding: 'utf-8' })\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n if (savedData !== trimmed) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n return savedData\n }\n\n return trimmed\n}\n\n/**\n * Recursively removes `path`. Silently succeeds when `path` does not exist.\n *\n * @example\n * ```ts\n * await clean('./dist')\n * ```\n */\nexport async function clean(path: string): Promise<void> {\n return rm(path, { recursive: true, force: true })\n}\n\n/**\n * Converts a filesystem path to use POSIX (`/`) separators.\n *\n * Most of the codebase compares and composes paths as strings (prefix matching, joining for\n * import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated\n * paths, but on Windows it returns `\\`-separated paths, which breaks every such comparison.\n *\n * Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the\n * code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is\n * exercisable from POSIX CI.\n *\n * @example\n * toPosixPath('C:\\\\repo\\\\src\\\\pet.ts') // 'C:/repo/src/pet.ts'\n */\nexport function toPosixPath(filePath: string): string {\n return filePath.replaceAll('\\\\', '/')\n}\n\n/**\n * Strips the file extension from a path or file name.\n * Only removes the last `.ext` segment when the dot is not part of a directory name.\n *\n * @example\n * trimExtName('petStore.ts') // 'petStore'\n * trimExtName('/src/models/pet.ts') // '/src/models/pet'\n * trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'\n * trimExtName('noExtension') // 'noExtension'\n */\nexport function trimExtName(text: string): string {\n const dotIndex = text.lastIndexOf('.')\n if (dotIndex > 0 && !text.includes('/', dotIndex)) {\n return text.slice(0, dotIndex)\n }\n return text\n}\n\n/**\n * Builds a nested file path from a dotted name. Splits on dots that precede a letter\n * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases\n * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.\n *\n * Empty segments are dropped before joining. They arise when the name starts with a dot\n * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to\n * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an\n * absolute path, letting generated files escape the configured output directory.\n *\n * @example Nested path from a dotted name\n * `toFilePath('pet.petId') // 'pet/petId'`\n *\n * @example PascalCase the final segment\n * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`\n *\n * @example Suffix applied to the final segment only\n * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`\n */\nexport function toFilePath(name: string, caseLast: (part: string) => string = camelCase): string {\n const parts = name.split(/\\.(?=[a-zA-Z])/)\n return parts\n .map((part, i) => (i === parts.length - 1 ? caseLast(part) : camelCase(part)))\n .filter(Boolean)\n .join('/')\n}\n","import { toError } from './errors.ts'\n\n/** A value that may already be resolved or still pending.\n *\n * @example\n * ```ts\n * function load(id: string): PossiblePromise<string> {\n * return cache.get(id) ?? fetchRemote(id)\n * }\n * ```\n */\nexport type PossiblePromise<T> = Promise<T> | T\n\n/** Returns `true` when `result` is a thenable `Promise`.\n *\n * @example\n * ```ts\n * isPromise(Promise.resolve(1)) // true\n * isPromise(42) // false\n * ```\n */\nexport function isPromise<T>(result: PossiblePromise<T>): result is Promise<T> {\n return result !== null && result !== undefined && typeof (result as Record<string, unknown>)['then'] === 'function'\n}\n\ntype Store<TKey, TValue> = {\n has(key: TKey): boolean\n get(key: TKey): TValue | undefined\n set(key: TKey, value: TValue): unknown\n}\n\n/**\n * Wraps `factory` with a keyed cache backed by the provided store.\n *\n * Pass a `WeakMap` for object keys (results are GC-eligible when the key is\n * collected) or a `Map` for primitive keys. For multi-argument functions,\n * nest two `memoize` calls — the outer keyed by the first argument, the\n * inner (created once per outer miss) keyed by the second.\n *\n * Because the cache is owned by the caller, it can be shared, inspected, or\n * cleared independently of the memoized function.\n *\n * @example Single WeakMap key\n * ```ts\n * const cache = new WeakMap<SchemaNode, Set<string>>()\n * const getRefs = memoize(cache, (node) => collectRefs(node))\n * ```\n *\n * @example Single Map key (primitive)\n * ```ts\n * const cache = new Map<string, Resolver>()\n * const getResolver = memoize(cache, (name) => buildResolver(name))\n * ```\n *\n * @example Two-level (object + primitive)\n * ```ts\n * const outer = new WeakMap<Params[], Map<string, Params[]>>()\n * const fn = memoize(outer, (params) => memoize(new Map(), (key) => transform(params, key)))\n * fn(params)('camelcase')\n * ```\n */\nexport function memoize<TKey, TValue>(store: Store<TKey, TValue>, factory: (key: TKey) => TValue): (key: TKey) => TValue {\n return (key: TKey): TValue => {\n if (store.has(key)) return store.get(key)!\n const value = factory(key)\n store.set(key, value)\n return value\n }\n}\n\ntype SerialRunnerOptions = {\n /**\n * The async work to serialize.\n */\n run(): Promise<void>\n /**\n * Receives errors thrown by `run`, so a failure never rejects the returned trigger.\n */\n onError(error: Error): void\n}\n\n/**\n * Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight\n * marks it dirty and runs once more after it finishes, no matter how many triggers arrived.\n * Useful for event-driven reruns (a file watcher, a queue drain) where bursts should\n * coalesce into a single trailing run.\n *\n * @example\n * ```ts\n * const rebuild = createSerialRunner({\n * run: () => build(),\n * onError: (error) => log.error(error.message),\n * })\n * watcher.on('change', () => void rebuild())\n * ```\n */\nexport function createSerialRunner({ run, onError }: SerialRunnerOptions): () => Promise<void> {\n let running = false\n let dirty = false\n\n return async (): Promise<void> => {\n if (running) {\n dirty = true\n return\n }\n running = true\n do {\n dirty = false\n try {\n await run()\n } catch (error) {\n onError(toError(error))\n }\n } while (dirty)\n running = false\n }\n}\n","import type { CodeNode } from '../nodes/code.ts'\n\n/**\n * Extracts all string content from a `CodeNode` tree recursively.\n *\n * Collects text node values, identifier references in string fields (`params`, `generics`, `returnType`, `type`),\n * and nested node content. Used to build the full source string for import filtering.\n */\nexport function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): string {\n if (!nodes?.length) return ''\n\n // Imperative single pass. The earlier `map().filter().join()` allocated a closure plus two\n // intermediate arrays per call, and this runs recursively over every code node during file\n // assembly, so the churn showed up in deopt traces. Appending directly keeps it flat.\n const collected: Array<string> = []\n\n for (const node of nodes) {\n // Backward-compat: compiled plugins may still pass bare strings at runtime\n if (typeof node === 'string') {\n if (node) collected.push(node as string)\n continue\n }\n if (node.kind === 'Text') {\n if (node.value) collected.push(node.value)\n continue\n }\n if (node.kind === 'Break') continue\n if (node.kind === 'Jsx') {\n if (node.value) collected.push(node.value)\n continue\n }\n\n const parts: Array<string> = []\n if ('params' in node && node.params) parts.push(node.params)\n if ('generics' in node && node.generics) parts.push(Array.isArray(node.generics) ? node.generics.join(', ') : node.generics)\n if ('returnType' in node && node.returnType) parts.push(node.returnType)\n if ('type' in node && typeof node.type === 'string') parts.push(node.type)\n\n const nested = extractStringsFromNodes(node.nodes)\n if (nested) parts.push(nested)\n\n if (parts.length) collected.push(parts.join('\\n'))\n }\n\n return collected.join('\\n')\n}\n","/**\n * File-member merging. `combineImports` and `combineExports` deduplicate and sort the import and\n * export entries of one file, while `combineSources` deduplicates source entries in original order.\n * `combineImports` also drops imports nothing references. This works on a file's members, not on\n * schema content.\n */\nimport type { ExportNode, ImportNode, SourceNode } from '../nodes/index.ts'\nimport { extractStringsFromNodes } from './extractStringsFromNodes.ts'\n\nfunction sourceKey(source: SourceNode): string {\n const nameKey = source.name ?? extractStringsFromNodes(source.nodes)\n return `${nameKey}:${source.isExportable ?? false}:${source.isTypeOnly ?? false}`\n}\n\nfunction pathTypeKey(path: string, isTypeOnly: boolean | null | undefined): string {\n return `${path}:${isTypeOnly ?? false}`\n}\n\nfunction exportKey(path: string, name: string | null | undefined, isTypeOnly: boolean | null | undefined, asAlias: boolean | null | undefined): string {\n return `${path}:${name ?? ''}:${isTypeOnly ?? false}:${asAlias ?? ''}`\n}\n\nfunction importKey(path: string, name: string | null | undefined, isTypeOnly: boolean | null | undefined): string {\n return `${path}:${name ?? ''}:${isTypeOnly ?? false}`\n}\n\n/**\n * Computes a multi-level sort key for exports and imports:\n * non-array names first (wildcards/namespace aliases). Type-only before value. Alphabetical path. Unnamed before named.\n */\nfunction sortKey(node: { name?: string | Array<unknown> | null; isTypeOnly?: boolean | null; path: string }): string {\n const isArray = Array.isArray(node.name) ? '1' : '0'\n const typeOnly = node.isTypeOnly ? '0' : '1'\n const hasName = node.name != null ? '1' : '0'\n const name = Array.isArray(node.name) ? node.name.toSorted().join('\\0') : (node.name ?? '')\n return `${isArray}:${typeOnly}:${node.path}:${hasName}:${name}`\n}\n\n/**\n * Deduplicates `SourceNode` objects by `name + isExportable + isTypeOnly`, keeping the first of each\n * key. Unnamed sources fall back to their extracted node strings as the name part of the key. Returns\n * the deduplicated array in original order.\n */\nexport function combineSources(sources: Array<SourceNode>): Array<SourceNode> {\n const seen = new Map<string, SourceNode>()\n for (const source of sources) {\n const key = sourceKey(source)\n if (!seen.has(key)) seen.set(key, source)\n }\n return [...seen.values()]\n}\n\n/**\n * Merges `incoming` names into `existing`, preserving order and dropping duplicates.\n *\n * Shared by `combineExports` and `combineImports` for the same-path name-merge case.\n */\nfunction mergeNameArrays<TName>(existing: Array<TName>, incoming: Array<TName>): Array<TName> {\n const merged = new Set(existing)\n for (const name of incoming) merged.add(name)\n return [...merged]\n}\n\n/**\n * Deduplicates and merges `ExportNode` objects by path and type.\n *\n * Named exports with the same path and `isTypeOnly` flag have their names merged into a single export.\n * Non-array exports are deduplicated by exact identity. Returns a sorted, deduplicated array.\n */\nexport function combineExports(exports: Array<ExportNode>): Array<ExportNode> {\n const result: Array<ExportNode> = []\n // Accumulates array-named exports keyed by `path:isTypeOnly` for name-merging\n const namedByPath = new Map<string, ExportNode>()\n // Deduplicates non-array exports by their exact identity\n const seen = new Set<string>()\n\n // Precompute sort keys once, avoids recomputing per comparison.\n const keyed = exports.map((node) => ({ node, key: sortKey(node) }))\n keyed.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n\n for (const { node: curr } of keyed) {\n const { name, path, isTypeOnly, asAlias } = curr\n\n if (Array.isArray(name)) {\n if (!name.length) continue\n\n const key = pathTypeKey(path, isTypeOnly)\n const existing = namedByPath.get(key)\n\n if (existing && Array.isArray(existing.name)) {\n existing.name = mergeNameArrays(existing.name, name)\n } else {\n const newItem: ExportNode = { ...curr, name: [...new Set(name)] }\n result.push(newItem)\n namedByPath.set(key, newItem)\n }\n } else {\n const key = exportKey(path, name, isTypeOnly, asAlias)\n if (!seen.has(key)) {\n result.push(curr)\n seen.add(key)\n }\n }\n }\n\n return result\n}\n\n/**\n * Deduplicates and merges `ImportNode` objects, filtering out unused imports.\n *\n * Retains imports that are referenced in `source` or re-exported. Imports with the same path and\n * `isTypeOnly` flag have their names merged. Returns a sorted, deduplicated, filtered array.\n */\nexport function combineImports(imports: Array<ImportNode>, exports: Array<ExportNode>, source?: string): Array<ImportNode> {\n // Build a lookup of all exported names to retain imports that are re-exported\n const exportedNames = new Set(exports.flatMap((e) => (Array.isArray(e.name) ? e.name : e.name ? [e.name] : [])))\n const isUsed = (importName: string): boolean => !source || source.includes(importName) || exportedNames.has(importName)\n\n // Memoize object import names so the same logical (propertyName, name) pair always\n // reuses the same object reference. Set-based deduplication then works correctly.\n const importNameMemo = new Map<string, { propertyName: string; name?: string }>()\n const canonicalizeName = (n: string | { propertyName: string; name?: string }): string | { propertyName: string; name?: string } => {\n if (typeof n === 'string') return n\n const key = `${n.propertyName}:${n.name ?? ''}`\n if (!importNameMemo.has(key)) importNameMemo.set(key, n)\n return importNameMemo.get(key)!\n }\n\n // Paths that keep at least one used named import. A default import from such a path is retained\n // even when its binding can't be found in `source` e.g. a generated `client` default import\n // alongside `import type { Client } from <same path>`, where merged grouped output omits the body.\n const pathsWithUsedNamedImport = new Set<string>()\n for (const node of imports) {\n if (!Array.isArray(node.name)) continue\n if (node.name.some((item) => (typeof item === 'string' ? isUsed(item) : isUsed(item.name ?? item.propertyName)))) {\n pathsWithUsedNamedImport.add(node.path)\n }\n }\n\n const result: Array<ImportNode> = []\n // Accumulates array-named imports keyed by `path:isTypeOnly` for name-merging\n const namedByPath = new Map<string, ImportNode>()\n // Deduplicates non-array imports by their exact identity\n const seen = new Set<string>()\n\n // Precompute sort keys once, avoids recomputing per comparison.\n const keyed = imports.map((node) => ({ node, key: sortKey(node) }))\n keyed.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n\n for (const { node: curr } of keyed) {\n if (curr.path === curr.root) continue\n\n const { path, isTypeOnly } = curr\n let { name } = curr\n\n if (Array.isArray(name)) {\n name = [...new Set(name.map(canonicalizeName))].filter((item) => (typeof item === 'string' ? isUsed(item) : isUsed(item.name ?? item.propertyName)))\n if (!name.length) continue\n\n const key = pathTypeKey(path, isTypeOnly)\n const existing = namedByPath.get(key)\n\n if (existing && Array.isArray(existing.name)) {\n existing.name = mergeNameArrays(existing.name, name)\n } else {\n const newItem: ImportNode = { ...curr, name }\n result.push(newItem)\n namedByPath.set(key, newItem)\n }\n } else {\n if (name && !isUsed(name) && !pathsWithUsedNamedImport.has(path)) continue\n\n const key = importKey(path, name, isTypeOnly)\n if (!seen.has(key)) {\n result.push(curr)\n seen.add(key)\n }\n }\n }\n\n return result\n}\n","import { hash } from 'node:crypto'\nimport path from 'node:path'\nimport { trimExtName } from '@internals/utils'\nimport { defineNode } from '../defineNode.ts'\nimport { combineExports, combineImports, combineSources } from '../utils/combineFileMembers.ts'\nimport { extractStringsFromNodes } from '../utils/extractStringsFromNodes.ts'\nimport type { BaseNode } from './base.ts'\nimport type { CodeNode } from './code.ts'\n\n/**\n * Supported file extensions.\n */\ntype Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`\n\ntype ImportName = string | Array<string | { propertyName: string; name?: string }>\n\n/**\n * Represents a language-agnostic import/dependency declaration.\n *\n * @example Named import (TypeScript: `import { useState } from 'react'`)\n * ```ts\n * createImport({ name: ['useState'], path: 'react' })\n * ```\n *\n * @example Default import (TypeScript: `import React from 'react'`)\n * ```ts\n * createImport({ name: 'React', path: 'react' })\n * ```\n *\n * @example Type-only import (TypeScript: `import type { FC } from 'react'`)\n * ```ts\n * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })\n * ```\n *\n * @example Namespace import (TypeScript: `import * as React from 'react'`)\n * ```ts\n * createImport({ name: 'React', path: 'react', isNameSpace: true })\n * ```\n */\nexport type ImportNode = BaseNode & {\n kind: 'Import'\n /**\n * Import name(s) to be used.\n *\n * @example Named imports\n * `['useState']`\n *\n * @example Default import\n * `'React'`\n */\n name: ImportName\n /**\n * Path for the import.\n *\n * @example\n * `'@kubb/core'`\n */\n path: string\n /**\n * Add a type-only import prefix.\n * - `true` generates `import type { Type } from './path'`\n * - `false` generates `import { Type } from './path'`\n */\n isTypeOnly?: boolean | null\n /**\n * Import the entire module as a namespace.\n * - `true` generates `import * as Name from './path'`\n * - `false` generates a standard import\n */\n isNameSpace?: boolean | null\n /**\n * When set, the import path is resolved relative to this root.\n */\n root?: string | null\n}\n\n/**\n * Represents a language-agnostic export/public API declaration.\n *\n * @example Named export (TypeScript: `export { Pets } from './Pets'`)\n * ```ts\n * createExport({ name: ['Pets'], path: './Pets' })\n * ```\n *\n * @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)\n * ```ts\n * createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })\n * ```\n *\n * @example Wildcard export (TypeScript: `export * from './utils'`)\n * ```ts\n * createExport({ path: './utils' })\n * ```\n *\n * @example Namespace alias (TypeScript: `export * as utils from './utils'`)\n * ```ts\n * createExport({ name: 'utils', path: './utils', asAlias: true })\n * ```\n */\nexport type ExportNode = BaseNode & {\n kind: 'Export'\n /**\n * Export name(s) to be used. When omitted, generates a wildcard export.\n *\n * @example Named exports\n * `['useState']`\n *\n * @example Single export\n * `'React'`\n */\n name?: string | Array<string> | null\n /**\n * Path for the export.\n *\n * @example\n * `'@kubb/core'`\n */\n path: string\n /**\n * Add a type-only export prefix.\n * - `true` generates `export type { Type } from './path'`\n * - `false` generates `export { Type } from './path'`\n */\n isTypeOnly?: boolean | null\n /**\n * Export as an aliased namespace.\n * - `true` generates `export * as aliasName from './path'`\n * - `false` generates a standard export\n */\n asAlias?: boolean | null\n}\n\n/**\n * Represents a fragment of source code within a file.\n *\n * @example Named exportable source\n * ```ts\n * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })\n * ```\n *\n * @example Inline unnamed code block\n * ```ts\n * createSource({ nodes: [createText('const x = 1')] })\n * ```\n */\nexport type SourceNode = BaseNode & {\n kind: 'Source'\n /**\n * Optional name identifying this source (used for deduplication and barrel generation).\n */\n name?: string | null\n /**\n * Mark this source as a type-only export.\n */\n isTypeOnly?: boolean | null\n /**\n * Include the `export` keyword in the generated source.\n */\n isExportable?: boolean | null\n /**\n * Include this source in barrel/index file generation.\n */\n isIndexable?: boolean | null\n /**\n * Child nodes that make up this source fragment, in DOM order.\n * Use a {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * Represents a fully resolved file in the AST.\n *\n * Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input\n * and deduplicates `imports`, `exports`, and `sources`.\n *\n * @example\n * ```ts\n * const file = createFile({\n * baseName: 'petStore.ts',\n * path: 'src/models/petStore.ts',\n * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],\n * imports: [createImport({ name: ['z'], path: 'zod' })],\n * exports: [createExport({ name: ['Pet'], path: './petStore' })],\n * })\n * // file.id = SHA256 hash of the path\n * // file.name = 'petStore'\n * // file.extname = '.ts'\n * ```\n */\nexport type FileNode<TMeta extends object = object> = BaseNode & {\n kind: 'File'\n /**\n * Unique identifier derived from a SHA256 hash of the file path. `createFile`\n * computes it, so callers do not need to provide it.\n */\n id: string\n /**\n * File name without extension, derived from `baseName`.\n *\n * @see https://nodejs.org/api/path.html#pathformatpathobject\n */\n name: string\n /**\n * File base name, including extension, shaped like `${name}${extname}`.\n *\n * @see https://nodejs.org/api/path.html#pathbasenamepath-suffix\n */\n baseName: `${string}.${string}`\n /**\n * Full qualified path to the file.\n */\n path: string\n /**\n * File extension extracted from `baseName`.\n */\n extname: Extname\n /**\n * Deduplicated list of source code fragments.\n */\n sources: Array<SourceNode>\n /**\n * Deduplicated list of import declarations.\n */\n imports: Array<ImportNode>\n /**\n * Deduplicated list of export declarations.\n */\n exports: Array<ExportNode>\n /**\n * Optional metadata attached to this file, read by plugins during barrel generation.\n */\n meta?: TMeta\n /**\n * Optional banner prepended to the generated file content.\n * Accepts `null` so `resolver.default.banner()` results can be passed directly.\n */\n banner?: string | null\n /**\n * Optional footer appended to the generated file content.\n * Accepts `null` so `resolver.default.footer()` results can be passed directly.\n */\n footer?: string | null\n /**\n * Absolute on-disk path to copy verbatim into the output, bypassing the parser.\n *\n * Use to emit a real source file shipped inside a package (a template) into the generated\n * folder without reformatting or import reordering. Only `banner` and `footer` are applied\n * around the copied content. When set, `copy` provides the file content and any `sources`\n * nodes are ignored for output; `sources` may still carry `name`/`isExportable`/`isIndexable`\n * so barrel generation treats the file the same as a rendered one.\n */\n copy?: string | null\n}\n\n/**\n * Definition for the {@link ImportNode}.\n */\nexport const importDef = defineNode<ImportNode>({ kind: 'Import' })\n\n/**\n * Definition for the {@link ExportNode}.\n */\nexport const exportDef = defineNode<ExportNode>({ kind: 'Export' })\n\n/**\n * Definition for the {@link SourceNode}.\n */\nexport const sourceDef = defineNode<SourceNode>({ kind: 'Source' })\n\n/**\n * Definition for the {@link FileNode}. The fully resolved builder lives in\n * `createFile`, so this definition only supplies the guard.\n */\nexport const fileDef = defineNode<FileNode>({ kind: 'File' })\n\n/**\n * Creates an `ImportNode` representing a language-agnostic import/dependency declaration.\n *\n * @example Named import\n * ```ts\n * createImport({ name: ['useState'], path: 'react' })\n * // import { useState } from 'react'\n * ```\n */\nexport const createImport = importDef.create\n\n/**\n * Creates an `ExportNode` representing a language-agnostic export/public API declaration.\n *\n * @example Named export\n * ```ts\n * createExport({ name: ['Pet'], path: './Pet' })\n * // export { Pet } from './Pet'\n * ```\n */\nexport const createExport = exportDef.create\n\n/**\n * Creates a `SourceNode` representing a fragment of source code within a file.\n *\n * @example\n * ```ts\n * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })\n * ```\n */\nexport const createSource = sourceDef.create\n\n/**\n * Input descriptor for {@link createFile}, before `id`, `name`, and `extname` are computed\n * and `imports`/`exports`/`sources` are deduplicated.\n */\nexport type UserFileNode<TMeta extends object = object> = Omit<FileNode<TMeta>, 'kind' | 'id' | 'name' | 'extname' | 'imports' | 'exports' | 'sources'> &\n Pick<Partial<FileNode<TMeta>>, 'imports' | 'exports' | 'sources'>\n\n/**\n * Creates a fully resolved `FileNode` from a file input descriptor.\n *\n * Computes:\n * - `id` SHA256 hash of the file path\n * - `name` `baseName` without extension\n * - `extname` extension extracted from `baseName`\n *\n * Deduplicates:\n * - `sources` via `combineSources`\n * - `exports` via `combineExports`\n * - `imports` via `combineImports` (also filters unused imports)\n *\n * @throws {Error} when `baseName` has no extension.\n *\n * @example\n * ```ts\n * const file = createFile({\n * baseName: 'petStore.ts',\n * path: 'src/models/petStore.ts',\n * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')] })],\n * imports: [createImport({ name: ['z'], path: 'zod' })],\n * exports: [createExport({ name: ['Pet'], path: './petStore' })],\n * })\n * // file.id = SHA256 hash of 'src/models/petStore.ts'\n * // file.name = 'petStore'\n * // file.extname = '.ts'\n * ```\n *\n * @example Copy a real file into the output verbatim\n * ```ts\n * const file = createFile({\n * baseName: 'client.ts',\n * path: 'src/gen/client.ts',\n * copy: '/abs/path/to/templates/client.ts',\n * })\n * ```\n */\nexport function createFile<TMeta extends object = object>(input: UserFileNode<TMeta>): FileNode<TMeta> {\n const extname = path.extname(input.baseName) as `.${string}`\n if (!extname) {\n throw new Error(`No extname found for ${input.baseName}`)\n }\n\n const resolvedExports = input.exports?.length ? combineExports(input.exports) : []\n\n // Skip building the source text and local-name set when there are no imports to resolve against them.\n const resolvedImports: Array<ImportNode> = (() => {\n if (!input.imports?.length) return []\n\n const sourceParts: Array<string> = []\n const localNames = new Set<string>()\n for (const item of input.sources ?? []) {\n const extracted = item.nodes && extractStringsFromNodes(item.nodes)\n if (extracted) sourceParts.push(extracted)\n if (item.name) localNames.add(item.name)\n }\n const source = sourceParts.join('\\n') || undefined\n const combinedImports = combineImports(input.imports, resolvedExports, source)\n const nameOf = (item: string | { propertyName: string; name?: string }): string => (typeof item === 'string' ? item : (item.name ?? item.propertyName))\n // Consolidating output (`mode: 'file'`) can put a symbol's definition and an import of it in the\n // same file: by path when the import still targets this file, by name when consolidation moved it.\n return combinedImports.flatMap((imp) => {\n if (imp.path === input.path) return []\n if (!Array.isArray(imp.name)) {\n return typeof imp.name === 'string' && localNames.has(imp.name) ? [] : [imp]\n }\n const kept = imp.name.filter((item) => !localNames.has(nameOf(item)))\n\n if (!kept.length) return []\n return [kept.length === imp.name.length ? imp : { ...imp, name: kept }]\n })\n })()\n const resolvedSources = input.sources?.length ? combineSources(input.sources) : []\n\n return {\n kind: 'File',\n ...input,\n id: hash('sha256', input.path, 'hex'),\n name: trimExtName(input.baseName),\n extname,\n imports: resolvedImports,\n exports: resolvedExports,\n sources: resolvedSources,\n meta: input.meta ?? ({} as TMeta),\n }\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { OperationNode } from './operation.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * Metadata for an API document, populated by the adapter and available to every generator.\n *\n * All fields are plain JSON-serializable values, no `Set`, no `Map`, no class instances.\n * Computed fields (`circularNames`, `enumNames`) are pre-calculated once during the adapter\n * pre-scan so generators never need to iterate the full schema list themselves.\n *\n * @example\n * ```ts\n * const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://api.example.com/v2', circularNames: [], enumNames: [] }\n * ```\n */\nexport type InputMeta = {\n /**\n * API title from `info.title` in the source document.\n */\n title?: string\n /**\n * API description from `info.description` in the source document.\n */\n description?: string\n /**\n * API version string from `info.version` in the source document.\n */\n version?: string\n /**\n * Resolved base URL from the first matching server entry in the source document.\n */\n baseURL?: string | null\n /**\n * Names of schemas that participate in a circular reference chain.\n * Computed once during the adapter pre-scan, so a generator never has to\n * call `findCircularSchemas` itself.\n *\n * Convert to a `Set` once at the start of a generator, not per-schema,\n * so lookups stay O(1) without repeated allocations.\n *\n * @example Wrap a circular schema in z.lazy()\n * ```ts\n * const circular = new Set(meta.circularNames)\n * if (circular.has(schema.name)) { ... }\n * ```\n */\n circularNames: ReadonlyArray<string>\n /**\n * Names of schemas whose type is `enum`.\n * Computed once during the adapter pre-scan, so a generator never has to\n * filter the schema list itself.\n *\n * Convert to a `Set` once at the start of a generator when you need repeated\n * membership checks, so each check stays O(1) instead of an array scan.\n *\n * @example Check if a referenced schema is an enum\n * `const enums = new Set(meta.enumNames)`\n * `const isEnum = enums.has(schemaName)`\n */\n enumNames: ReadonlyArray<string>\n}\n\n/**\n * Input AST node that contains all schemas and operations for one API document.\n * Produced by the adapter and consumed by all Kubb plugins.\n *\n * @example\n * ```ts\n * const input: InputNode = {\n * kind: 'Input',\n * schemas: [],\n * operations: [],\n * meta: { circularNames: [], enumNames: [] },\n * }\n * ```\n */\nexport type InputNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Input'\n /**\n * All schema nodes in the document.\n */\n schemas: Array<SchemaNode>\n /**\n * All operation nodes in the document.\n */\n operations: Array<OperationNode>\n /**\n * Document metadata populated by the adapter.\n */\n meta: InputMeta\n}\n\n/**\n * Definition for the {@link InputNode}.\n */\nexport const inputDef = defineNode<InputNode, Partial<Omit<InputNode, 'kind'>>>({\n kind: 'Input',\n defaults: { schemas: [], operations: [], meta: { circularNames: [], enumNames: [] } },\n children: ['schemas', 'operations'],\n visitorKey: 'input',\n})\n\n/**\n * Creates an `InputNode`, defaulting `schemas`/`operations` to empty arrays and `meta` per\n * {@link inputDef}.\n *\n * @example\n * ```ts\n * const input = createInput()\n * // { kind: 'Input', schemas: [], operations: [] }\n * ```\n */\nexport function createInput(overrides: Partial<Omit<InputNode, 'kind'>> = {}): InputNode {\n return inputDef.create(overrides)\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { ContentNode } from './content.ts'\n\n/**\n * AST node representing an operation request body.\n *\n * Body schemas live exclusively inside the `content` array (one entry per content type),\n * mirroring {@link ResponseNode}.\n *\n * @example\n * ```ts\n * const requestBody: RequestBodyNode = {\n * kind: 'RequestBody',\n * required: true,\n * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],\n * }\n * ```\n */\nexport type RequestBodyNode = BaseNode & {\n kind: 'RequestBody'\n /**\n * Request body description carried over from the spec.\n */\n description?: string\n /**\n * Whether the request body is required (`requestBody.required: true` in the spec).\n * When `false` or absent, the generated `data` parameter should be optional.\n */\n required?: boolean\n /**\n * Content type entries for this request body.\n *\n * When the adapter `contentType` option is set, this array contains exactly one entry for\n * that content type. Otherwise it contains one entry per content type declared in the spec,\n * so plugins can generate code for every variant (for example, separate hooks for\n * `application/json` and `multipart/form-data`).\n */\n content?: Array<ContentNode>\n}\n\n/**\n * Definition for the {@link RequestBodyNode}. Content entries are built upfront with\n * {@link createContent}, mirroring how `parameters` and `responses` take prebuilt nodes.\n */\nexport const requestBodyDef = defineNode<RequestBodyNode>({\n kind: 'RequestBody',\n children: ['content'],\n})\n\n/**\n * Creates a `RequestBodyNode`.\n */\nexport const createRequestBody = requestBodyDef.create\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { ParameterNode } from './parameter.ts'\nimport { createRequestBody, type RequestBodyNode } from './requestBody.ts'\nimport type { ResponseNode } from './response.ts'\n\n/**\n * HTTP method an operation responds to.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE'\n\n/**\n * Transport an operation belongs to.\n */\ntype OperationProtocol = 'http'\n\n/**\n * Fields shared by every operation, regardless of transport.\n */\ntype OperationNodeBase = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Operation'\n /**\n * Stable identifier for the operation.\n */\n operationId: string\n /**\n * Group labels for the operation.\n */\n tags: Array<string>\n /**\n * Short one-line operation summary.\n */\n summary?: string\n /**\n * Full operation description.\n */\n description?: string\n /**\n * Marks the operation as deprecated.\n */\n deprecated?: boolean\n /**\n * Query, path, header, and cookie parameters for the operation.\n */\n parameters: Array<ParameterNode>\n /**\n * Request body for the operation.\n */\n requestBody?: RequestBodyNode\n /**\n * Operation responses.\n */\n responses: Array<ResponseNode>\n}\n\n/**\n * Operation served over HTTP. `method` and `path` are guaranteed.\n *\n * @example\n * ```ts\n * const operation: HttpOperationNode = {\n * kind: 'Operation',\n * operationId: 'listPets',\n * protocol: 'http',\n * method: 'GET',\n * path: '/pets',\n * tags: [],\n * parameters: [],\n * responses: [],\n * }\n * ```\n */\nexport type HttpOperationNode = OperationNodeBase & {\n /**\n * Transport the operation belongs to.\n */\n protocol?: 'http'\n /**\n * HTTP method like `'GET'`.\n */\n method: HttpMethod\n /**\n * Path string, for example `/pets/{petId}`, with `{param}` notation preserved.\n */\n path: string\n}\n\n/**\n * Operation for a non-HTTP transport. HTTP-only fields are forbidden.\n */\nexport type GenericOperationNode = OperationNodeBase & {\n /**\n * Transport the operation belongs to.\n */\n protocol?: Exclude<OperationProtocol, 'http'>\n method?: never\n path?: never\n}\n\n/**\n * AST node representing one API operation.\n *\n * Discriminated on `protocol`: an {@link HttpOperationNode} (`protocol: 'http'`) guarantees\n * `method` and `path`, while a {@link GenericOperationNode} omits them. Narrow with\n * `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.\n */\nexport type OperationNode = HttpOperationNode | GenericOperationNode\n\ntype OperationInput = {\n operationId: string\n method?: HttpOperationNode['method']\n path?: HttpOperationNode['path']\n requestBody?: Omit<RequestBodyNode, 'kind'>\n [key: string]: unknown\n}\n\n/**\n * Definition for the {@link OperationNode}. HTTP operations (those carrying both\n * `method` and `path`) are tagged with `protocol: 'http'`, and the request body is\n * normalized into a `RequestBodyNode`.\n */\nexport const operationDef = defineNode<OperationNode, OperationInput>({\n kind: 'Operation',\n build: (props) => {\n const { requestBody, ...rest } = props\n const isHttp = rest.method !== undefined && rest.path !== undefined\n\n return {\n tags: [],\n parameters: [],\n responses: [],\n ...rest,\n ...(isHttp ? { protocol: 'http' as const } : {}),\n requestBody: requestBody ? createRequestBody(requestBody) : undefined,\n }\n },\n children: ['parameters', 'requestBody', 'responses'],\n visitorKey: 'operation',\n})\n\n/**\n * Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.\n *\n * @example\n * ```ts\n * const operation = createOperation({ operationId: 'getPetById', method: 'GET', path: '/pet/{petId}' })\n * // tags, parameters, and responses are []\n * ```\n */\nexport function createOperation(\n props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> &\n Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {\n requestBody?: Omit<RequestBodyNode, 'kind'>\n },\n): HttpOperationNode\nexport function createOperation(\n props: Pick<GenericOperationNode, 'operationId'> &\n Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {\n requestBody?: Omit<RequestBodyNode, 'kind'>\n },\n): GenericOperationNode\nexport function createOperation(props: OperationInput): OperationNode {\n return operationDef.create(props)\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { FileNode } from './file.ts'\n\n/**\n * Output AST node that groups all generated file output for one API document.\n *\n * Produced by generators and consumed by the build pipeline to write files.\n *\n * @example\n * ```ts\n * const output: OutputNode = {\n * kind: 'Output',\n * files: [],\n * }\n * ```\n */\nexport type OutputNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Output'\n /**\n * Generated file nodes.\n */\n files: Array<FileNode>\n}\n\n/**\n * Definition for the {@link OutputNode}.\n */\nexport const outputDef = defineNode<OutputNode, Partial<Omit<OutputNode, 'kind'>>>({\n kind: 'Output',\n defaults: { files: [] },\n visitorKey: 'output',\n})\n\n/**\n * Creates an `OutputNode` with a stable default for `files`.\n *\n * @example\n * ```ts\n * const output = createOutput()\n * // { kind: 'Output', files: [] }\n * ```\n */\nexport function createOutput(overrides: Partial<Omit<OutputNode, 'kind'>> = {}): OutputNode {\n return outputDef.create(overrides)\n}\n","import type { SchemaNode } from './nodes/schema.ts'\n\n/**\n * Generic JSON Schema optionality: a non-required field is optional, and a\n * non-required nullable field is nullish.\n */\nexport function optionality(schema: SchemaNode, required: boolean): SchemaNode {\n const nullable = schema.nullable ?? false\n\n return {\n ...schema,\n optional: !required && !nullable ? true : undefined,\n nullish: !required && nullable ? true : undefined,\n }\n}\n","import { defineNode } from '../defineNode.ts'\nimport { optionality } from '../optionality.ts'\nimport type { BaseNode } from './base.ts'\nimport type { SchemaNode } from './schema.ts'\n\nexport type ParameterLocation = 'path' | 'query' | 'header' | 'cookie'\n\n/**\n * Parameter serialization style, controlling how a parameter value is rendered into the request.\n */\nexport type ParameterStyle = 'matrix' | 'label' | 'form' | 'simple' | 'spaceDelimited' | 'pipeDelimited' | 'deepObject'\n\n/**\n * AST node representing one operation parameter.\n *\n * @example\n * ```ts\n * const param: ParameterNode = {\n * kind: 'Parameter',\n * name: 'petId',\n * in: 'path',\n * schema: createSchema({ type: 'string' }),\n * required: true,\n * }\n * ```\n */\nexport type ParameterNode = BaseNode & {\n kind: 'Parameter'\n /**\n * Parameter name.\n */\n name: string\n /**\n * Parameter location (`path`, `query`, `header`, or `cookie`).\n */\n in: ParameterLocation\n /**\n * Parameter schema.\n */\n schema: SchemaNode\n /**\n * Whether the parameter is required.\n */\n required: boolean\n /**\n * Serialization style. Absent when the source omits it, leaving consumers to apply the\n * per-location default.\n */\n style?: ParameterStyle\n /**\n * Whether array and object values expand into separate values. Absent when the source omits it,\n * leaving consumers to apply the default for the style.\n */\n explode?: boolean\n}\n\ntype UserParameterNode = Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>\n\n/**\n * Definition for the {@link ParameterNode}. `required` defaults to `false`, and the schema's\n * `optional`/`nullish` flags are derived from it through {@link optionality}.\n */\nexport const parameterDef = defineNode<ParameterNode, UserParameterNode>({\n kind: 'Parameter',\n build: (props) => {\n const required = props.required ?? false\n return { ...props, required, schema: optionality(props.schema, required) }\n },\n children: ['schema'],\n visitorKey: 'parameter',\n})\n\n/**\n * Creates a `ParameterNode`.\n *\n * @example\n * ```ts\n * const param = createParameter({\n * name: 'petId',\n * in: 'path',\n * required: true,\n * schema: createSchema({ type: 'string' }),\n * })\n * ```\n */\nexport const createParameter = parameterDef.create\n","import { defineNode } from '../defineNode.ts'\nimport { optionality } from '../optionality.ts'\nimport type { BaseNode } from './base.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * AST node representing one named object property.\n *\n * @example\n * ```ts\n * const property: PropertyNode = {\n * kind: 'Property',\n * name: 'id',\n * schema: createSchema({ type: 'integer' }),\n * required: true,\n * }\n * ```\n */\nexport type PropertyNode = BaseNode & {\n kind: 'Property'\n /**\n * Property key.\n */\n name: string\n /**\n * Property schema.\n */\n schema: SchemaNode\n /**\n * Whether the property is required.\n */\n required: boolean\n}\n\n/**\n * Loosely-typed property accepted by `createProperty`, with `required` optional.\n */\nexport type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>\n\n/**\n * Definition for the {@link PropertyNode}. `required` defaults to `false`, and the schema's\n * `optional`/`nullish` flags are derived from it through {@link optionality}.\n */\nexport const propertyDef = defineNode<PropertyNode, UserPropertyNode>({\n kind: 'Property',\n build: (props) => {\n const required = props.required ?? false\n return { ...props, required, schema: optionality(props.schema, required) }\n },\n children: ['schema'],\n visitorKey: 'property',\n})\n\n/**\n * Creates a `PropertyNode`.\n *\n * @example\n * ```ts\n * const property = createProperty({\n * name: 'status',\n * required: true,\n * schema: createSchema({ type: 'string', nullable: true }),\n * })\n * // required=true, no optional/nullish\n * ```\n */\nexport const createProperty = propertyDef.create\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport { type ContentNode, createContent } from './content.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * All supported HTTP status code literals as strings, as used in API specs\n * (for example, `\"200\"` and `\"404\"`).\n */\ntype HttpStatusCode =\n // 1xx Informational\n | '100'\n | '101'\n | '102'\n | '103'\n // 2xx Success\n | '200'\n | '201'\n | '202'\n | '203'\n | '204'\n | '205'\n | '206'\n | '207'\n | '208'\n | '226'\n // 3xx Redirection\n | '300'\n | '301'\n | '302'\n | '303'\n | '304'\n | '305'\n | '307'\n | '308'\n // 4xx Client Error\n | '400'\n | '401'\n | '402'\n | '403'\n | '404'\n | '405'\n | '406'\n | '407'\n | '408'\n | '409'\n | '410'\n | '411'\n | '412'\n | '413'\n | '414'\n | '415'\n | '416'\n | '417'\n | '418'\n | '421'\n | '422'\n | '423'\n | '424'\n | '425'\n | '426'\n | '428'\n | '429'\n | '431'\n | '451'\n // 5xx Server Error\n | '500'\n | '501'\n | '502'\n | '503'\n | '504'\n | '505'\n | '506'\n | '507'\n | '508'\n | '510'\n | '511'\n\n/**\n * Response status code literal used by operations.\n *\n * Includes specific HTTP status code strings and `\"default\"` for catch-all responses.\n *\n * @example\n * ```ts\n * const status: StatusCode = '200'\n * const fallback: StatusCode = 'default'\n * ```\n */\nexport type StatusCode = HttpStatusCode | 'default'\n\n/**\n * AST node representing one operation response variant.\n *\n * Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside\n * the `content` array (one entry per content type), so the same schema is never duplicated at the\n * node root and inside `content`.\n *\n * @example\n * ```ts\n * const response: ResponseNode = {\n * kind: 'Response',\n * statusCode: '200',\n * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],\n * }\n * ```\n */\nexport type ResponseNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Response'\n /**\n * HTTP status code or `'default'` for a fallback response.\n */\n statusCode: StatusCode\n /**\n * Optional response description.\n */\n description?: string\n /**\n * All available content type entries for this response.\n *\n * When the adapter `contentType` option is set, this array contains exactly one entry for that\n * content type. Otherwise it contains one entry per content type declared in the spec, so that\n * plugins can generate a union of response types (e.g. `application/json` and `application/xml`).\n * Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.\n *\n * @example\n * ```ts\n * // spec response declares both application/json and application/xml\n * response.content[0].contentType // 'application/json'\n * response.content[1].contentType // 'application/xml'\n * ```\n */\n content?: Array<ContentNode>\n}\n\ntype ResponseInput = Pick<ResponseNode, 'statusCode'> &\n Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {\n content?: Array<ContentNode>\n schema?: SchemaNode\n mediaType?: string | null\n keysToOmit?: Array<string> | null\n }\n\n/**\n * Definition for the {@link ResponseNode}. A single legacy `schema` (with optional\n * `mediaType`/`keysToOmit`) is normalized into one `content` entry.\n */\nexport const responseDef = defineNode<ResponseNode, ResponseInput>({\n kind: 'Response',\n build: (props) => {\n const { schema, mediaType, keysToOmit, content, ...rest } = props\n const entries = content ?? (schema ? [createContent({ contentType: mediaType ?? 'application/json', schema, keysToOmit: keysToOmit ?? null })] : undefined)\n return { ...rest, content: entries }\n },\n children: ['content'],\n visitorKey: 'response',\n})\n\n/**\n * Creates a `ResponseNode`.\n *\n * @example\n * ```ts\n * const response = createResponse({\n * statusCode: '200',\n * content: [createContent({ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) })],\n * })\n * ```\n */\nexport const createResponse = responseDef.create\n","import type { InferSchemaNode } from '../infer.ts'\nimport { defineNode, type DistributiveOmit } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { PropertyNode } from './property.ts'\n\nexport type PrimitiveSchemaType =\n /**\n * Text value.\n */\n | 'string'\n /**\n * Floating-point number.\n */\n | 'number'\n /**\n * Integer number.\n */\n | 'integer'\n /**\n * Big integer number.\n */\n | 'bigint'\n /**\n * Boolean value.\n */\n | 'boolean'\n /**\n * Null value.\n */\n | 'null'\n /**\n * Any value.\n */\n | 'any'\n /**\n * Unknown value.\n */\n | 'unknown'\n /**\n * No value (`void`).\n */\n | 'void'\n /**\n * Never value.\n */\n | 'never'\n /**\n * Object value.\n */\n | 'object'\n /**\n * Array value.\n */\n | 'array'\n /**\n * Date value.\n */\n | 'date'\n\n/**\n * Composite schema types.\n */\ntype ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum'\n\n/**\n * Schema types that need special handling in generators.\n */\ntype SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob'\n\n/**\n * All schema type strings.\n */\nexport type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType\n\n/**\n * Scalar schema types without extra object/array/ref structure.\n */\nexport type ScalarSchemaType = Exclude<\n SchemaType,\n | 'object'\n | 'array'\n | 'tuple'\n | 'union'\n | 'intersection'\n | 'enum'\n | 'ref'\n | 'datetime'\n | 'date'\n | 'time'\n | 'string'\n | 'number'\n | 'integer'\n | 'bigint'\n | 'url'\n | 'uuid'\n | 'email'\n>\n\n/**\n * Fields shared by all schema nodes.\n */\ntype SchemaNodeBase = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Schema'\n /**\n * Schema name for named definitions (for example, `\"Pet\"`).\n * Inline schemas omit this field.\n * `null` means Kubb has processed this and determined there is no applicable name.\n * `undefined` means the name has not been set yet.\n */\n name?: string | null\n /**\n * Short schema title.\n */\n title?: string\n /**\n * Schema description text.\n */\n description?: string\n /**\n * Whether `null` is allowed.\n */\n nullable?: boolean\n /**\n * Whether the field is optional.\n */\n optional?: boolean\n /**\n * Both optional and nullable (`optional` + `nullable`).\n */\n nullish?: boolean\n /**\n * Whether the schema is deprecated.\n */\n deprecated?: boolean\n /**\n * Whether the schema is read-only.\n */\n readOnly?: boolean\n /**\n * Whether the schema is write-only.\n */\n writeOnly?: boolean\n /**\n * Default value.\n */\n default?: unknown\n /**\n * Example values from an `examples` array.\n */\n examples?: Array<unknown>\n /**\n * Base primitive type.\n * For example, this is `'string'` for a `uuid` schema.\n */\n primitive?: PrimitiveSchemaType\n /**\n * Schema `format` value.\n */\n format?: string\n}\n\n/**\n * Object schema with ordered properties.\n *\n * @example\n * ```ts\n * const objectSchema: ObjectSchemaNode = {\n * kind: 'Schema',\n * type: 'object',\n * properties: [],\n * }\n * ```\n */\nexport type ObjectSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'object'\n /**\n * Primitive type, always `'object'` for object schemas.\n */\n primitive: 'object'\n /**\n * Ordered object properties.\n */\n properties: Array<PropertyNode>\n /**\n * Additional object properties behavior:\n * - `true`: allow any value\n * - `false`: reject unknown properties\n * - `SchemaNode`: allow values that match that schema\n * - `undefined`: no additional properties constraint (open object)\n */\n additionalProperties?: SchemaNode | boolean\n /**\n * Pattern-based property schemas.\n */\n patternProperties?: Record<string, SchemaNode>\n /**\n * Minimum number of properties allowed.\n */\n minProperties?: number\n /**\n * Maximum number of properties allowed.\n */\n maxProperties?: number\n}\n\n/**\n * Array-like schema (`array` or `tuple`).\n *\n * @example\n * ```ts\n * const arraySchema: ArraySchemaNode = {\n * kind: 'Schema',\n * type: 'array',\n * items: [],\n * }\n * ```\n */\nexport type ArraySchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator (`array` or `tuple`).\n */\n type: 'array' | 'tuple'\n /**\n * Item schemas.\n */\n items?: Array<SchemaNode>\n /**\n * Tuple rest-item schema for elements beyond positional `items`.\n */\n rest?: SchemaNode\n /**\n * Minimum item count (or tuple length).\n */\n min?: number\n /**\n * Maximum item count (or tuple length).\n */\n max?: number\n /**\n * Whether all items must be unique.\n */\n unique?: boolean\n}\n\n/**\n * Shared shape for union and intersection schemas.\n */\ntype CompositeSchemaNodeBase = SchemaNodeBase & {\n /**\n * Member schemas.\n */\n members?: Array<SchemaNode>\n}\n\n/**\n * Union schema, often from `oneOf` or `anyOf`.\n *\n * @example\n * ```ts\n * const unionSchema: UnionSchemaNode = {\n * kind: 'Schema',\n * type: 'union',\n * members: [],\n * }\n * ```\n */\nexport type UnionSchemaNode = CompositeSchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'union'\n /**\n * Discriminator property name for a polymorphic union.\n */\n discriminatorPropertyName?: string\n /**\n * How many union members must be valid.\n * - `'one'`: exactly one member, from `oneOf`\n * - `'any'`: any number of members, from `anyOf`\n */\n strategy?: 'one' | 'any'\n}\n\n/**\n * Intersection schema, often from `allOf`.\n *\n * @example\n * ```ts\n * const intersectionSchema: IntersectionSchemaNode = {\n * kind: 'Schema',\n * type: 'intersection',\n * members: [],\n * }\n * ```\n */\nexport type IntersectionSchemaNode = CompositeSchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'intersection'\n}\n\n/**\n * One named enum item.\n */\ntype EnumValueNode = {\n /**\n * Enum item name.\n */\n name: string\n /**\n * Enum item value.\n */\n value: string | number | boolean\n /**\n * Primitive type of the enum value.\n */\n primitive: Extract<PrimitiveSchemaType, 'string' | 'number' | 'boolean'>\n /**\n * Label for the enum item, taken from the `x-enumDescriptions` or\n * `x-enum-descriptions` vendor extension. `@kubb/plugin-ts` renders it as\n * JSDoc on the matching enum member.\n */\n description?: string\n}\n\n/**\n * Enum schema node.\n *\n * @example\n * ```ts\n * const enumSchema: EnumSchemaNode = {\n * kind: 'Schema',\n * type: 'enum',\n * enumValues: ['a', 'b'],\n * }\n * ```\n */\nexport type EnumSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'enum'\n /**\n * Enum values in simple form.\n */\n enumValues?: Array<string | number | boolean | null>\n /**\n * Enum values in named form.\n * If present, this is used instead of `enumValues`.\n */\n namedEnumValues?: Array<EnumValueNode>\n}\n\n/**\n * Reference schema that points to another schema definition.\n *\n * @example\n * ```ts\n * const refSchema: RefSchemaNode = {\n * kind: 'Schema',\n * type: 'ref',\n * ref: '#/components/schemas/Pet',\n * }\n * ```\n */\nexport type RefSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'ref'\n /**\n * Referenced schema name.\n * `null` means Kubb has processed this and determined there is no applicable name.\n */\n name?: string | null\n /**\n * Original `$ref` path, for example, `#/components/schemas/Order`.\n * Used to resolve names later.\n */\n ref?: string\n /**\n * Pattern copied from a sibling `pattern` field.\n */\n pattern?: string\n /**\n * The fully-parsed schema this ref resolves to, so its structure (`primitive`, `properties`)\n * can be read without following the reference. Populated during parsing when the\n * definition resolves, `null` when it can't or the ref is circular, and `undefined` when\n * resolution has not been attempted.\n */\n schema?: SchemaNode | null\n}\n\n/**\n * Datetime schema.\n *\n * @example\n * ```ts\n * const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }\n * ```\n */\nexport type DatetimeSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'datetime'\n /**\n * Whether the datetime includes a timezone offset (`dateType: 'stringOffset'`).\n */\n offset?: boolean\n /**\n * Whether the datetime is local (no timezone, `dateType: 'stringLocal'`).\n */\n local?: boolean\n}\n\n/**\n * Shared base for `date` and `time` schemas.\n */\ntype TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: T\n /**\n * Output representation in generated code.\n */\n representation: 'date' | 'string'\n}\n\n/**\n * Date schema node.\n *\n * @example\n * ```ts\n * const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }\n * ```\n */\nexport type DateSchemaNode = TemporalSchemaNodeBase<'date'>\n\n/**\n * Time schema node.\n *\n * @example\n * ```ts\n * const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }\n * ```\n */\nexport type TimeSchemaNode = TemporalSchemaNodeBase<'time'>\n\n/**\n * String schema node.\n *\n * @example\n * ```ts\n * const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }\n * ```\n */\nexport type StringSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'string'\n /**\n * Minimum string length.\n */\n min?: number\n /**\n * Maximum string length.\n */\n max?: number\n /**\n * Regex pattern.\n */\n pattern?: string\n}\n\n/**\n * Numeric schema (`number`, `integer`, or `bigint`).\n *\n * @example\n * ```ts\n * const numberSchema: NumberSchemaNode = { kind: 'Schema', type: 'number' }\n * ```\n */\nexport type NumberSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'number' | 'integer' | 'bigint'\n /**\n * Minimum value.\n */\n min?: number\n /**\n * Maximum value.\n */\n max?: number\n /**\n * Exclusive minimum value.\n */\n exclusiveMinimum?: number\n /**\n * Exclusive maximum value.\n */\n exclusiveMaximum?: number\n /**\n * The value must be a multiple of this number.\n */\n multipleOf?: number\n}\n\n/**\n * Scalar schema with no extra constraints.\n *\n * @example\n * ```ts\n * const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }\n * ```\n */\nexport type ScalarSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: ScalarSchemaType\n}\n\n/**\n * URL schema node.\n * Can include a path template for template literal types.\n *\n * @example\n * ```ts\n * const urlSchema: UrlSchemaNode = { kind: 'Schema', type: 'url', path: '/pets/{petId}' }\n * ```\n */\nexport type UrlSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'url'\n /**\n * Path template, for example, `'/pets/{petId}'`.\n */\n path?: string\n /**\n * Minimum string length.\n */\n min?: number\n /**\n * Maximum string length.\n */\n max?: number\n}\n\n/**\n * Format-string schema for string-based formats that support length constraints.\n *\n * @example\n * ```ts\n * const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }\n * ```\n */\ntype FormatStringSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'uuid' | 'email'\n /**\n * Minimum string length.\n */\n min?: number\n /**\n * Maximum string length.\n */\n max?: number\n}\n\n/**\n * IPv4 address schema node.\n *\n * @example\n * ```ts\n * const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }\n * ```\n */\ntype Ipv4SchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'ipv4'\n}\n\n/**\n * IPv6 address schema node.\n *\n * @example\n * ```ts\n * const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }\n * ```\n */\ntype Ipv6SchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'ipv6'\n}\n\n/**\n * Mapping from schema type literals to concrete schema node types.\n * Used by `narrowSchema`.\n */\nexport type SchemaNodeByType = {\n object: ObjectSchemaNode\n array: ArraySchemaNode\n tuple: ArraySchemaNode\n union: UnionSchemaNode\n intersection: IntersectionSchemaNode\n enum: EnumSchemaNode\n ref: RefSchemaNode\n datetime: DatetimeSchemaNode\n date: DateSchemaNode\n time: TimeSchemaNode\n string: StringSchemaNode\n number: NumberSchemaNode\n integer: NumberSchemaNode\n bigint: NumberSchemaNode\n boolean: ScalarSchemaNode\n null: ScalarSchemaNode\n any: ScalarSchemaNode\n unknown: ScalarSchemaNode\n void: ScalarSchemaNode\n never: ScalarSchemaNode\n uuid: FormatStringSchemaNode\n email: FormatStringSchemaNode\n url: UrlSchemaNode\n ipv4: Ipv4SchemaNode\n ipv6: Ipv6SchemaNode\n blob: ScalarSchemaNode\n}\n\n/**\n * Union of all schema node types.\n */\nexport type SchemaNode =\n | ObjectSchemaNode\n | ArraySchemaNode\n | UnionSchemaNode\n | IntersectionSchemaNode\n | EnumSchemaNode\n | RefSchemaNode\n | DatetimeSchemaNode\n | DateSchemaNode\n | TimeSchemaNode\n | StringSchemaNode\n | NumberSchemaNode\n | UrlSchemaNode\n | FormatStringSchemaNode\n | Ipv4SchemaNode\n | Ipv6SchemaNode\n | ScalarSchemaNode\n\ntype CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & { properties?: Array<PropertyNode>; primitive?: 'object' }\ntype CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>\ntype CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {\n kind: 'Schema'\n}\n\n/**\n * Maps schema `type` to its underlying `primitive`.\n * Primitive types map to themselves and special string formats map to `'string'`.\n * Any type not listed here (such as `ref`, `enum`, `union`, `intersection`, `tuple`, `ipv4`, `ipv6`, `blob`) has no `primitive`.\n */\nconst TYPE_TO_PRIMITIVE: Partial<Record<SchemaNode['type'], PrimitiveSchemaType>> = {\n string: 'string',\n number: 'number',\n integer: 'integer',\n bigint: 'bigint',\n boolean: 'boolean',\n null: 'null',\n any: 'any',\n unknown: 'unknown',\n void: 'void',\n never: 'never',\n object: 'object',\n array: 'array',\n date: 'date',\n uuid: 'string',\n email: 'string',\n url: 'string',\n datetime: 'string',\n time: 'string',\n}\n\n/**\n * Definition for the {@link SchemaNode}. Object schemas default `properties` to an\n * empty array, and `primitive` is inferred from `type` when not explicitly provided.\n */\nexport const schemaDef = defineNode<SchemaNode, CreateSchemaInput>({\n kind: 'Schema',\n build: (props) => {\n if (props.type === 'object') {\n return { properties: [], primitive: 'object' as const, ...props }\n }\n\n return { primitive: TYPE_TO_PRIMITIVE[props.type as keyof typeof TYPE_TO_PRIMITIVE], ...props }\n },\n children: ['properties', 'items', 'members', 'additionalProperties'],\n visitorKey: 'schema',\n})\n\n/**\n * Creates a `SchemaNode`, narrowed to the variant of `props.type`.\n *\n * @example\n * ```ts\n * const scalar = createSchema({ type: 'string' })\n * // { kind: 'Schema', type: 'string', primitive: 'string' }\n * ```\n *\n * @example\n * ```ts\n * const object = createSchema({ type: 'object' })\n * // { kind: 'Schema', type: 'object', primitive: 'object', properties: [] }\n * ```\n */\nexport function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>\nexport function createSchema(props: CreateSchemaInput): SchemaNode\nexport function createSchema(props: CreateSchemaInput): SchemaNode {\n return schemaDef.create(props)\n}\n","import type { NodeDef } from './defineNode.ts'\nimport { arrowFunctionDef, breakDef, constDef, functionDef, jsxDef, textDef, typeDef } from './nodes/code.ts'\nimport { contentDef } from './nodes/content.ts'\nimport { exportDef, fileDef, importDef, sourceDef } from './nodes/file.ts'\nimport { inputDef } from './nodes/input.ts'\nimport { operationDef } from './nodes/operation.ts'\nimport { outputDef } from './nodes/output.ts'\nimport { parameterDef } from './nodes/parameter.ts'\nimport { propertyDef } from './nodes/property.ts'\nimport { requestBodyDef } from './nodes/requestBody.ts'\nimport { responseDef } from './nodes/response.ts'\nimport { schemaDef } from './nodes/schema.ts'\n\n// Surface every def from one place so the package barrel re-exports them with `export * from './registry.ts'`.\n// Adding a node means adding its `defineNode` to a `nodes/*.ts` file and listing it in `nodeDefs` below, nothing else.\nexport {\n arrowFunctionDef,\n breakDef,\n constDef,\n contentDef,\n exportDef,\n fileDef,\n functionDef,\n importDef,\n inputDef,\n jsxDef,\n operationDef,\n outputDef,\n parameterDef,\n propertyDef,\n requestBodyDef,\n responseDef,\n schemaDef,\n sourceDef,\n textDef,\n typeDef,\n}\n\n/**\n * Every node definition. Adding a node means adding its `defineNode` to one\n * `nodes/*.ts` file and listing it here. The visitor tables in `visitor.ts` derive from it.\n */\nexport const nodeDefs = [\n inputDef,\n outputDef,\n operationDef,\n requestBodyDef,\n contentDef,\n responseDef,\n schemaDef,\n propertyDef,\n parameterDef,\n constDef,\n typeDef,\n functionDef,\n arrowFunctionDef,\n textDef,\n breakDef,\n jsxDef,\n importDef,\n exportDef,\n sourceDef,\n fileDef,\n] satisfies ReadonlyArray<NodeDef>\n","import type { VisitorDepth } from './constants.ts'\nimport { visitorDepths } from './constants.ts'\nimport type { NodeDef } from './defineNode.ts'\nimport type {\n ContentNode,\n InputNode,\n Node,\n NodeKind,\n OperationNode,\n OutputNode,\n ParameterNode,\n PropertyNode,\n RequestBodyNode,\n ResponseNode,\n SchemaNode,\n} from './nodes/index.ts'\nimport { nodeDefs } from './registry.ts'\n\n/**\n * Child node fields per node kind, in traversal order (Babel's `VISITOR_KEYS`).\n * Derived from each definition's `children`.\n */\nconst VISITOR_KEYS = Object.fromEntries(nodeDefs.flatMap((def) => (def.children ? [[def.kind, def.children] as const] : []))) as Partial<\n Record<NodeKind, ReadonlyArray<string>>\n>\n\n/**\n * Maps a node kind to the matching visitor callback name. Derived from each\n * definition's `visitorKey`.\n */\nconst VISITOR_KEY_BY_KIND = Object.fromEntries(nodeDefs.flatMap((def) => (def.visitorKey ? [[def.kind, def.visitorKey] as const] : []))) as Partial<\n Record<NodeKind, NonNullable<NodeDef['visitorKey']>>\n>\n\n/**\n * Ordered mapping of `[NodeType, ParentType]` pairs.\n *\n * `ParentOf` uses this map to find parent types.\n */\ntype ParentNodeMap = [\n [InputNode, undefined],\n [OutputNode, undefined],\n [OperationNode, InputNode],\n [RequestBodyNode, OperationNode],\n [ContentNode, RequestBodyNode | ResponseNode],\n [SchemaNode, InputNode | ContentNode | SchemaNode | PropertyNode | ParameterNode],\n [PropertyNode, SchemaNode],\n [ParameterNode, OperationNode],\n [ResponseNode, OperationNode],\n]\n\n/**\n * Resolves the parent node type for a given AST node type.\n *\n * Visitor context relies on this so `ctx.parent` is typed for each callback.\n *\n * @example\n * ```ts\n * type InputParent = ParentOf<InputNode>\n * // undefined\n * ```\n *\n * @example\n * ```ts\n * type PropertyParent = ParentOf<PropertyNode>\n * // SchemaNode\n * ```\n *\n * @example\n * ```ts\n * type SchemaParent = ParentOf<SchemaNode>\n * // InputNode | ContentNode | SchemaNode | PropertyNode | ParameterNode\n * ```\n */\nexport type ParentOf<T extends Node, TEntries extends ReadonlyArray<[Node, unknown]> = ParentNodeMap> = TEntries extends [\n infer TEntry extends [Node, unknown],\n ...infer TRest extends ReadonlyArray<[Node, unknown]>,\n]\n ? T extends TEntry[0]\n ? TEntry[1]\n : ParentOf<T, TRest>\n : Node\n\n/**\n * Traversal context passed as the second argument to every visitor callback.\n * `parent` is typed from the current node type.\n *\n * @example\n * ```ts\n * const visitor: Visitor = {\n * schema(node, { parent }) {\n * // parent type is narrowed by node kind\n * },\n * }\n * ```\n */\nexport type VisitorContext<T extends Node = Node> = {\n /**\n * Parent node of the currently visited node.\n * For `InputNode`, this is `undefined`.\n */\n parent?: ParentOf<T>\n}\n\n/**\n * Synchronous visitor consumed by `transform`. Each optional callback runs\n * for the matching node type. Return a new node to replace it, or `undefined`\n * to leave it untouched.\n *\n * Plugins typically expose `transformer` so users can supply a `Visitor` that\n * rewrites the AST before printing.\n *\n * @example Prefix every operationId\n * ```ts\n * const visitor: Visitor = {\n * operation(node) {\n * return { ...node, operationId: `api_${node.operationId}` }\n * },\n * }\n * ```\n *\n * @example Strip schema descriptions\n * ```ts\n * const visitor: Visitor = {\n * schema(node) {\n * return { ...node, description: undefined }\n * },\n * }\n * ```\n */\nexport type Visitor = {\n input?(node: InputNode, context: VisitorContext<InputNode>): undefined | null | InputNode\n output?(node: OutputNode, context: VisitorContext<OutputNode>): undefined | null | OutputNode\n operation?(node: OperationNode, context: VisitorContext<OperationNode>): undefined | null | OperationNode\n schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): undefined | null | SchemaNode\n property?(node: PropertyNode, context: VisitorContext<PropertyNode>): undefined | null | PropertyNode\n parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): undefined | null | ParameterNode\n response?(node: ResponseNode, context: VisitorContext<ResponseNode>): undefined | null | ResponseNode\n}\n\n/**\n * Visitor used by `collect`.\n *\n * @example\n * ```ts\n * const visitor: CollectVisitor<string> = {\n * operation(node) {\n * return node.operationId\n * },\n * }\n * ```\n */\ntype CollectVisitor<T> = {\n input?(node: InputNode, context: VisitorContext<InputNode>): T | null | undefined\n output?(node: OutputNode, context: VisitorContext<OutputNode>): T | null | undefined\n operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | null | undefined\n schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | null | undefined\n property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | null | undefined\n parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | null | undefined\n response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | null | undefined\n}\n\n/**\n * Options for `transform`.\n *\n * @example\n * ```ts\n * const options: TransformOptions = { depth: 'deep', schema: (node) => node }\n * ```\n *\n * @example\n * ```ts\n * // Only transform the current node, not nested children\n * const options: TransformOptions = { depth: 'shallow', schema: (node) => node }\n * ```\n */\nexport type TransformOptions = Visitor & {\n /**\n * Traversal depth.\n * @default 'deep'\n */\n depth?: VisitorDepth\n /**\n * Internal parent override used during recursion.\n */\n parent?: Node\n}\n\n/**\n * Options for `collect`.\n *\n * @example\n * ```ts\n * const options: CollectOptions<string> = { depth: 'shallow', schema: () => undefined }\n * ```\n */\nexport type CollectOptions<T> = CollectVisitor<T> & {\n /**\n * Traversal depth.\n * @default 'deep'\n */\n depth?: VisitorDepth\n /**\n * Internal parent override used during recursion.\n */\n parent?: Node\n}\n\nconst visitorKeysByKind = VISITOR_KEYS as Record<string, ReadonlyArray<string> | undefined>\n\n/**\n * Returns `true` when `value` is an AST node (an object carrying a `kind`).\n */\nfunction isNode(value: unknown): value is Node {\n return typeof value === 'object' && value !== null && typeof (value as { kind?: unknown }).kind === 'string'\n}\n\n/**\n * Returns the immediate traversable children of `node` based on {@link VISITOR_KEYS}.\n *\n * `Schema` children are only included when `recurse` is `true`. Shallow mode skips them.\n *\n * @example\n * ```ts\n * const children = getChildren(operationNode, true)\n * // returns parameters, the request body, and responses\n * ```\n */\nfunction* getChildren(node: Node, recurse: boolean): Generator<Node, void, undefined> {\n if (node.kind === 'Schema' && !recurse) return\n\n const keys = visitorKeysByKind[node.kind]\n if (!keys) return\n\n const record = node as unknown as Record<string, unknown>\n for (const key of keys) {\n const value = record[key]\n if (Array.isArray(value)) {\n for (const item of value) if (isNode(item)) yield item\n } else if (isNode(value)) {\n yield value\n }\n }\n}\n\n/**\n * Runs the visitor callback that matches `node.kind` with the traversal\n * context. The result is a replacement node, a collected value, or `undefined`\n * when no callback is registered for the kind.\n *\n * Shared by `transform` and `collectLazy` so node-kind dispatch lives in one place.\n * `TResult` is the caller's expected return: the same node type for `transform`,\n * the collected value type for `collectLazy`.\n */\nfunction applyVisitor<TResult>(node: Node, visitor: Visitor | CollectVisitor<unknown>, parent: Node | undefined): TResult | null | undefined {\n const key = VISITOR_KEY_BY_KIND[node.kind]\n if (!key) return undefined\n\n const fn = visitor[key] as ((node: Node, context: VisitorContext) => TResult | null | undefined) | undefined\n\n return fn?.(node, { parent })\n}\n\n/**\n * Synchronous depth-first transform. Each visitor callback can return a\n * replacement node. Returning `undefined` keeps the original.\n *\n * The original tree is never mutated, a new tree is returned. Pass\n * `depth: 'shallow'` to skip recursion into children.\n *\n * @example Prefix every operationId\n * ```ts\n * const next = transform(root, {\n * operation(node) {\n * return { ...node, operationId: `prefixed_${node.operationId}` }\n * },\n * })\n * ```\n *\n * @example Replace only the root node\n * ```ts\n * const next = transform(root, {\n * depth: 'shallow',\n * input: (node) => ({ ...node, meta: { ...node.meta, title: 'Rewritten' } }),\n * })\n * ```\n */\nexport function transform(node: InputNode, options: TransformOptions): InputNode\nexport function transform(node: OutputNode, options: TransformOptions): OutputNode\nexport function transform(node: OperationNode, options: TransformOptions): OperationNode\nexport function transform(node: SchemaNode, options: TransformOptions): SchemaNode\nexport function transform(node: PropertyNode, options: TransformOptions): PropertyNode\nexport function transform(node: ParameterNode, options: TransformOptions): ParameterNode\nexport function transform(node: ResponseNode, options: TransformOptions): ResponseNode\nexport function transform(node: Node, options: TransformOptions): Node\nexport function transform(node: Node, options: TransformOptions): Node {\n const { depth, parent, ...visitor } = options\n const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep\n\n // Split the visitor object out once here, then thread it plus `recurse`/`parent` as plain\n // arguments through the recursion. The previous code re-ran the `...visitor` rest-destructure on\n // every recursive `transform` call and rebuilt a `{ ...options, parent }` object per node, so the\n // options shape (which callbacks are present) varied call to call and the hot recursion churned.\n return transformNode(node, visitor, recurse, parent)\n}\n\n/**\n * Visits a single node, then immutably rebuilds its children. Returns the original\n * reference when neither the visitor nor the child rebuild changed anything, so callers\n * can detect \"nothing changed\" by identity and ancestors avoid reallocating.\n */\nfunction transformNode(node: Node, visitor: Visitor, recurse: boolean, parent: Node | undefined): Node {\n const visited = applyVisitor<Node>(node, visitor, parent) ?? node\n return transformChildren(visited, visitor, recurse)\n}\n\n/**\n * Immutably rebuilds a node's children using {@link VISITOR_KEYS}, transforming\n * each child node and leaving non-node values (e.g. `additionalProperties: true`) intact.\n * `Schema` children are skipped in shallow mode.\n */\nfunction transformChildren(node: Node, visitor: Visitor, recurse: boolean): Node {\n if (node.kind === 'Schema' && !recurse) return node\n\n const keys = visitorKeysByKind[node.kind]\n if (!keys) return node\n\n const record = node as unknown as Record<string, unknown>\n let updates: Record<string, unknown> | undefined\n\n for (const key of keys) {\n if (!(key in record)) continue\n const value = record[key]\n if (Array.isArray(value)) {\n // Rebuild the array lazily: allocate a new array only once a child actually changes, copying\n // the unchanged prefix at that point. An unchanged array keeps its original reference and\n // allocates nothing. This also drops the per-array `.map` closure that ran on every node.\n let mapped: Array<unknown> | undefined\n for (const [i, item] of value.entries()) {\n const next = isNode(item) ? transformNode(item, visitor, recurse, node) : item\n if (mapped) {\n mapped.push(next)\n continue\n }\n if (next !== item) mapped = [...value.slice(0, i), next]\n }\n if (mapped) (updates ??= {})[key] = mapped\n } else if (isNode(value)) {\n const next = transformNode(value, visitor, recurse, node)\n if (next !== value) (updates ??= {})[key] = next\n }\n }\n\n return updates ? ({ ...node, ...updates } as Node) : node\n}\n/**\n * Lazy depth-first collection pass. Yields every non-null value returned by\n * the visitor callbacks. Use `collect` for the eager array form.\n *\n * @example Collect every operationId\n * ```ts\n * const ids: string[] = []\n * for (const id of collectLazy<string>(root, {\n * operation(node) {\n * return node.operationId\n * },\n * })) {\n * ids.push(id)\n * }\n * ```\n */\nexport function* collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined> {\n const { depth, parent, ...visitor } = options\n const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep\n\n // Thread the split-out visitor through the recursion instead of rebuilding `{ ...options, parent }`\n // for every child, mirroring `transform`. Keeps the recursive object shape stable.\n yield* collectNode<T>(node, visitor as CollectVisitor<T>, recurse, parent)\n}\n\nfunction* collectNode<T>(node: Node, visitor: CollectVisitor<T>, recurse: boolean, parent: Node | undefined): Generator<T, void, undefined> {\n const v = applyVisitor<T>(node, visitor, parent)\n if (v != null) yield v\n\n for (const child of getChildren(node, recurse)) {\n yield* collectNode<T>(child, visitor, recurse, node)\n }\n}\n\n/**\n * Eager depth-first collection pass. Gathers every non-null value the visitor\n * callbacks return into an array.\n *\n * @example Collect every operationId\n * ```ts\n * const ids = collect<string>(root, {\n * operation(node) {\n * return node.operationId\n * },\n * })\n * ```\n */\nexport function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {\n return Array.from(collectLazy(node, options))\n}\n","import type { VisitorDepth } from './constants.ts'\nimport type { VisitorKey } from './defineNode.ts'\nimport { visitorKeys } from './defineNode.ts'\nimport type { Node } from './nodes/index.ts'\nimport type { Visitor, VisitorContext } from './visitor.ts'\nimport { transform } from './visitor.ts'\n\n/**\n * Ordering hint shared by macros and plugins. `pre` runs before unmarked items, `post` after,\n * and `undefined` keeps declaration order.\n */\nexport type Enforce = 'pre' | 'post'\n\n/**\n * Sort weight for an `enforce` hint. `pre` sorts before unmarked items and `post` after, so a plain\n * list keeps its authored order.\n */\nfunction enforceWeight(enforce?: Enforce): number {\n if (enforce === 'pre') return 0\n if (enforce === 'post') return 2\n return 1\n}\n\n/**\n * A named, composable transform over the Kubb AST. It carries the same per-kind callbacks as a\n * {@link Visitor} (`schema`, `operation`, …), plus a `name`, an optional `enforce` order, and an\n * optional `when` gate. Macros run on the shared AST, so the same macro works across every adapter\n * and output target. Exports follow the `macro<Name>` convention, mirroring plugins (`pluginTs`).\n */\nexport type Macro = Visitor & {\n /**\n * Macro identifier used to tell macros apart, for example `'simplify-union'`.\n */\n name: string\n /**\n * Ordering hint. `pre` macros run before unmarked macros, `post` macros run after.\n * Ordering within a bucket follows list order.\n */\n enforce?: Enforce\n /**\n * Gate checked against the current node before any callback runs. When it returns `false`\n * the macro is skipped for that node.\n */\n when?: (node: Node) => boolean\n}\n\n/**\n * Types a macro for inference and a single construction site, mirroring `definePlugin`.\n * Adds no runtime behavior.\n *\n * @example\n * ```ts\n * const macroUntagged = defineMacro({\n * name: 'untagged',\n * operation(node) {\n * return node.tags?.length ? undefined : { ...node, tags: ['untagged'] }\n * },\n * })\n * ```\n */\nexport function defineMacro(macro: Macro): Macro {\n return macro\n}\n\ntype MacroCallback = (node: Node, context: VisitorContext) => Node | null | undefined\n\ntype ChainProps = {\n macros: ReadonlyArray<Macro>\n key: VisitorKey\n node: Node\n context: VisitorContext\n}\n\n/**\n * Runs every macro's callback for one node kind in order, chaining the result so each macro sees\n * the previous macro's output. Returns `undefined` when nothing changed, so `transform` keeps the\n * original reference (structural sharing).\n */\nfunction chain({ macros, key, node, context }: ChainProps): Node | undefined {\n let current = node\n\n for (const macro of macros) {\n const callback = macro[key] as MacroCallback | undefined\n if (!callback) continue\n if (macro.when && !macro.when(current)) continue\n\n const next = callback(current, context)\n if (next != null) current = next\n }\n\n return current === node ? undefined : current\n}\n\n/**\n * Folds an ordered list of macros into a single {@link Visitor} that `transform` (and the per-plugin\n * transform layer in `@kubb/core`) can run. Macros are stable-sorted by `enforce`, then applied\n * sequentially per node so later macros see earlier output. This differs from a plain visitor, which\n * has no names, ordering, or composition.\n *\n * @example\n * ```ts\n * const visitor = composeMacros([macroSimplifyUnion, macroDiscriminatorEnum])\n * const next = transform(root, visitor)\n * ```\n */\nexport function composeMacros(macros: ReadonlyArray<Macro>): Visitor {\n const ordered = [...macros].sort((a, b) => enforceWeight(a.enforce) - enforceWeight(b.enforce))\n\n const visitor: Visitor = {}\n for (const key of visitorKeys) {\n if (!ordered.some((macro) => typeof macro[key] === 'function')) continue\n\n const callback = (node: Node, context: VisitorContext) => chain({ macros: ordered, key, node, context })\n ;(visitor as Record<VisitorKey, MacroCallback>)[key] = callback\n }\n\n return visitor\n}\n\n/**\n * Runs a list of macros over a node tree and returns the rewritten tree. Keeps `transform`'s\n * structural sharing, so an empty or no-op macro list returns the same reference. Pass\n * `depth: 'shallow'` to rewrite the root node only.\n *\n * @example\n * ```ts\n * const next = applyMacros(root, [macroIntegerToString])\n * ```\n *\n * @example Apply to the root node only\n * ```ts\n * const named = applyMacros(node, [macroEnumName({ parentName, propName, enumSuffix })], { depth: 'shallow' })\n * ```\n */\nexport function applyMacros<TNode extends Node>(root: TNode, macros: ReadonlyArray<Macro>, options?: { depth?: VisitorDepth }): TNode {\n if (macros.length === 0) return root\n\n return transform(root, { ...composeMacros(macros), ...options }) as TNode\n}\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Runtime context passed as `this` to printer handlers.\n *\n * `this.transform` dispatches to node-level handlers from `nodes`.\n *\n * @example\n * ```ts\n * const context: PrinterHandlerContext<string, {}> = {\n * options: {},\n * transform: () => 'value',\n * }\n * ```\n */\ntype PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.\n * Use `this.transform` inside `nodes` handlers and inside the `print` override.\n */\n transform: (node: SchemaNode) => TOutput | null\n /**\n * Run the printer's built-in handler for the node, ignoring any override for its type.\n * Inside an override, `this.base(node)` returns what the printer would have emitted,\n * so the override can wrap it instead of re-implementing the handler. Nested nodes\n * still dispatch through the overrides.\n */\n base: (node: SchemaNode) => TOutput | null\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for one schema node type.\n *\n * Use a regular function (not an arrow function) if you need `this`.\n *\n * @example\n * ```ts\n * const handler: PrinterHandler<string, {}, 'string'> = function () {\n * return 'string'\n * }\n * ```\n */\ntype PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null\n\n/**\n * Partial map of per-node-type handler overrides for a printer.\n *\n * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).\n * Supply only the handlers you want to replace. The printer's built-in\n * defaults fill in the rest.\n *\n * @example\n * ```ts\n * pluginZod({\n * printer: {\n * nodes: {\n * date(): string {\n * return 'z.string().date()'\n * },\n * } satisfies PrinterPartial<string, PrinterZodOptions>,\n * },\n * })\n * ```\n */\nexport type PrinterPartial<TOutput, TOptions extends object> = Partial<{\n [K in SchemaType]: PrinterHandler<TOutput, TOptions, K>\n}>\n\n/**\n * Generic shape used by `definePrinter`.\n *\n * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` options passed to and stored on the printer instance\n * - `TOutput` the type emitted by node handlers\n * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)\n *\n * @example\n * ```ts\n * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>\n * ```\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {\n name: TName\n options: TOptions\n output: TOutput\n printOutput: TPrintOutput\n}\n\n/**\n * Printer instance returned by a printer factory.\n *\n * @example\n * ```ts\n * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})\n * ```\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.\n * Always dispatches through the `nodes` map. Never calls the `print` override.\n * Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.\n */\n transform: (node: SchemaNode) => T['output'] | null\n /**\n * Public printer. If the builder provides a root-level `print`, this calls that\n * higher-level function (which may produce full declarations).\n * Otherwise, falls back to the node-level dispatcher.\n */\n print: (node: SchemaNode) => T['printOutput'] | null\n}\n\n/**\n * Builder function passed to `definePrinter`.\n *\n * It receives resolved options and returns:\n * - `name`\n * - `options`\n * - `nodes` handlers\n * - optional top-level `print` override\n *\n * @example\n * ```ts\n * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })\n * ```\n */\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * User-supplied handler overrides. An override wins over the matching `nodes` handler,\n * and can call `this.base(node)` to reuse the handler it replaced. Pass overrides here\n * instead of spreading them into `nodes`, otherwise `this.base` cannot find the original.\n */\n overrides?: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * Optional root-level print override. When provided, becomes the public `printer.print`.\n * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),\n * not the override itself, so recursion is safe.\n */\n print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null\n}\n/**\n * Creates a schema printer: a function that takes a `SchemaNode` and emits\n * code in your target language. Each plugin that produces code from schemas\n * (TypeScript types, Zod schemas, Faker factories) ships a printer built\n * with this helper.\n *\n * The builder receives resolved options and returns:\n *\n * - `name` unique identifier for the printer.\n * - `options` stored on the returned printer instance.\n * - `nodes` map of `SchemaType` → handler. Handlers return the rendered\n * output (a string, a TypeScript AST node, ...) for that schema type.\n * - `overrides` (optional), user-supplied handlers that win over `nodes`.\n * An override can call `this.base(node)` to reuse the handler it replaced.\n * - `print` (optional), top-level override exposed as `printer.print`.\n * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.\n *\n * Without a `print` override, `printer.print` falls back to `printer.transform`\n * (the node-level dispatcher).\n *\n * @example Tiny Zod printer\n * ```ts\n * import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'\n *\n * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>\n *\n * export const zodPrinter = createPrinter<PrinterZod>((options) => ({\n * name: 'zod',\n * options: { strict: options.strict ?? true },\n * nodes: {\n * string: () => 'z.string()',\n * object(node) {\n * const props = node.properties\n * .map((p) => `${p.name}: ${this.transform(p.schema)}`)\n * .join(', ')\n * return `z.object({ ${props} })`\n * },\n * },\n * }))\n * ```\n */\nexport function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes, overrides, print: printOverride } = build(options ?? ({} as T['options']))\n const merged = overrides ? { ...nodes, ...overrides } : nodes\n\n const context = {\n options: resolvedOptions,\n transform: (node: SchemaNode): T['output'] | null => {\n const handler = merged[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n base: (node: SchemaNode): T['output'] | null => {\n const handler = nodes[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n transform: context.transform,\n print: (printOverride ? printOverride.bind(context) : context.transform) as (node: SchemaNode) => T['printOutput'] | null,\n }\n }\n}\n","import { narrowSchema } from '../guards.ts'\nimport { createSchema, type SchemaNode } from '../nodes/schema.ts'\n\n/**\n * Merges a run of adjacent anonymous object members into one. Named or non-object members break the\n * run and pass through unchanged. The merge follows member order, so callers control which members\n * combine by where they place them in the sequence.\n *\n * @example\n * ```ts\n * const merged = [...mergeAdjacentObjectsLazy([objectA, objectB])]\n * ```\n */\nexport function* mergeAdjacentObjectsLazy(members: Iterable<SchemaNode>): Generator<SchemaNode, void, undefined> {\n let acc: SchemaNode | undefined\n\n for (const member of members) {\n const objectMember = narrowSchema(member, 'object')\n if (objectMember && !objectMember.name && acc !== undefined) {\n const accObject = narrowSchema(acc, 'object')\n if (accObject && !accObject.name) {\n acc = createSchema({\n ...accObject,\n properties: [...(accObject.properties ?? []), ...(objectMember.properties ?? [])],\n })\n continue\n }\n }\n if (acc !== undefined) yield acc\n acc = member\n }\n\n if (acc !== undefined) yield acc\n}\n","import { pascalCase } from '@internals/utils'\nimport { narrowSchema } from '../guards.ts'\nimport type { SchemaNode } from '../nodes/index.ts'\nimport { createSchema, type SchemaType } from '../nodes/schema.ts'\n\nconst plainStringTypes = new Set<SchemaType>(['string', 'uuid', 'email', 'url', 'datetime'] as const)\n\n/**\n * Returns the last path segment of a reference string.\n *\n * @example\n * `extractRefName('#/components/schemas/Pet') // 'Pet'`\n */\nexport function extractRefName(ref: string): string {\n return ref.split('/').at(-1) ?? ref\n}\n\n/**\n * Resolves the schema name of a ref node. Uses the last segment of `ref` when set, otherwise falls\n * back to `name` then nested `schema.name`.\n *\n * Returns `null` for non-ref nodes or when no name resolves.\n *\n * @example\n * `resolveRefName({ kind: 'Schema', type: 'ref', ref: '#/components/schemas/Pet' }) // 'Pet'`\n */\nexport function resolveRefName(node: SchemaNode | undefined): string | null {\n if (!node || node.type !== 'ref') return null\n if (node.ref) return extractRefName(node.ref) ?? node.name ?? node.schema?.name ?? null\n\n return node.name ?? node.schema?.name ?? null\n}\n\n/**\n * Builds a PascalCase child schema name by joining a parent name and property name.\n * Returns `null` when there is no parent to nest under.\n *\n * @example Nested under a parent\n * `childName('Order', 'shipping_address') // 'OrderShippingAddress'`\n *\n * @example No parent\n * `childName(undefined, 'params') // null`\n */\nexport function childName(parentName: string | null | undefined, propName: string): string | null {\n return parentName ? pascalCase([parentName, propName].join(' ')) : null\n}\n\n/**\n * Builds a PascalCase enum name from the parent name, property name, and a suffix, skipping any\n * empty parts.\n *\n * @example\n * `enumPropName('Order', 'status', 'enum') // 'OrderStatusEnum'`\n */\nexport function enumPropName(parentName: string | null | undefined, propName: string, enumSuffix: string): string {\n return pascalCase([parentName, propName, enumSuffix].filter(Boolean).join(' '))\n}\n\n/**\n * Merges a ref node with its resolved schema, giving usage-site fields precedence.\n *\n * Every field set on the ref node except `kind`, `type`, `name`, `ref`, and `schema` overrides the\n * same field in the resolved `node.schema` (for example `description`, `nullable`, `readOnly`,\n * `deprecated`). Fields left `undefined` on the ref do not shadow the resolved schema. Non-ref\n * nodes and refs without a resolved `schema` are returned unchanged.\n *\n * @example\n * ```ts\n * const ref = createSchema({ type: 'ref', ref: '#/components/schemas/Pet', description: 'A cute pet' })\n * const merged = syncSchemaRef(ref) // merges with resolved Pet schema\n * ```\n */\nexport function syncSchemaRef(node: SchemaNode): SchemaNode {\n const ref = narrowSchema(node, 'ref')\n\n if (!ref) return node\n if (!ref.schema) return node\n\n const { kind: _kind, type: _type, name: _name, ref: _ref, schema: _schema, ...overrides } = ref\n\n // Filter out undefined override values so they don't shadow the resolved schema's fields.\n const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, v]) => v !== undefined))\n\n return createSchema({ ...ref.schema, ...definedOverrides })\n}\n\n/**\n * Type guard that returns `true` when a schema emits as a plain `string` type.\n *\n * Covers `string`, `uuid`, `email`, `url`, and `datetime` types. For `date` and `time`\n * types, returns `true` only when `representation` is `'string'` rather than `'date'`.\n */\nexport function isStringType(node: SchemaNode): boolean {\n if (plainStringTypes.has(node.type)) {\n return true\n }\n\n const temporal = narrowSchema(node, 'date') ?? narrowSchema(node, 'time')\n if (temporal) {\n return temporal.representation !== 'date'\n }\n\n return false\n}\n","import { memoize } from '@internals/utils'\nimport type { OperationNode, SchemaNode } from '../nodes/index.ts'\nimport { collect, collectLazy } from '../visitor.ts'\nimport { resolveRefName } from './refs.ts'\n\n/**\n * Memoized inner pass that walks a single node and returns the names of every schema it references.\n */\nconst collectSchemaRefs = memoize(new WeakMap<SchemaNode, ReadonlySet<string>>(), (node: SchemaNode): ReadonlySet<string> => {\n const refs = new Set<string>()\n collect<void>(node, {\n schema(child) {\n if (child.type === 'ref') {\n const name = resolveRefName(child)\n if (name) refs.add(name)\n }\n },\n })\n return refs\n})\n\n/**\n * Collects the names of every ref found anywhere inside a node's own subtree.\n *\n * Each ref contributes its name only, so the schema it points to is never traversed here. Pass `out`\n * to accumulate names from several nodes into one set.\n *\n * @example Collect refs from a single schema\n * ```ts\n * const names = collectReferencedSchemaNames(petSchema)\n * // Set { 'Category', 'Tag' }\n * ```\n *\n * @example Accumulate refs from multiple schemas into one set\n * ```ts\n * const out = new Set<string>()\n * for (const schema of schemas) {\n * collectReferencedSchemaNames(schema, out)\n * }\n * ```\n */\nexport function collectReferencedSchemaNames(node: SchemaNode | undefined, out: Set<string> = new Set()): Set<string> {\n if (!node) return out\n for (const name of collectSchemaRefs(node)) out.add(name)\n return out\n}\n\n/**\n * Memoized two-level cache keyed first on the operations array, then on the schemas array.\n */\nconst collectUsedSchemaNamesMemo = memoize(new WeakMap<ReadonlyArray<OperationNode>, (schemas: ReadonlyArray<SchemaNode>) => Set<string>>(), (ops) =>\n memoize(new WeakMap<ReadonlyArray<SchemaNode>, Set<string>>(), (schemas) => computeUsedSchemaNames(ops, schemas)),\n)\n\nfunction computeUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string> {\n const schemaMap = new Map<string, SchemaNode>()\n for (const schema of schemas) {\n if (schema.name) schemaMap.set(schema.name, schema)\n }\n\n const result = new Set<string>()\n\n function visitSchema(schema: SchemaNode): void {\n const directRefs = collectReferencedSchemaNames(schema)\n for (const name of directRefs) {\n if (!result.has(name)) {\n result.add(name)\n const namedSchema = schemaMap.get(name)\n if (namedSchema) visitSchema(namedSchema)\n }\n }\n }\n\n for (const op of operations) {\n for (const schema of collectLazy<SchemaNode>(op, { depth: 'shallow', schema: (node) => node })) {\n visitSchema(schema)\n }\n }\n\n return result\n}\n\n/**\n * Collects the names of all top-level schemas transitively used by a set of operations.\n *\n * An operation uses a schema when its parameters, request body, or responses reference it, directly\n * or through other named schemas. Once a name is added to the result it is not revisited, so\n * reference cycles terminate.\n *\n * Pair it with `include` filters so schemas reachable only from excluded operations stay ungenerated.\n *\n * @example Only generate schemas referenced by included operations\n * ```ts\n * const includedOps = operations.filter((op) => resolver.default.options(op, { options, include }) !== null)\n * const allowed = collectUsedSchemaNames(includedOps, schemas)\n *\n * for (const schema of schemas) {\n * if (schema.name && !allowed.has(schema.name)) continue\n * // generate schema\n * }\n * ```\n */\nexport function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string> {\n return collectUsedSchemaNamesMemo(operations)(schemas)\n}\n\nconst EMPTY_CIRCULAR_SET = new Set<string>()\n\nconst findCircularSchemasMemo = memoize(new WeakMap<ReadonlyArray<SchemaNode>, Set<string>>(), (schemas: ReadonlyArray<SchemaNode>): Set<string> => {\n const graph = new Map<string, Set<string>>()\n\n for (const schema of schemas) {\n if (!schema.name) continue\n graph.set(schema.name, collectReferencedSchemaNames(schema))\n }\n\n const circular = new Set<string>()\n for (const start of graph.keys()) {\n const visited = new Set<string>()\n const stack: Array<string> = [...(graph.get(start) ?? [])]\n while (stack.length > 0) {\n const node = stack.pop()!\n if (node === start) {\n circular.add(start)\n break\n }\n if (visited.has(node)) continue\n visited.add(node)\n\n const next = graph.get(node)\n if (next) for (const r of next) stack.push(r)\n }\n }\n\n return circular\n})\n\n/**\n * Finds every schema that takes part in a circular dependency chain, including direct self-loops.\n *\n * Wrap the returned schema positions in a deferred construct (a lazy getter or `z.lazy(() => …)`) so\n * the generated code does not recurse forever. Refs are followed by name only, so the walk stays\n * linear in the size of the schema graph.\n *\n * @note Call this once on the full graph, then check individual schemas with `containsCircularRef()`.\n */\nexport function findCircularSchemas(schemas: ReadonlyArray<SchemaNode>): Set<string> {\n if (schemas.length === 0) return EMPTY_CIRCULAR_SET\n return findCircularSchemasMemo(schemas)\n}\n\n/**\n * Returns `true` when a schema, or anything nested inside it, references a circular schema.\n *\n * Pass `excludeName` to skip refs to a specific schema, which helps when self-references are handled\n * on their own. Pair it with `findCircularSchemas()` to decide where lazy wrappers go.\n *\n * @note Stops at the first matching circular ref.\n */\nexport function containsCircularRef(\n node: SchemaNode | undefined,\n { circularSchemas, excludeName }: { circularSchemas: ReadonlySet<string>; excludeName?: string },\n): boolean {\n if (!node || circularSchemas.size === 0) return false\n\n for (const _ of collectLazy<true>(node, {\n schema(child) {\n if (child.type !== 'ref') return null\n const name = resolveRefName(child)\n return name && name !== excludeName && circularSchemas.has(name) ? true : null\n },\n })) {\n return true\n }\n\n return false\n}\n","import type { ArraySchemaNode, IntersectionSchemaNode, ObjectSchemaNode, PropertyNode, SchemaNode, UnionSchemaNode } from '../nodes/index.ts'\n\n/**\n * Converts a child schema to printer output. Plugins instantiate it with their own output type:\n * `string` for the zod and faker printers, `ts.TypeNode` for the TypeScript printer. A printer's\n * `this.transform` fits directly, so its `null` for an empty result carries through to `output`.\n */\nexport type SchemaTransform<TOutput> = (schema: SchemaNode) => TOutput\n\n/**\n * A union or intersection member, or an array or tuple item, paired with its transformed output.\n */\nexport type MappedSchema<TOutput> = {\n /**\n * The original child schema, kept so the printer can read its metadata for leaf formatting.\n */\n schema: SchemaNode\n /**\n * The child schema after being run through the transform.\n */\n output: TOutput\n}\n\n/**\n * An object property paired with its transformed output.\n */\nexport type MappedProperty<TOutput> = {\n /**\n * The property name as written on the schema, before any identifier quoting.\n */\n name: string\n /**\n * The original property node, kept so the printer can read `required`, `schema`, and metadata.\n */\n property: PropertyNode\n /**\n * The property schema after being run through the transform.\n */\n output: TOutput\n}\n\n/**\n * Maps each property of an object schema to its transformed output. Pairs every result with the\n * original property so the printer keeps full control over modifiers, getters, and key syntax.\n *\n * @example\n * ```ts\n * const entries = mapSchemaProperties(node, (schema) => this.transform(schema))\n * // entries: [{ name: 'id', property, output: 'z.number()' }, ...]\n * ```\n */\nexport function mapSchemaProperties<TOutput>(node: ObjectSchemaNode, transform: SchemaTransform<TOutput>): Array<MappedProperty<TOutput>> {\n return node.properties.map((property) => ({ name: property.name, property, output: transform(property.schema) }))\n}\n\n/**\n * Maps each member of a union or intersection schema to its transformed output, pairing every\n * result with the original member.\n */\nexport function mapSchemaMembers<TOutput>(node: UnionSchemaNode | IntersectionSchemaNode, transform: SchemaTransform<TOutput>): Array<MappedSchema<TOutput>> {\n return (node.members ?? []).map((schema) => ({ schema, output: transform(schema) }))\n}\n\n/**\n * Maps each item of an array or tuple schema to its transformed output, pairing every result with\n * the original item.\n */\nexport function mapSchemaItems<TOutput>(node: ArraySchemaNode, transform: SchemaTransform<TOutput>): Array<MappedSchema<TOutput>> {\n return (node.items ?? []).map((schema) => ({ schema, output: transform(schema) }))\n}\n","import { defineMacro } from '../defineMacro.ts'\nimport { narrowSchema } from '../guards.ts'\nimport { createProperty } from '../nodes/property.ts'\nimport { createSchema } from '../nodes/schema.ts'\n\ntype Props = {\n propertyName: string\n values: Array<string>\n enumName?: string\n}\n\n/**\n * Builds a macro that replaces a discriminator property's schema with a string enum of the given\n * values. Object schemas that lack the property are returned unchanged.\n *\n * @example\n * ```ts\n * const macro = macroDiscriminatorEnum({ propertyName: 'type', values: ['dog', 'cat'] })\n * const next = applyMacros(objectSchema, [macro], { depth: 'shallow' })\n * ```\n */\nexport function macroDiscriminatorEnum({ propertyName, values, enumName }: Props) {\n return defineMacro({\n name: 'discriminator-enum',\n schema(node) {\n const objectNode = narrowSchema(node, 'object')\n if (!objectNode?.properties?.length) return undefined\n if (!objectNode.properties.some((prop) => prop.name === propertyName)) return undefined\n\n return createSchema({\n ...objectNode,\n properties: objectNode.properties.map((prop) => {\n if (prop.name !== propertyName) return prop\n\n return createProperty({\n ...prop,\n schema: createSchema({\n type: 'enum',\n primitive: 'string',\n enumValues: values,\n name: enumName,\n readOnly: prop.schema.readOnly,\n writeOnly: prop.schema.writeOnly,\n }),\n })\n }),\n })\n },\n })\n}\n","import { defineMacro } from '../defineMacro.ts'\nimport { narrowSchema } from '../guards.ts'\nimport { enumPropName } from '../utils/refs.ts'\n\ntype Props = {\n parentName: string | null | undefined\n propName: string\n enumSuffix: string\n}\n\n/**\n * Builds a macro that names an inline enum schema from its parent and property name. Boolean enums\n * are left anonymous. Non-enum nodes are returned unchanged.\n *\n * @example\n * ```ts\n * const macro = macroEnumName({ parentName: 'Pet', propName: 'status', enumSuffix: 'enum' })\n * const named = applyMacros(propSchema, [macro], { depth: 'shallow' })\n * ```\n */\nexport function macroEnumName({ parentName, propName, enumSuffix }: Props) {\n return defineMacro({\n name: 'enum-name',\n schema(node) {\n const enumNode = narrowSchema(node, 'enum')\n\n if (enumNode?.primitive === 'boolean') return { ...node, name: null }\n if (enumNode) return { ...node, name: enumPropName(parentName, propName, enumSuffix) }\n\n return undefined\n },\n })\n}\n","import { defineMacro } from '../defineMacro.ts'\nimport { narrowSchema } from '../guards.ts'\nimport type { SchemaNode } from '../nodes/schema.ts'\n\ntype ScalarPrimitive = 'string' | 'number' | 'integer' | 'bigint' | 'boolean'\n\n/**\n * Scalar primitive schema types used for union simplification and type narrowing.\n */\nconst SCALAR_PRIMITIVE_TYPES = new Set<ScalarPrimitive>(['string', 'number', 'integer', 'bigint', 'boolean'])\n\nfunction isScalarPrimitive(type: string): type is ScalarPrimitive {\n return SCALAR_PRIMITIVE_TYPES.has(type as ScalarPrimitive)\n}\n\n/**\n * Filters union members, dropping enum members that a broader scalar primitive already covers.\n */\nfunction simplifyUnionMembers(members: Array<SchemaNode>): Array<SchemaNode> {\n const scalarPrimitives = new Set(members.filter((member) => isScalarPrimitive(member.type)).map((m) => m.type))\n if (!scalarPrimitives.size) return members\n\n return members.filter((member) => {\n const enumNode = narrowSchema(member, 'enum')\n if (!enumNode) return true\n\n const primitive = enumNode.primitive\n if (!primitive) return true\n\n const enumValueCount = enumNode.namedEnumValues?.length ?? enumNode.enumValues?.length ?? 0\n if (enumValueCount <= 1) return true\n\n if (scalarPrimitives.has(primitive)) return false\n if ((primitive === 'integer' || primitive === 'number') && (scalarPrimitives.has('integer') || scalarPrimitives.has('number'))) return false\n\n return true\n })\n}\n\n/**\n * Removes union members a broader scalar primitive already covers, such as a multi-value string enum\n * sitting next to a plain `string`. Single-value enums are kept.\n *\n * @example\n * ```ts\n * const next = applyMacros(unionSchema, [macroSimplifyUnion], { depth: 'shallow' })\n * ```\n */\nexport const macroSimplifyUnion = defineMacro({\n name: 'simplify-union',\n schema(node) {\n const unionNode = narrowSchema(node, 'union')\n if (!unionNode?.members?.length) return undefined\n\n const simplified = simplifyUnionMembers(unionNode.members)\n if (simplified.length === unionNode.members.length) return undefined\n\n return { ...unionNode, members: simplified }\n },\n})\n","import type { Node } from './nodes/index.ts'\n\nexport { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'\nexport { createContent } from './nodes/content.ts'\nexport { createExport, createFile, createImport, createSource } from './nodes/file.ts'\nexport type { UserFileNode } from './nodes/file.ts'\nexport { createInput } from './nodes/input.ts'\nexport { createOperation } from './nodes/operation.ts'\nexport { createOutput } from './nodes/output.ts'\nexport { createParameter } from './nodes/parameter.ts'\nexport { createProperty } from './nodes/property.ts'\nexport { createRequestBody } from './nodes/requestBody.ts'\nexport { createResponse } from './nodes/response.ts'\nexport { createSchema } from './nodes/schema.ts'\n\n/**\n * Identity-preserving node update: returns `node` unchanged when every field in\n * `changes` already equals (by reference) the current value, otherwise a new node\n * with the changes applied.\n *\n * Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the\n * structural sharing in {@link transform} so a no-op rewrite does not allocate and\n * downstream passes can detect \"nothing changed\" by identity. Comparison is shallow,\n * so a structurally equal but newly allocated array or object counts as a change.\n *\n * @example\n * ```ts\n * update(node, { name: node.name }) // -> same `node` reference\n * update(node, { name: 'renamed' }) // -> new node, `name` replaced\n * ```\n */\nexport function update<T extends Node>(node: T, changes: Partial<T>): T {\n for (const key in changes) {\n if (changes[key] !== node[key as keyof T]) {\n return { ...node, ...changes }\n }\n }\n\n return node\n}\n","export { schemaTypes } from './constants.ts'\nexport { isHttpOperationNode, narrowSchema } from './guards.ts'\nexport { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'\nexport { defineNode } from './defineNode.ts'\nexport { optionality } from './optionality.ts'\nexport { createPrinter } from './createPrinter.ts'\nexport { collect, transform } from './visitor.ts'\nexport * from './utils/index.ts'\nexport * from './macros/index.ts'\n\nexport * as factory from './factory.ts'\nexport * from './registry.ts'\nexport type * from './types.ts'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["path"],"sources":["../src/constants.ts","../src/guards.ts","../src/defineNode.ts","../src/nodes/code.ts","../src/nodes/content.ts","../../../internals/utils/src/casing.ts","../../../internals/utils/src/fs.ts","../../../internals/utils/src/promise.ts","../src/utils/extractStringsFromNodes.ts","../src/utils/combineFileMembers.ts","../src/nodes/file.ts","../src/nodes/input.ts","../src/nodes/requestBody.ts","../src/nodes/operation.ts","../src/nodes/output.ts","../src/optionality.ts","../src/nodes/parameter.ts","../src/nodes/property.ts","../src/nodes/response.ts","../src/nodes/schema.ts","../src/registry.ts","../src/visitor.ts","../src/defineMacro.ts","../src/createPrinter.ts","../src/utils/mergeAdjacentSchemas.ts","../src/utils/refs.ts","../src/utils/schemaGraph.ts","../src/utils/schemaTraversal.ts","../src/macros/macroDiscriminatorEnum.ts","../src/macros/macroEnumName.ts","../src/macros/macroSimplifyUnion.ts","../src/factory.ts","../src/exports.ts"],"sourcesContent":["import type { SchemaType } from './nodes/schema.ts'\n\n/**\n * Traversal depth for AST visitor utilities.\n *\n * - `'shallow'` recurses through every node except nested `Schema` subtrees, which it treats as\n * leaves: a schema node itself is visited, but its children are not.\n * - `'deep'` recursively visits all descendant nodes, including schema subtrees.\n */\nexport type VisitorDepth = 'shallow' | 'deep'\n\nexport const visitorDepths = {\n shallow: 'shallow',\n deep: 'deep',\n} as const satisfies Record<VisitorDepth, VisitorDepth>\n\n/**\n * Schema type discriminators used by all AST schema nodes.\n *\n * Each value is a stable discriminator across the AST (for example `schema.type === schemaTypes.object`).\n */\nexport const schemaTypes = {\n /**\n * Text value.\n */\n string: 'string',\n /**\n * Floating-point number (`float`, `double`).\n */\n number: 'number',\n /**\n * Whole number (`int32`). Use `bigint` for `int64`.\n */\n integer: 'integer',\n /**\n * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.\n */\n bigint: 'bigint',\n /**\n * Boolean value.\n */\n boolean: 'boolean',\n /**\n * Explicit null value.\n */\n null: 'null',\n /**\n * Any value (no type restriction).\n */\n any: 'any',\n /**\n * Unknown value (must be narrowed before usage).\n */\n unknown: 'unknown',\n /**\n * No return value (`void`).\n */\n void: 'void',\n /**\n * Object with named properties.\n */\n object: 'object',\n /**\n * Sequential list of items.\n */\n array: 'array',\n /**\n * Fixed-length list with position-specific items.\n */\n tuple: 'tuple',\n /**\n * \"One of\" multiple schema members.\n */\n union: 'union',\n /**\n * \"All of\" multiple schema members.\n */\n intersection: 'intersection',\n /**\n * Enum schema.\n */\n enum: 'enum',\n /**\n * Reference to another schema.\n */\n ref: 'ref',\n /**\n * Calendar date (for example `2026-03-24`).\n */\n date: 'date',\n /**\n * Date-time value (for example `2026-03-24T09:00:00Z`).\n */\n datetime: 'datetime',\n /**\n * Time-only value (for example `09:00:00`).\n */\n time: 'time',\n /**\n * UUID value.\n */\n uuid: 'uuid',\n /**\n * Email address value.\n */\n email: 'email',\n /**\n * URL value.\n */\n url: 'url',\n /**\n * IPv4 address value.\n */\n ipv4: 'ipv4',\n /**\n * IPv6 address value.\n */\n ipv6: 'ipv6',\n /**\n * Binary/blob value.\n */\n blob: 'blob',\n /**\n * Impossible value (`never`).\n */\n never: 'never',\n} as const satisfies Record<SchemaType, SchemaType>\n","import type { HttpOperationNode, OperationNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'\n\n/**\n * Narrows a `SchemaNode` to the variant that matches `type`.\n *\n * @example\n * ```ts\n * const schema = createSchema({ type: 'string' })\n * const stringNode = narrowSchema(schema, 'string') // StringSchemaNode | null\n * ```\n */\nexport function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | null {\n return node?.type === type ? (node as SchemaNodeByType[T]) : null\n}\n\n/**\n * Narrows an `OperationNode` to an `HttpOperationNode` so `method` and `path` are present.\n *\n * @example\n * ```ts\n * if (isHttpOperationNode(node)) {\n * console.log(node.method, node.path)\n * }\n * ```\n */\nexport function isHttpOperationNode(node: OperationNode): node is HttpOperationNode {\n return node.protocol === 'http' || (node.method !== undefined && node.path !== undefined)\n}\n","import type { BaseNode, NodeKind } from './nodes/base.ts'\n\n/**\n * Visitor callback names, one per traversable node kind, in traversal order.\n * Kept in sync with the keys of `Visitor` in `visitor.ts`.\n */\nexport const visitorKeys = ['input', 'output', 'operation', 'schema', 'property', 'parameter', 'response'] as const\n\n/**\n * One of the {@link visitorKeys} callback names.\n */\nexport type VisitorKey = (typeof visitorKeys)[number]\n\n/**\n * Distributive `Omit` that preserves each member of a union.\n *\n * @example\n * ```ts\n * type A = { kind: 'a'; keep: string; drop: number }\n * type B = { kind: 'b'; keep: boolean; drop: number }\n * type Result = DistributiveOmit<A | B, 'drop'>\n * // -> { kind: 'a'; keep: string } | { kind: 'b'; keep: boolean }\n * ```\n */\nexport type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Builds a type guard that matches nodes of the given `kind`.\n */\nfunction isKind<T extends BaseNode>(kind: NodeKind) {\n return (node: unknown): node is T => (node as BaseNode | undefined)?.kind === kind\n}\n\n/**\n * The single definition derived from one {@link defineNode} call: the node's\n * `create` builder, its `is` guard, and the traversal metadata the registry\n * collects into the visitor tables.\n */\nexport type NodeDef<TNode extends BaseNode = BaseNode, TInput = never> = {\n /**\n * Node discriminator this definition owns.\n */\n kind: NodeKind\n /**\n * Builds a node from its input, applying `defaults` and the optional `build` hook.\n */\n create: (input: TInput) => TNode\n /**\n * Type guard matching this node kind.\n */\n is: (node: unknown) => node is TNode\n /**\n * Child node fields in traversal order. Feeds `VISITOR_KEYS`.\n */\n children?: ReadonlyArray<string>\n /**\n * Visitor callback name. Feeds `VISITOR_KEY_BY_KIND`.\n */\n visitorKey?: VisitorKey\n}\n\ntype DefineNodeConfig<TNode extends BaseNode, TInput, TBuilt extends object> = {\n kind: TNode['kind']\n defaults?: Partial<TNode>\n build?: (input: TInput) => TBuilt\n children?: ReadonlyArray<string>\n visitorKey?: VisitorKey\n}\n\n/**\n * Defines a node once and derives its `create` builder, `is` guard, and traversal\n * metadata. `create` merges `defaults`, the `build` hook (or the raw input), and the\n * `kind`, so node construction lives in one place without scattered `as` casts.\n *\n * @example Simple node\n * ```ts\n * const importDef = defineNode<ImportNode>({ kind: 'Import' })\n * const createImport = importDef.create\n * ```\n *\n * @example Node with a build hook\n * ```ts\n * const propertyDef = defineNode<PropertyNode, UserPropertyNode>({\n * kind: 'Property',\n * build: (props) => ({ ...props, required: props.required ?? false }),\n * children: ['schema'],\n * visitorKey: 'property',\n * })\n * ```\n */\nexport function defineNode<TNode extends BaseNode, TInput = Omit<TNode, 'kind'>, TBuilt extends object = Omit<TNode, 'kind'>>(\n config: DefineNodeConfig<TNode, TInput, TBuilt>,\n): NodeDef<TNode, TInput> {\n const { kind, defaults, build, children, visitorKey } = config\n\n function create(input: TInput): TNode {\n const base = build ? build(input) : input\n // `kind` is written first so the discriminant lands at a fixed in-object offset for every node\n // of this kind. Hot dispatch paths (`transform`, `walk`, the parser printers) read `node.kind`\n // constantly; a trailing-only `kind` floats its offset with each node's field count and turns\n // those reads megamorphic. The post-spread reassignment keeps `kind` authoritative when an input\n // carries a (wrong) `kind`: it overwrites the offset-0 slot in place without reshaping the node.\n const built = { kind, ...defaults, ...(base as object) }\n const node = built as TNode\n node.kind = kind\n return node\n }\n\n return { kind, create, is: isKind<TNode>(kind), children, visitorKey }\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\n\n/**\n * JSDoc documentation metadata attached to code declarations.\n */\nexport type JSDocNode = {\n /**\n * JSDoc comment lines. `undefined` entries are filtered out during rendering.\n *\n * @example\n * ```ts\n * ['@description A pet resource', '@deprecated']\n * ```\n */\n comments?: Array<string | undefined>\n}\n\n/**\n * AST node representing a TypeScript `const` declaration.\n *\n * Mirrors the props of the `Const` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createConst({ name: 'pet', export: true, asConst: true })\n * // export const pet = ... as const\n * ```\n */\nexport type ConstNode = BaseNode & {\n kind: 'Const'\n /**\n * Name of the constant declaration.\n */\n name: string\n /**\n * Whether the declaration should be exported.\n */\n export?: boolean | null\n /**\n * Explicit type annotation.\n *\n * @example Type reference\n * `'Pet'`\n */\n type?: string | null\n /**\n * JSDoc documentation metadata.\n */\n JSDoc?: JSDocNode | null\n /**\n * Whether to append `as const` to the declaration.\n */\n asConst?: boolean | null\n /**\n * Child nodes representing the value of the constant (children of the `Const` component).\n * Each entry is a {@link CodeNode}. Use {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * AST node representing a TypeScript `type` alias declaration.\n *\n * Mirrors the props of the `Type` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createType({ name: 'Pet', export: true })\n * // export type Pet = ...\n * ```\n */\nexport type TypeNode = BaseNode & {\n kind: 'Type'\n /**\n * Name of the type alias.\n */\n name: string\n /**\n * Whether the declaration should be exported.\n */\n export?: boolean | null\n /**\n * JSDoc documentation metadata.\n */\n JSDoc?: JSDocNode | null\n /**\n * Child nodes representing the type body (children of the `Type` component).\n * Each entry is a {@link CodeNode}. Use {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * AST node representing a TypeScript `function` declaration.\n *\n * Mirrors the props of the `Function` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createFunction({ name: 'getPet', export: true, async: true, returnType: 'Pet' })\n * // export async function getPet(): Promise<Pet> { ... }\n * ```\n */\nexport type FunctionNode = BaseNode & {\n kind: 'Function'\n /**\n * Name of the function.\n */\n name: string\n /**\n * Whether the function is a default export.\n */\n default?: boolean | null\n /**\n * Function parameter list as a pre-rendered string, written verbatim between the parentheses.\n *\n * @example\n * `'id: string, config: Config = {}'`\n */\n params?: string | null\n /**\n * Whether the function should be exported.\n */\n export?: boolean | null\n /**\n * Whether the function is async. When `true`, the return type is wrapped in `Promise<>`.\n */\n async?: boolean | null\n /**\n * TypeScript generic type parameters.\n *\n * @example Constrained generics\n * `['T', 'U extends string']`\n */\n generics?: string | Array<string> | null\n /**\n * Return type annotation.\n *\n * @example Type reference\n * `'Pet'`\n */\n returnType?: string | null\n /**\n * JSDoc documentation metadata.\n */\n JSDoc?: JSDocNode | null\n /**\n * Child nodes representing the function body (children of the `Function` component).\n * Each entry is a {@link CodeNode}. Use {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * AST node representing a TypeScript arrow function (`const name = () => { ... }`).\n *\n * Mirrors the props of the `Function.Arrow` component from `@kubb/renderer-jsx`.\n * The `children` prop of the component is represented as `nodes`.\n *\n * @example\n * ```ts\n * createArrowFunction({ name: 'getPet', export: true, singleLine: true })\n * // export const getPet = () => ...\n * ```\n */\nexport type ArrowFunctionNode = Omit<FunctionNode, 'kind'> & {\n kind: 'ArrowFunction'\n /**\n * Render the arrow function body as a single-line expression.\n */\n singleLine?: boolean | null\n}\n\n/**\n * AST node representing a raw text/string fragment in the source output.\n *\n * Used instead of bare `string` values so that all entries in `nodes` arrays\n * are typed `CodeNode` objects rather than a mixed `CodeNode | string` union.\n *\n * @example\n * ```ts\n * createText('return fetch(id)')\n * // { kind: 'Text', value: 'return fetch(id)' }\n * ```\n */\nexport type TextNode = BaseNode & {\n kind: 'Text'\n /**\n * The raw string content.\n */\n value: string\n}\n\n/**\n * AST node representing a blank line in the source output.\n *\n * Corresponds to `<br/>` in JSX components. `printNodes` turns a `Break` between two\n * statements into one blank line. Consecutive breaks, and breaks at the start or end of\n * the list, are folded away, so a `Break` never produces more than one blank line.\n *\n * @example\n * ```ts\n * createBreak()\n * // { kind: 'Break' }\n * ```\n */\nexport type BreakNode = BaseNode & {\n kind: 'Break'\n}\n\n/**\n * AST node representing a raw JSX fragment in the source output.\n *\n * Mirrors the `Jsx` component from `@kubb/renderer-jsx`. Embeds raw JSX/TSX markup\n * (including fragments `<>…</>`) directly in generated code.\n *\n * @example\n * ```ts\n * createJsx('<>\\n <a href={href}>Open</a>\\n</>')\n * // { kind: 'Jsx', value: '<>\\n <a href={href}>Open</a>\\n</>' }\n * ```\n */\nexport type JsxNode = BaseNode & {\n kind: 'Jsx'\n /**\n * The raw JSX string content.\n */\n value: string\n}\n\n/**\n * Union of all code-generation AST nodes.\n *\n * These nodes mirror the JSX components from `@kubb/renderer-jsx` and are used as\n * structured children in {@link SourceNode.nodes}.\n */\nexport type CodeNode = ConstNode | TypeNode | FunctionNode | ArrowFunctionNode | TextNode | BreakNode | JsxNode\n\n/**\n * Definition for the {@link ConstNode}.\n */\nexport const constDef = defineNode<ConstNode>({ kind: 'Const' })\n\n/**\n * Definition for the {@link TypeNode}.\n */\nexport const typeDef = defineNode<TypeNode>({ kind: 'Type' })\n\n/**\n * Definition for the {@link FunctionNode}.\n */\nexport const functionDef = defineNode<FunctionNode>({ kind: 'Function' })\n\n/**\n * Definition for the {@link ArrowFunctionNode}.\n */\nexport const arrowFunctionDef = defineNode<ArrowFunctionNode>({ kind: 'ArrowFunction' })\n\n/**\n * Definition for the {@link TextNode}.\n */\nexport const textDef = defineNode<TextNode, string>({ kind: 'Text', build: (value) => ({ value }) })\n\n/**\n * Definition for the {@link BreakNode}.\n */\nexport const breakDef = defineNode<BreakNode, void>({ kind: 'Break', build: () => ({}) })\n\n/**\n * Definition for the {@link JsxNode}.\n */\nexport const jsxDef = defineNode<JsxNode, string>({ kind: 'Jsx', build: (value) => ({ value }) })\n\n/**\n * Creates a `ConstNode` representing a TypeScript `const` declaration.\n *\n * @example Exported constant with type and `as const`\n * ```ts\n * createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true })\n * // export const pets: Pet[] = ... as const\n * ```\n */\nexport const createConst = constDef.create\n\n/**\n * Creates a `TypeNode` representing a TypeScript `type` alias declaration.\n *\n * @example\n * ```ts\n * createType({ name: 'Pet', export: true })\n * // export type Pet = ...\n * ```\n */\nexport const createType = typeDef.create\n\n/**\n * Creates a `FunctionNode` representing a TypeScript `function` declaration.\n *\n * @example\n * ```ts\n * createFunction({ name: 'fetchPet', export: true, async: true, returnType: 'Pet' })\n * // export async function fetchPet(): Promise<Pet> { ... }\n * ```\n */\nexport const createFunction = functionDef.create\n\n/**\n * Creates an `ArrowFunctionNode` representing a TypeScript arrow function.\n *\n * @example\n * ```ts\n * createArrowFunction({ name: 'double', export: true, params: 'n: number', singleLine: true })\n * // export const double = (n: number) => ...\n * ```\n */\nexport const createArrowFunction = arrowFunctionDef.create\n\n/**\n * Creates a {@link TextNode} representing a raw string fragment in the source output.\n *\n * @example\n * ```ts\n * createText('return fetch(id)')\n * // { kind: 'Text', value: 'return fetch(id)' }\n * ```\n */\nexport const createText = textDef.create\n\n/**\n * Creates a {@link BreakNode} representing a line break in the source output.\n *\n * @example\n * ```ts\n * createBreak()\n * // { kind: 'Break' }\n * ```\n */\nexport function createBreak(): BreakNode {\n return breakDef.create()\n}\n\n/**\n * Creates a {@link JsxNode} representing a raw JSX fragment in the source output.\n *\n * @example\n * ```ts\n * createJsx('<>\\n <a href={href}>Open</a>\\n</>')\n * // { kind: 'Jsx', value: '<>\\n <a href={href}>Open</a>\\n</>' }\n * ```\n */\nexport const createJsx = jsxDef.create\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * AST node representing one content-type entry of a request body or response.\n *\n * There is one entry per content type declared in the spec (e.g. `application/json`,\n * `multipart/form-data`), and each entry holds its own body schema.\n *\n * @example\n * ```ts\n * const content: ContentNode = {\n * kind: 'Content',\n * contentType: 'application/json',\n * schema: createSchema({ type: 'string' }),\n * }\n * ```\n */\nexport type ContentNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Content'\n /**\n * The content type for this entry (e.g. `'application/json'`).\n */\n contentType: string\n /**\n * Body schema for this content type.\n */\n schema?: SchemaNode\n /**\n * Property keys to exclude from the generated type via `Omit<Type, Keys>`.\n * Set when a referenced schema has `readOnly`/`writeOnly` fields that should be omitted.\n */\n keysToOmit?: Array<string> | null\n}\n\n/**\n * Definition for the {@link ContentNode}.\n */\nexport const contentDef = defineNode<ContentNode>({\n kind: 'Content',\n children: ['schema'],\n})\n\n/**\n * Creates a `ContentNode` for a single request-body or response content type.\n */\nexport const createContent = contentDef.create\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n","import { existsSync } from 'node:fs'\nimport { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { dirname, join, posix, resolve } from 'node:path'\nimport { camelCase } from './casing.ts'\nimport { runtime } from './runtime.ts'\n\n/**\n * Walks up the directory tree from `cwd` (defaults to `process.cwd()`) and\n * returns the absolute path of the nearest `package.json`, or `null` when none\n * is found before reaching the filesystem root.\n *\n * @example\n * ```ts\n * const pkgPath = findPackageJSON('/home/user/project/src') // '/home/user/project/package.json'\n * ```\n */\nexport function findPackageJSON(cwd?: string): string | null {\n let dir = cwd ? resolve(cwd) : process.cwd()\n while (true) {\n const pkgPath = join(dir, 'package.json')\n if (existsSync(pkgPath)) return pkgPath\n const parent = dirname(dir)\n if (parent === dir) return null\n dir = parent\n }\n}\n\n/**\n * Converts all backslashes to forward slashes.\n * Extended-length Windows paths (`\\\\?\\...`) are left unchanged.\n */\nfunction toSlash(p: string): string {\n if (p.startsWith('\\\\\\\\?\\\\')) return p\n\n return p.replaceAll('\\\\', '/')\n}\n\n/**\n * Returns the relative path from `rootDir` to `filePath`, always using forward slashes\n * and prefixed with `./` when not already traversing upward.\n *\n * @example\n * ```ts\n * getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'\n * getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'\n * ```\n */\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = posix.relative(toSlash(rootDir), toSlash(filePath))\n\n return relativePath.startsWith('../') ? relativePath : `./${relativePath}`\n}\n\n/**\n * Resolves to `true` when the file or directory at `path` exists.\n * Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.\n *\n * @example\n * ```ts\n * if (await exists('./kubb.config.ts')) {\n * const content = await read('./kubb.config.ts')\n * }\n * ```\n */\nexport async function exists(path: string): Promise<boolean> {\n if (runtime.isBun) {\n return Bun.file(path).exists()\n }\n return access(path).then(\n () => true,\n () => false,\n )\n}\n\n/**\n * Reads the file at `path` as a UTF-8 string.\n * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.\n *\n * @example\n * ```ts\n * const source = await read('./src/Pet.ts')\n * ```\n */\nexport async function read(path: string): Promise<string> {\n if (runtime.isBun) {\n return Bun.file(path).text()\n }\n return readFile(path, { encoding: 'utf8' })\n}\n\ntype WriteOptions = {\n /**\n * When `true`, re-reads the file immediately after writing and throws if the\n * content does not match — useful for catching write failures on unreliable file systems.\n */\n sanity?: boolean\n}\n\n/**\n * Writes `data` to `path`, trimming leading/trailing whitespace before saving.\n * Skips the write when the trimmed content is empty or identical to what is already on disk.\n * Creates any missing parent directories automatically.\n * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.\n *\n * @example\n * ```ts\n * await write('./src/Pet.ts', source) // writes and returns trimmed content\n * await write('./src/Pet.ts', source) // null — file unchanged\n * await write('./src/Pet.ts', ' ') // null — empty content skipped\n * ```\n */\nexport async function write(path: string, data: string, options: WriteOptions = {}): Promise<string | null> {\n const trimmed = data.trim()\n if (trimmed === '') return null\n\n const resolved = resolve(path)\n\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n const oldContent = (await file.exists()) ? await file.text() : null\n if (oldContent === trimmed) return null\n await Bun.write(resolved, trimmed)\n return trimmed\n }\n\n try {\n const oldContent = await readFile(resolved, { encoding: 'utf-8' })\n if (oldContent === trimmed) return null\n } catch {\n /* file doesn't exist yet */\n }\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, trimmed, { encoding: 'utf-8' })\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n if (savedData !== trimmed) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n return savedData\n }\n\n return trimmed\n}\n\n/**\n * Recursively removes `path`. Silently succeeds when `path` does not exist.\n *\n * @example\n * ```ts\n * await clean('./dist')\n * ```\n */\nexport async function clean(path: string): Promise<void> {\n return rm(path, { recursive: true, force: true })\n}\n\n/**\n * Converts a filesystem path to use POSIX (`/`) separators.\n *\n * Most of the codebase compares and composes paths as strings (prefix matching, joining for\n * import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated\n * paths, but on Windows it returns `\\`-separated paths, which breaks every such comparison.\n *\n * Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the\n * code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is\n * exercisable from POSIX CI.\n *\n * @example\n * toPosixPath('C:\\\\repo\\\\src\\\\pet.ts') // 'C:/repo/src/pet.ts'\n */\nexport function toPosixPath(filePath: string): string {\n return filePath.replaceAll('\\\\', '/')\n}\n\n/**\n * Strips the file extension from a path or file name.\n * Only removes the last `.ext` segment when the dot is not part of a directory name.\n *\n * @example\n * trimExtName('petStore.ts') // 'petStore'\n * trimExtName('/src/models/pet.ts') // '/src/models/pet'\n * trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'\n * trimExtName('noExtension') // 'noExtension'\n */\nexport function trimExtName(text: string): string {\n const dotIndex = text.lastIndexOf('.')\n if (dotIndex > 0 && !text.includes('/', dotIndex)) {\n return text.slice(0, dotIndex)\n }\n return text\n}\n\n/**\n * Builds a nested file path from a dotted name. Splits on dots that precede a letter\n * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases\n * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.\n *\n * Empty segments are dropped before joining. They arise when the name starts with a dot\n * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to\n * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an\n * absolute path, letting generated files escape the configured output directory.\n *\n * @example Nested path from a dotted name\n * `toFilePath('pet.petId') // 'pet/petId'`\n *\n * @example PascalCase the final segment\n * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`\n *\n * @example Suffix applied to the final segment only\n * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`\n */\nexport function toFilePath(name: string, caseLast: (part: string) => string = camelCase): string {\n const parts = name.split(/\\.(?=[a-zA-Z])/)\n return parts\n .map((part, i) => (i === parts.length - 1 ? caseLast(part) : camelCase(part)))\n .filter(Boolean)\n .join('/')\n}\n","import { toError } from './errors.ts'\n\n/** A value that may already be resolved or still pending.\n *\n * @example\n * ```ts\n * function load(id: string): PossiblePromise<string> {\n * return cache.get(id) ?? fetchRemote(id)\n * }\n * ```\n */\nexport type PossiblePromise<T> = Promise<T> | T\n\n/** Returns `true` when `result` is a thenable `Promise`.\n *\n * @example\n * ```ts\n * isPromise(Promise.resolve(1)) // true\n * isPromise(42) // false\n * ```\n */\nexport function isPromise<T>(result: PossiblePromise<T>): result is Promise<T> {\n return result !== null && result !== undefined && typeof (result as Record<string, unknown>)['then'] === 'function'\n}\n\ntype Store<TKey, TValue> = {\n has(key: TKey): boolean\n get(key: TKey): TValue | undefined\n set(key: TKey, value: TValue): unknown\n}\n\n/**\n * Wraps `factory` with a keyed cache backed by the provided store.\n *\n * Pass a `WeakMap` for object keys (results are GC-eligible when the key is\n * collected) or a `Map` for primitive keys. For multi-argument functions,\n * nest two `memoize` calls — the outer keyed by the first argument, the\n * inner (created once per outer miss) keyed by the second.\n *\n * Because the cache is owned by the caller, it can be shared, inspected, or\n * cleared independently of the memoized function.\n *\n * @example Single WeakMap key\n * ```ts\n * const cache = new WeakMap<SchemaNode, Set<string>>()\n * const getRefs = memoize(cache, (node) => collectRefs(node))\n * ```\n *\n * @example Single Map key (primitive)\n * ```ts\n * const cache = new Map<string, Resolver>()\n * const getResolver = memoize(cache, (name) => buildResolver(name))\n * ```\n *\n * @example Two-level (object + primitive)\n * ```ts\n * const outer = new WeakMap<Params[], Map<string, Params[]>>()\n * const fn = memoize(outer, (params) => memoize(new Map(), (key) => transform(params, key)))\n * fn(params)('camelcase')\n * ```\n */\nexport function memoize<TKey, TValue>(store: Store<TKey, TValue>, factory: (key: TKey) => TValue): (key: TKey) => TValue {\n return (key: TKey): TValue => {\n if (store.has(key)) return store.get(key)!\n const value = factory(key)\n store.set(key, value)\n return value\n }\n}\n\ntype SerialRunnerOptions = {\n /**\n * The async work to serialize.\n */\n run(): Promise<void>\n /**\n * Receives errors thrown by `run`, so a failure never rejects the returned trigger.\n */\n onError(error: Error): void\n}\n\n/**\n * Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight\n * marks it dirty and runs once more after it finishes, no matter how many triggers arrived.\n * Useful for event-driven reruns (a file watcher, a queue drain) where bursts should\n * coalesce into a single trailing run.\n *\n * @example\n * ```ts\n * const rebuild = createSerialRunner({\n * run: () => build(),\n * onError: (error) => log.error(error.message),\n * })\n * watcher.on('change', () => void rebuild())\n * ```\n */\nexport function createSerialRunner({ run, onError }: SerialRunnerOptions): () => Promise<void> {\n let running = false\n let dirty = false\n\n return async (): Promise<void> => {\n if (running) {\n dirty = true\n return\n }\n running = true\n do {\n dirty = false\n try {\n await run()\n } catch (error) {\n onError(toError(error))\n }\n } while (dirty)\n running = false\n }\n}\n","import type { CodeNode } from '../nodes/code.ts'\n\n/**\n * Extracts all string content from a `CodeNode` tree recursively.\n *\n * Collects text node values, identifier references in string fields (`params`, `generics`, `returnType`, `type`),\n * and nested node content. Used to build the full source string for import filtering.\n */\nexport function extractStringsFromNodes(nodes: Array<CodeNode> | undefined): string {\n if (!nodes?.length) return ''\n\n // Imperative single pass. The earlier `map().filter().join()` allocated a closure plus two\n // intermediate arrays per call, and this runs recursively over every code node during file\n // assembly, so the churn showed up in deopt traces. Appending directly keeps it flat.\n const collected: Array<string> = []\n\n for (const node of nodes) {\n // Backward-compat: compiled plugins may still pass bare strings at runtime\n if (typeof node === 'string') {\n if (node) collected.push(node as string)\n continue\n }\n if (node.kind === 'Text') {\n if (node.value) collected.push(node.value)\n continue\n }\n if (node.kind === 'Break') continue\n if (node.kind === 'Jsx') {\n if (node.value) collected.push(node.value)\n continue\n }\n\n const parts: Array<string> = []\n if ('params' in node && node.params) parts.push(node.params)\n if ('generics' in node && node.generics) parts.push(Array.isArray(node.generics) ? node.generics.join(', ') : node.generics)\n if ('returnType' in node && node.returnType) parts.push(node.returnType)\n if ('type' in node && typeof node.type === 'string') parts.push(node.type)\n\n const nested = extractStringsFromNodes(node.nodes)\n if (nested) parts.push(nested)\n\n if (parts.length) collected.push(parts.join('\\n'))\n }\n\n return collected.join('\\n')\n}\n","/**\n * File-member merging. `combineImports` and `combineExports` deduplicate and sort the import and\n * export entries of one file, while `combineSources` deduplicates source entries in original order.\n * `combineImports` also drops imports nothing references. This works on a file's members, not on\n * schema content.\n */\nimport type { ExportNode, ImportNode, SourceNode } from '../nodes/index.ts'\nimport { extractStringsFromNodes } from './extractStringsFromNodes.ts'\n\nfunction sourceKey(source: SourceNode): string {\n const nameKey = source.name ?? extractStringsFromNodes(source.nodes)\n return `${nameKey}:${source.isExportable ?? false}:${source.isTypeOnly ?? false}`\n}\n\nfunction pathTypeKey(path: string, isTypeOnly: boolean | null | undefined): string {\n return `${path}:${isTypeOnly ?? false}`\n}\n\nfunction exportKey(path: string, name: string | null | undefined, isTypeOnly: boolean | null | undefined, asAlias: boolean | null | undefined): string {\n return `${path}:${name ?? ''}:${isTypeOnly ?? false}:${asAlias ?? ''}`\n}\n\nfunction importKey(path: string, name: string | null | undefined, isTypeOnly: boolean | null | undefined): string {\n return `${path}:${name ?? ''}:${isTypeOnly ?? false}`\n}\n\n/**\n * Computes a multi-level sort key for exports and imports:\n * non-array names first (wildcards/namespace aliases). Type-only before value. Alphabetical path. Unnamed before named.\n */\nfunction sortKey(node: { name?: string | Array<unknown> | null; isTypeOnly?: boolean | null; path: string }): string {\n const isArray = Array.isArray(node.name) ? '1' : '0'\n const typeOnly = node.isTypeOnly ? '0' : '1'\n const hasName = node.name != null ? '1' : '0'\n const name = Array.isArray(node.name) ? node.name.toSorted().join('\\0') : (node.name ?? '')\n return `${isArray}:${typeOnly}:${node.path}:${hasName}:${name}`\n}\n\n/**\n * Deduplicates `SourceNode` objects by `name + isExportable + isTypeOnly`, keeping the first of each\n * key. Unnamed sources fall back to their extracted node strings as the name part of the key. Returns\n * the deduplicated array in original order.\n */\nexport function combineSources(sources: Array<SourceNode>): Array<SourceNode> {\n const seen = new Map<string, SourceNode>()\n for (const source of sources) {\n const key = sourceKey(source)\n if (!seen.has(key)) seen.set(key, source)\n }\n return [...seen.values()]\n}\n\n/**\n * Merges `incoming` names into `existing`, preserving order and dropping duplicates.\n *\n * Shared by `combineExports` and `combineImports` for the same-path name-merge case.\n */\nfunction mergeNameArrays<TName>(existing: Array<TName>, incoming: Array<TName>): Array<TName> {\n const merged = new Set(existing)\n for (const name of incoming) merged.add(name)\n return [...merged]\n}\n\n/**\n * Deduplicates and merges `ExportNode` objects by path and type.\n *\n * Named exports with the same path and `isTypeOnly` flag have their names merged into a single export.\n * Non-array exports are deduplicated by exact identity. Returns a sorted, deduplicated array.\n */\nexport function combineExports(exports: Array<ExportNode>): Array<ExportNode> {\n const result: Array<ExportNode> = []\n // Accumulates array-named exports keyed by `path:isTypeOnly` for name-merging\n const namedByPath = new Map<string, ExportNode>()\n // Deduplicates non-array exports by their exact identity\n const seen = new Set<string>()\n\n // Precompute sort keys once, avoids recomputing per comparison.\n const keyed = exports.map((node) => ({ node, key: sortKey(node) }))\n keyed.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n\n for (const { node: curr } of keyed) {\n const { name, path, isTypeOnly, asAlias } = curr\n\n if (Array.isArray(name)) {\n if (!name.length) continue\n\n const key = pathTypeKey(path, isTypeOnly)\n const existing = namedByPath.get(key)\n\n if (existing && Array.isArray(existing.name)) {\n existing.name = mergeNameArrays(existing.name, name)\n } else {\n const newItem: ExportNode = { ...curr, name: [...new Set(name)] }\n result.push(newItem)\n namedByPath.set(key, newItem)\n }\n } else {\n const key = exportKey(path, name, isTypeOnly, asAlias)\n if (!seen.has(key)) {\n result.push(curr)\n seen.add(key)\n }\n }\n }\n\n return result\n}\n\n/**\n * Deduplicates and merges `ImportNode` objects, filtering out unused imports.\n *\n * Retains imports that are referenced in `source` or re-exported. Imports with the same path and\n * `isTypeOnly` flag have their names merged. Returns a sorted, deduplicated, filtered array.\n */\nexport function combineImports(imports: Array<ImportNode>, exports: Array<ExportNode>, source?: string): Array<ImportNode> {\n // Build a lookup of all exported names to retain imports that are re-exported\n const exportedNames = new Set(exports.flatMap((e) => (Array.isArray(e.name) ? e.name : e.name ? [e.name] : [])))\n const isUsed = (importName: string): boolean => !source || source.includes(importName) || exportedNames.has(importName)\n\n // Memoize object import names so the same logical (propertyName, name) pair always\n // reuses the same object reference. Set-based deduplication then works correctly.\n const importNameMemo = new Map<string, { propertyName: string; name?: string }>()\n const canonicalizeName = (n: string | { propertyName: string; name?: string }): string | { propertyName: string; name?: string } => {\n if (typeof n === 'string') return n\n const key = `${n.propertyName}:${n.name ?? ''}`\n if (!importNameMemo.has(key)) importNameMemo.set(key, n)\n return importNameMemo.get(key)!\n }\n\n // Paths that keep at least one used named import. A default import from such a path is retained\n // even when its binding can't be found in `source` e.g. a generated `client` default import\n // alongside `import type { Client } from <same path>`, where merged grouped output omits the body.\n const pathsWithUsedNamedImport = new Set<string>()\n for (const node of imports) {\n if (!Array.isArray(node.name)) continue\n if (node.name.some((item) => (typeof item === 'string' ? isUsed(item) : isUsed(item.name ?? item.propertyName)))) {\n pathsWithUsedNamedImport.add(node.path)\n }\n }\n\n const result: Array<ImportNode> = []\n // Accumulates array-named imports keyed by `path:isTypeOnly` for name-merging\n const namedByPath = new Map<string, ImportNode>()\n // Deduplicates non-array imports by their exact identity\n const seen = new Set<string>()\n\n // Precompute sort keys once, avoids recomputing per comparison.\n const keyed = imports.map((node) => ({ node, key: sortKey(node) }))\n keyed.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n\n for (const { node: curr } of keyed) {\n if (curr.path === curr.root) continue\n\n const { path, isTypeOnly } = curr\n let { name } = curr\n\n if (Array.isArray(name)) {\n name = [...new Set(name.map(canonicalizeName))].filter((item) => (typeof item === 'string' ? isUsed(item) : isUsed(item.name ?? item.propertyName)))\n if (!name.length) continue\n\n const key = pathTypeKey(path, isTypeOnly)\n const existing = namedByPath.get(key)\n\n if (existing && Array.isArray(existing.name)) {\n existing.name = mergeNameArrays(existing.name, name)\n } else {\n const newItem: ImportNode = { ...curr, name }\n result.push(newItem)\n namedByPath.set(key, newItem)\n }\n } else {\n if (name && !isUsed(name) && !pathsWithUsedNamedImport.has(path)) continue\n\n const key = importKey(path, name, isTypeOnly)\n if (!seen.has(key)) {\n result.push(curr)\n seen.add(key)\n }\n }\n }\n\n return result\n}\n","import { hash } from 'node:crypto'\nimport path from 'node:path'\nimport { trimExtName } from '@internals/utils'\nimport { defineNode } from '../defineNode.ts'\nimport { combineExports, combineImports, combineSources } from '../utils/combineFileMembers.ts'\nimport { extractStringsFromNodes } from '../utils/extractStringsFromNodes.ts'\nimport type { BaseNode } from './base.ts'\nimport type { CodeNode } from './code.ts'\n\n/**\n * Supported file extensions.\n */\ntype Extname = '.ts' | '.js' | '.tsx' | '.json' | `.${string}`\n\ntype ImportName = string | Array<string | { propertyName: string; name?: string }>\n\n/**\n * Represents a language-agnostic import/dependency declaration.\n *\n * @example Named import (TypeScript: `import { useState } from 'react'`)\n * ```ts\n * createImport({ name: ['useState'], path: 'react' })\n * ```\n *\n * @example Default import (TypeScript: `import React from 'react'`)\n * ```ts\n * createImport({ name: 'React', path: 'react' })\n * ```\n *\n * @example Type-only import (TypeScript: `import type { FC } from 'react'`)\n * ```ts\n * createImport({ name: ['FC'], path: 'react', isTypeOnly: true })\n * ```\n *\n * @example Namespace import (TypeScript: `import * as React from 'react'`)\n * ```ts\n * createImport({ name: 'React', path: 'react', isNameSpace: true })\n * ```\n */\nexport type ImportNode = BaseNode & {\n kind: 'Import'\n /**\n * Import name(s) to be used.\n *\n * @example Named imports\n * `['useState']`\n *\n * @example Default import\n * `'React'`\n */\n name: ImportName\n /**\n * Path for the import.\n *\n * @example\n * `'@kubb/core'`\n */\n path: string\n /**\n * Add a type-only import prefix.\n * - `true` generates `import type { Type } from './path'`\n * - `false` generates `import { Type } from './path'`\n */\n isTypeOnly?: boolean | null\n /**\n * Import the entire module as a namespace.\n * - `true` generates `import * as Name from './path'`\n * - `false` generates a standard import\n */\n isNameSpace?: boolean | null\n /**\n * When set, the import path is resolved relative to this root.\n */\n root?: string | null\n}\n\n/**\n * Represents a language-agnostic export/public API declaration.\n *\n * @example Named export (TypeScript: `export { Pets } from './Pets'`)\n * ```ts\n * createExport({ name: ['Pets'], path: './Pets' })\n * ```\n *\n * @example Type-only export (TypeScript: `export type { Pet } from './Pet'`)\n * ```ts\n * createExport({ name: ['Pet'], path: './Pet', isTypeOnly: true })\n * ```\n *\n * @example Wildcard export (TypeScript: `export * from './utils'`)\n * ```ts\n * createExport({ path: './utils' })\n * ```\n *\n * @example Namespace alias (TypeScript: `export * as utils from './utils'`)\n * ```ts\n * createExport({ name: 'utils', path: './utils', asAlias: true })\n * ```\n */\nexport type ExportNode = BaseNode & {\n kind: 'Export'\n /**\n * Export name(s) to be used. When omitted, generates a wildcard export.\n *\n * @example Named exports\n * `['useState']`\n *\n * @example Single export\n * `'React'`\n */\n name?: string | Array<string> | null\n /**\n * Path for the export.\n *\n * @example\n * `'@kubb/core'`\n */\n path: string\n /**\n * Add a type-only export prefix.\n * - `true` generates `export type { Type } from './path'`\n * - `false` generates `export { Type } from './path'`\n */\n isTypeOnly?: boolean | null\n /**\n * Export as an aliased namespace.\n * - `true` generates `export * as aliasName from './path'`\n * - `false` generates a standard export\n */\n asAlias?: boolean | null\n}\n\n/**\n * Represents a fragment of source code within a file.\n *\n * @example Named exportable source\n * ```ts\n * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true, isIndexable: true })\n * ```\n *\n * @example Inline unnamed code block\n * ```ts\n * createSource({ nodes: [createText('const x = 1')] })\n * ```\n */\nexport type SourceNode = BaseNode & {\n kind: 'Source'\n /**\n * Optional name identifying this source (used for deduplication and barrel generation).\n */\n name?: string | null\n /**\n * Mark this source as a type-only export.\n */\n isTypeOnly?: boolean | null\n /**\n * Include the `export` keyword in the generated source.\n */\n isExportable?: boolean | null\n /**\n * Include this source in barrel/index file generation.\n */\n isIndexable?: boolean | null\n /**\n * Child nodes that make up this source fragment, in DOM order.\n * Use a {@link TextNode} for raw string content.\n */\n nodes?: Array<CodeNode>\n}\n\n/**\n * Represents a fully resolved file in the AST.\n *\n * Created via `createFile()`, which computes the `id`, `name`, and `extname` from the input\n * and deduplicates `imports`, `exports`, and `sources`.\n *\n * @example\n * ```ts\n * const file = createFile({\n * baseName: 'petStore.ts',\n * path: 'src/models/petStore.ts',\n * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })],\n * imports: [createImport({ name: ['z'], path: 'zod' })],\n * exports: [createExport({ name: ['Pet'], path: './petStore' })],\n * })\n * // file.id = SHA256 hash of the path\n * // file.name = 'petStore'\n * // file.extname = '.ts'\n * ```\n */\nexport type FileNode<TMeta extends object = object> = BaseNode & {\n kind: 'File'\n /**\n * Unique identifier derived from a SHA256 hash of the file path. `createFile`\n * computes it, so callers do not need to provide it.\n */\n id: string\n /**\n * File name without extension, derived from `baseName`.\n *\n * @see https://nodejs.org/api/path.html#pathformatpathobject\n */\n name: string\n /**\n * File base name, including extension, shaped like `${name}${extname}`.\n *\n * @see https://nodejs.org/api/path.html#pathbasenamepath-suffix\n */\n baseName: `${string}.${string}`\n /**\n * Full qualified path to the file.\n */\n path: string\n /**\n * File extension extracted from `baseName`.\n */\n extname: Extname\n /**\n * Deduplicated list of source code fragments.\n */\n sources: Array<SourceNode>\n /**\n * Deduplicated list of import declarations.\n */\n imports: Array<ImportNode>\n /**\n * Deduplicated list of export declarations.\n */\n exports: Array<ExportNode>\n /**\n * Optional metadata attached to this file, read by plugins during barrel generation.\n */\n meta?: TMeta\n /**\n * Optional banner prepended to the generated file content.\n * Accepts `null` so `resolver.default.banner()` results can be passed directly.\n */\n banner?: string | null\n /**\n * Optional footer appended to the generated file content.\n * Accepts `null` so `resolver.default.footer()` results can be passed directly.\n */\n footer?: string | null\n /**\n * Absolute on-disk path to copy verbatim into the output, bypassing the parser.\n *\n * Use to emit a real source file shipped inside a package (a template) into the generated\n * folder without reformatting or import reordering. Only `banner` and `footer` are applied\n * around the copied content. When set, `copy` provides the file content and any `sources`\n * nodes are ignored for output; `sources` may still carry `name`/`isExportable`/`isIndexable`\n * so barrel generation treats the file the same as a rendered one.\n */\n copy?: string | null\n}\n\n/**\n * Definition for the {@link ImportNode}.\n */\nexport const importDef = defineNode<ImportNode>({ kind: 'Import' })\n\n/**\n * Definition for the {@link ExportNode}.\n */\nexport const exportDef = defineNode<ExportNode>({ kind: 'Export' })\n\n/**\n * Definition for the {@link SourceNode}.\n */\nexport const sourceDef = defineNode<SourceNode>({ kind: 'Source' })\n\n/**\n * Definition for the {@link FileNode}. The fully resolved builder lives in\n * `createFile`, so this definition only supplies the guard.\n */\nexport const fileDef = defineNode<FileNode>({ kind: 'File' })\n\n/**\n * Creates an `ImportNode` representing a language-agnostic import/dependency declaration.\n *\n * @example Named import\n * ```ts\n * createImport({ name: ['useState'], path: 'react' })\n * // import { useState } from 'react'\n * ```\n */\nexport const createImport = importDef.create\n\n/**\n * Creates an `ExportNode` representing a language-agnostic export/public API declaration.\n *\n * @example Named export\n * ```ts\n * createExport({ name: ['Pet'], path: './Pet' })\n * // export { Pet } from './Pet'\n * ```\n */\nexport const createExport = exportDef.create\n\n/**\n * Creates a `SourceNode` representing a fragment of source code within a file.\n *\n * @example\n * ```ts\n * createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')], isExportable: true })\n * ```\n */\nexport const createSource = sourceDef.create\n\n/**\n * Input descriptor for {@link createFile}, before `id`, `name`, and `extname` are computed\n * and `imports`/`exports`/`sources` are deduplicated.\n */\nexport type UserFileNode<TMeta extends object = object> = Omit<FileNode<TMeta>, 'kind' | 'id' | 'name' | 'extname' | 'imports' | 'exports' | 'sources'> &\n Pick<Partial<FileNode<TMeta>>, 'imports' | 'exports' | 'sources'>\n\n/**\n * Creates a fully resolved `FileNode` from a file input descriptor.\n *\n * Computes:\n * - `id` SHA256 hash of the file path\n * - `name` `baseName` without extension\n * - `extname` extension extracted from `baseName`\n *\n * Deduplicates:\n * - `sources` via `combineSources`\n * - `exports` via `combineExports`\n * - `imports` via `combineImports` (also filters unused imports)\n *\n * @throws {Error} when `baseName` has no extension.\n *\n * @example\n * ```ts\n * const file = createFile({\n * baseName: 'petStore.ts',\n * path: 'src/models/petStore.ts',\n * sources: [createSource({ name: 'Pet', nodes: [createText('export type Pet = { id: number }')] })],\n * imports: [createImport({ name: ['z'], path: 'zod' })],\n * exports: [createExport({ name: ['Pet'], path: './petStore' })],\n * })\n * // file.id = SHA256 hash of 'src/models/petStore.ts'\n * // file.name = 'petStore'\n * // file.extname = '.ts'\n * ```\n *\n * @example Copy a real file into the output verbatim\n * ```ts\n * const file = createFile({\n * baseName: 'client.ts',\n * path: 'src/gen/client.ts',\n * copy: '/abs/path/to/templates/client.ts',\n * })\n * ```\n */\nexport function createFile<TMeta extends object = object>(input: UserFileNode<TMeta>): FileNode<TMeta> {\n const extname = path.extname(input.baseName) as `.${string}`\n if (!extname) {\n throw new Error(`No extname found for ${input.baseName}`)\n }\n\n const resolvedExports = input.exports?.length ? combineExports(input.exports) : []\n\n // Skip building the source text and local-name set when there are no imports to resolve against them.\n const resolvedImports: Array<ImportNode> = (() => {\n if (!input.imports?.length) return []\n\n const sourceParts: Array<string> = []\n const localNames = new Set<string>()\n for (const item of input.sources ?? []) {\n const extracted = item.nodes && extractStringsFromNodes(item.nodes)\n if (extracted) sourceParts.push(extracted)\n if (item.name) localNames.add(item.name)\n }\n const source = sourceParts.join('\\n') || undefined\n const combinedImports = combineImports(input.imports, resolvedExports, source)\n const nameOf = (item: string | { propertyName: string; name?: string }): string => (typeof item === 'string' ? item : (item.name ?? item.propertyName))\n // Consolidating output (`mode: 'file'`) can put a symbol's definition and an import of it in the\n // same file: by path when the import still targets this file, by name when consolidation moved it.\n return combinedImports.flatMap((imp) => {\n if (imp.path === input.path) return []\n if (!Array.isArray(imp.name)) {\n return typeof imp.name === 'string' && localNames.has(imp.name) ? [] : [imp]\n }\n const kept = imp.name.filter((item) => !localNames.has(nameOf(item)))\n\n if (!kept.length) return []\n return [kept.length === imp.name.length ? imp : { ...imp, name: kept }]\n })\n })()\n const resolvedSources = input.sources?.length ? combineSources(input.sources) : []\n\n return {\n kind: 'File',\n ...input,\n id: hash('sha256', input.path, 'hex'),\n name: trimExtName(input.baseName),\n extname,\n imports: resolvedImports,\n exports: resolvedExports,\n sources: resolvedSources,\n meta: (input.meta ?? {}) as TMeta,\n }\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { OperationNode } from './operation.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * Metadata for an API document, populated by the adapter and available to every generator.\n *\n * All fields are plain JSON-serializable values, no `Set`, no `Map`, no class instances.\n * Computed fields (`circularNames`, `enumNames`) are pre-calculated once during the adapter\n * pre-scan so generators never need to iterate the full schema list themselves.\n *\n * @example\n * ```ts\n * const meta: InputMeta = { title: 'Pet Store', version: '1.0.0', baseURL: 'https://api.example.com/v2', circularNames: [], enumNames: [] }\n * ```\n */\nexport type InputMeta = {\n /**\n * API title from `info.title` in the source document.\n */\n title?: string\n /**\n * API description from `info.description` in the source document.\n */\n description?: string\n /**\n * API version string from `info.version` in the source document.\n */\n version?: string\n /**\n * Resolved base URL from the first matching server entry in the source document.\n */\n baseURL?: string | null\n /**\n * Names of schemas that participate in a circular reference chain.\n * Computed once during the adapter pre-scan, so a generator never has to\n * call `findCircularSchemas` itself.\n *\n * Convert to a `Set` once at the start of a generator, not per-schema,\n * so lookups stay O(1) without repeated allocations.\n *\n * @example Wrap a circular schema in z.lazy()\n * ```ts\n * const circular = new Set(meta.circularNames)\n * if (circular.has(schema.name)) { ... }\n * ```\n */\n circularNames: ReadonlyArray<string>\n /**\n * Names of schemas whose type is `enum`.\n * Computed once during the adapter pre-scan, so a generator never has to\n * filter the schema list itself.\n *\n * Convert to a `Set` once at the start of a generator when you need repeated\n * membership checks, so each check stays O(1) instead of an array scan.\n *\n * @example Check if a referenced schema is an enum\n * `const enums = new Set(meta.enumNames)`\n * `const isEnum = enums.has(schemaName)`\n */\n enumNames: ReadonlyArray<string>\n}\n\n/**\n * Input AST node that contains all schemas and operations for one API document.\n * Produced by the adapter and consumed by all Kubb plugins.\n *\n * @example\n * ```ts\n * const input: InputNode = {\n * kind: 'Input',\n * schemas: [],\n * operations: [],\n * meta: { circularNames: [], enumNames: [] },\n * }\n * ```\n */\nexport type InputNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Input'\n /**\n * All schema nodes in the document.\n */\n schemas: Array<SchemaNode>\n /**\n * All operation nodes in the document.\n */\n operations: Array<OperationNode>\n /**\n * Document metadata populated by the adapter.\n */\n meta: InputMeta\n}\n\n/**\n * Definition for the {@link InputNode}.\n */\nexport const inputDef = defineNode<InputNode, Partial<Omit<InputNode, 'kind'>>>({\n kind: 'Input',\n defaults: { schemas: [], operations: [], meta: { circularNames: [], enumNames: [] } },\n children: ['schemas', 'operations'],\n visitorKey: 'input',\n})\n\n/**\n * Creates an `InputNode`, defaulting `schemas`/`operations` to empty arrays and `meta` per\n * {@link inputDef}.\n *\n * @example\n * ```ts\n * const input = createInput()\n * // { kind: 'Input', schemas: [], operations: [] }\n * ```\n */\nexport function createInput(overrides: Partial<Omit<InputNode, 'kind'>> = {}): InputNode {\n return inputDef.create(overrides)\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { ContentNode } from './content.ts'\n\n/**\n * AST node representing an operation request body.\n *\n * Body schemas live exclusively inside the `content` array (one entry per content type),\n * mirroring {@link ResponseNode}.\n *\n * @example\n * ```ts\n * const requestBody: RequestBodyNode = {\n * kind: 'RequestBody',\n * required: true,\n * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],\n * }\n * ```\n */\nexport type RequestBodyNode = BaseNode & {\n kind: 'RequestBody'\n /**\n * Request body description carried over from the spec.\n */\n description?: string\n /**\n * Whether the request body is required (`requestBody.required: true` in the spec).\n * When `false` or absent, the generated `data` parameter should be optional.\n */\n required?: boolean\n /**\n * Content type entries for this request body.\n *\n * When the adapter `contentType` option is set, this array contains exactly one entry for\n * that content type. Otherwise it contains one entry per content type declared in the spec,\n * so plugins can generate code for every variant (for example, separate hooks for\n * `application/json` and `multipart/form-data`).\n */\n content?: Array<ContentNode>\n}\n\n/**\n * Definition for the {@link RequestBodyNode}. Content entries are built upfront with\n * {@link createContent}, mirroring how `parameters` and `responses` take prebuilt nodes.\n */\nexport const requestBodyDef = defineNode<RequestBodyNode>({\n kind: 'RequestBody',\n children: ['content'],\n})\n\n/**\n * Creates a `RequestBodyNode`.\n */\nexport const createRequestBody = requestBodyDef.create\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { ParameterNode } from './parameter.ts'\nimport { createRequestBody, type RequestBodyNode } from './requestBody.ts'\nimport type { ResponseNode } from './response.ts'\n\n/**\n * HTTP method an operation responds to.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE'\n\n/**\n * Transport an operation belongs to.\n */\ntype OperationProtocol = 'http'\n\n/**\n * Fields shared by every operation, regardless of transport.\n */\ntype OperationNodeBase = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Operation'\n /**\n * Stable identifier for the operation.\n */\n operationId: string\n /**\n * Group labels for the operation.\n */\n tags: Array<string>\n /**\n * Short one-line operation summary.\n */\n summary?: string\n /**\n * Full operation description.\n */\n description?: string\n /**\n * Marks the operation as deprecated.\n */\n deprecated?: boolean\n /**\n * Query, path, header, and cookie parameters for the operation.\n */\n parameters: Array<ParameterNode>\n /**\n * Request body for the operation.\n */\n requestBody?: RequestBodyNode\n /**\n * Operation responses.\n */\n responses: Array<ResponseNode>\n}\n\n/**\n * Operation served over HTTP. `method` and `path` are guaranteed.\n *\n * @example\n * ```ts\n * const operation: HttpOperationNode = {\n * kind: 'Operation',\n * operationId: 'listPets',\n * protocol: 'http',\n * method: 'GET',\n * path: '/pets',\n * tags: [],\n * parameters: [],\n * responses: [],\n * }\n * ```\n */\nexport type HttpOperationNode = OperationNodeBase & {\n /**\n * Transport the operation belongs to.\n */\n protocol?: 'http'\n /**\n * HTTP method like `'GET'`.\n */\n method: HttpMethod\n /**\n * Path string, for example `/pets/{petId}`, with `{param}` notation preserved.\n */\n path: string\n}\n\n/**\n * Operation for a non-HTTP transport. HTTP-only fields are forbidden.\n */\nexport type GenericOperationNode = OperationNodeBase & {\n /**\n * Transport the operation belongs to.\n */\n protocol?: Exclude<OperationProtocol, 'http'>\n method?: never\n path?: never\n}\n\n/**\n * AST node representing one API operation.\n *\n * Discriminated on `protocol`: an {@link HttpOperationNode} (`protocol: 'http'`) guarantees\n * `method` and `path`, while a {@link GenericOperationNode} omits them. Narrow with\n * `isHttpOperationNode(node)` or `node.protocol === 'http'` before reading `method`/`path`.\n */\nexport type OperationNode = HttpOperationNode | GenericOperationNode\n\ntype OperationInput = {\n operationId: string\n method?: HttpOperationNode['method']\n path?: HttpOperationNode['path']\n requestBody?: Omit<RequestBodyNode, 'kind'>\n [key: string]: unknown\n}\n\n/**\n * Definition for the {@link OperationNode}. HTTP operations (those carrying both\n * `method` and `path`) are tagged with `protocol: 'http'`, and the request body is\n * normalized into a `RequestBodyNode`.\n */\nexport const operationDef = defineNode<OperationNode, OperationInput>({\n kind: 'Operation',\n build: (props) => {\n const { requestBody, ...rest } = props\n const isHttp = rest.method !== undefined && rest.path !== undefined\n\n return {\n tags: [],\n parameters: [],\n responses: [],\n ...rest,\n ...(isHttp ? { protocol: 'http' as const } : {}),\n requestBody: requestBody ? createRequestBody(requestBody) : undefined,\n }\n },\n children: ['parameters', 'requestBody', 'responses'],\n visitorKey: 'operation',\n})\n\n/**\n * Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.\n *\n * @example\n * ```ts\n * const operation = createOperation({ operationId: 'getPetById', method: 'GET', path: '/pet/{petId}' })\n * // tags, parameters, and responses are []\n * ```\n */\nexport function createOperation(\n props: Pick<HttpOperationNode, 'operationId' | 'method' | 'path'> &\n Partial<Omit<HttpOperationNode, 'kind' | 'operationId' | 'method' | 'path' | 'requestBody'>> & {\n requestBody?: Omit<RequestBodyNode, 'kind'>\n },\n): HttpOperationNode\nexport function createOperation(\n props: Pick<GenericOperationNode, 'operationId'> &\n Partial<Omit<GenericOperationNode, 'kind' | 'operationId' | 'requestBody'>> & {\n requestBody?: Omit<RequestBodyNode, 'kind'>\n },\n): GenericOperationNode\nexport function createOperation(props: OperationInput): OperationNode {\n return operationDef.create(props)\n}\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { FileNode } from './file.ts'\n\n/**\n * Output AST node that groups all generated file output for one API document.\n *\n * Produced by generators and consumed by the build pipeline to write files.\n *\n * @example\n * ```ts\n * const output: OutputNode = {\n * kind: 'Output',\n * files: [],\n * }\n * ```\n */\nexport type OutputNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Output'\n /**\n * Generated file nodes.\n */\n files: Array<FileNode>\n}\n\n/**\n * Definition for the {@link OutputNode}.\n */\nexport const outputDef = defineNode<OutputNode, Partial<Omit<OutputNode, 'kind'>>>({\n kind: 'Output',\n defaults: { files: [] },\n visitorKey: 'output',\n})\n\n/**\n * Creates an `OutputNode` with a stable default for `files`.\n *\n * @example\n * ```ts\n * const output = createOutput()\n * // { kind: 'Output', files: [] }\n * ```\n */\nexport function createOutput(overrides: Partial<Omit<OutputNode, 'kind'>> = {}): OutputNode {\n return outputDef.create(overrides)\n}\n","import type { SchemaNode } from './nodes/schema.ts'\n\n/**\n * Generic JSON Schema optionality: a non-required field is optional, and a\n * non-required nullable field is nullish.\n */\nexport function optionality(schema: SchemaNode, required: boolean): SchemaNode {\n const nullable = schema.nullable ?? false\n\n return {\n ...schema,\n optional: !required && !nullable ? true : undefined,\n nullish: !required && nullable ? true : undefined,\n }\n}\n","import { defineNode } from '../defineNode.ts'\nimport { optionality } from '../optionality.ts'\nimport type { BaseNode } from './base.ts'\nimport type { SchemaNode } from './schema.ts'\n\nexport type ParameterLocation = 'path' | 'query' | 'header' | 'cookie'\n\n/**\n * Parameter serialization style, controlling how a parameter value is rendered into the request.\n */\nexport type ParameterStyle = 'matrix' | 'label' | 'form' | 'simple' | 'spaceDelimited' | 'pipeDelimited' | 'deepObject'\n\n/**\n * AST node representing one operation parameter.\n *\n * @example\n * ```ts\n * const param: ParameterNode = {\n * kind: 'Parameter',\n * name: 'petId',\n * in: 'path',\n * schema: createSchema({ type: 'string' }),\n * required: true,\n * }\n * ```\n */\nexport type ParameterNode = BaseNode & {\n kind: 'Parameter'\n /**\n * Parameter name.\n */\n name: string\n /**\n * Parameter location (`path`, `query`, `header`, or `cookie`).\n */\n in: ParameterLocation\n /**\n * Parameter schema.\n */\n schema: SchemaNode\n /**\n * Whether the parameter is required.\n */\n required: boolean\n /**\n * Serialization style. Absent when the source omits it, leaving consumers to apply the\n * per-location default.\n */\n style?: ParameterStyle\n /**\n * Whether array and object values expand into separate values. Absent when the source omits it,\n * leaving consumers to apply the default for the style.\n */\n explode?: boolean\n}\n\ntype UserParameterNode = Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>\n\n/**\n * Definition for the {@link ParameterNode}. `required` defaults to `false`, and the schema's\n * `optional`/`nullish` flags are derived from it through {@link optionality}.\n */\nexport const parameterDef = defineNode<ParameterNode, UserParameterNode>({\n kind: 'Parameter',\n build: (props) => {\n const required = props.required ?? false\n return { ...props, required, schema: optionality(props.schema, required) }\n },\n children: ['schema'],\n visitorKey: 'parameter',\n})\n\n/**\n * Creates a `ParameterNode`.\n *\n * @example\n * ```ts\n * const param = createParameter({\n * name: 'petId',\n * in: 'path',\n * required: true,\n * schema: createSchema({ type: 'string' }),\n * })\n * ```\n */\nexport const createParameter = parameterDef.create\n","import { defineNode } from '../defineNode.ts'\nimport { optionality } from '../optionality.ts'\nimport type { BaseNode } from './base.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * AST node representing one named object property.\n *\n * @example\n * ```ts\n * const property: PropertyNode = {\n * kind: 'Property',\n * name: 'id',\n * schema: createSchema({ type: 'integer' }),\n * required: true,\n * }\n * ```\n */\nexport type PropertyNode = BaseNode & {\n kind: 'Property'\n /**\n * Property key.\n */\n name: string\n /**\n * Property schema.\n */\n schema: SchemaNode\n /**\n * Whether the property is required.\n */\n required: boolean\n}\n\n/**\n * Loosely-typed property accepted by `createProperty`, with `required` optional.\n */\nexport type UserPropertyNode = Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>\n\n/**\n * Definition for the {@link PropertyNode}. `required` defaults to `false`, and the schema's\n * `optional`/`nullish` flags are derived from it through {@link optionality}.\n */\nexport const propertyDef = defineNode<PropertyNode, UserPropertyNode>({\n kind: 'Property',\n build: (props) => {\n const required = props.required ?? false\n return { ...props, required, schema: optionality(props.schema, required) }\n },\n children: ['schema'],\n visitorKey: 'property',\n})\n\n/**\n * Creates a `PropertyNode`.\n *\n * @example\n * ```ts\n * const property = createProperty({\n * name: 'status',\n * required: true,\n * schema: createSchema({ type: 'string', nullable: true }),\n * })\n * // required=true, no optional/nullish\n * ```\n */\nexport const createProperty = propertyDef.create\n","import { defineNode } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport { type ContentNode, createContent } from './content.ts'\nimport type { SchemaNode } from './schema.ts'\n\n/**\n * All supported HTTP status code literals as strings, as used in API specs\n * (for example, `\"200\"` and `\"404\"`).\n */\ntype HttpStatusCode =\n // 1xx Informational\n | '100'\n | '101'\n | '102'\n | '103'\n // 2xx Success\n | '200'\n | '201'\n | '202'\n | '203'\n | '204'\n | '205'\n | '206'\n | '207'\n | '208'\n | '226'\n // 3xx Redirection\n | '300'\n | '301'\n | '302'\n | '303'\n | '304'\n | '305'\n | '307'\n | '308'\n // 4xx Client Error\n | '400'\n | '401'\n | '402'\n | '403'\n | '404'\n | '405'\n | '406'\n | '407'\n | '408'\n | '409'\n | '410'\n | '411'\n | '412'\n | '413'\n | '414'\n | '415'\n | '416'\n | '417'\n | '418'\n | '421'\n | '422'\n | '423'\n | '424'\n | '425'\n | '426'\n | '428'\n | '429'\n | '431'\n | '451'\n // 5xx Server Error\n | '500'\n | '501'\n | '502'\n | '503'\n | '504'\n | '505'\n | '506'\n | '507'\n | '508'\n | '510'\n | '511'\n\n/**\n * Response status code literal used by operations.\n *\n * Includes specific HTTP status code strings and `\"default\"` for catch-all responses.\n *\n * @example\n * ```ts\n * const status: StatusCode = '200'\n * const fallback: StatusCode = 'default'\n * ```\n */\nexport type StatusCode = HttpStatusCode | 'default'\n\n/**\n * AST node representing one operation response variant.\n *\n * Mirrors {@link OperationNode.requestBody}: the response body schemas live exclusively inside\n * the `content` array (one entry per content type), so the same schema is never duplicated at the\n * node root and inside `content`.\n *\n * @example\n * ```ts\n * const response: ResponseNode = {\n * kind: 'Response',\n * statusCode: '200',\n * content: [{ kind: 'Content', contentType: 'application/json', schema: createSchema({ type: 'string' }) }],\n * }\n * ```\n */\nexport type ResponseNode = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Response'\n /**\n * HTTP status code or `'default'` for a fallback response.\n */\n statusCode: StatusCode\n /**\n * Optional response description.\n */\n description?: string\n /**\n * All available content type entries for this response.\n *\n * When the adapter `contentType` option is set, this array contains exactly one entry for that\n * content type. Otherwise it contains one entry per content type declared in the spec, so that\n * plugins can generate a union of response types (e.g. `application/json` and `application/xml`).\n * Body-less responses keep a single entry whose `schema` is the empty/`void` placeholder.\n *\n * @example\n * ```ts\n * // spec response declares both application/json and application/xml\n * response.content[0].contentType // 'application/json'\n * response.content[1].contentType // 'application/xml'\n * ```\n */\n content?: Array<ContentNode>\n}\n\ntype ResponseInput = Pick<ResponseNode, 'statusCode'> &\n Partial<Omit<ResponseNode, 'kind' | 'statusCode' | 'content'>> & {\n content?: Array<ContentNode>\n schema?: SchemaNode\n mediaType?: string | null\n keysToOmit?: Array<string> | null\n }\n\n/**\n * Definition for the {@link ResponseNode}. A single legacy `schema` (with optional\n * `mediaType`/`keysToOmit`) is normalized into one `content` entry.\n */\nexport const responseDef = defineNode<ResponseNode, ResponseInput>({\n kind: 'Response',\n build: (props) => {\n const { schema, mediaType, keysToOmit, content, ...rest } = props\n const entries = content ?? (schema ? [createContent({ contentType: mediaType ?? 'application/json', schema, keysToOmit: keysToOmit ?? null })] : undefined)\n return { ...rest, content: entries }\n },\n children: ['content'],\n visitorKey: 'response',\n})\n\n/**\n * Creates a `ResponseNode`.\n *\n * @example\n * ```ts\n * const response = createResponse({\n * statusCode: '200',\n * content: [createContent({ contentType: 'application/json', schema: createSchema({ type: 'object', properties: [] }) })],\n * })\n * ```\n */\nexport const createResponse = responseDef.create\n","import type { InferSchemaNode } from '../infer.ts'\nimport { defineNode, type DistributiveOmit } from '../defineNode.ts'\nimport type { BaseNode } from './base.ts'\nimport type { PropertyNode } from './property.ts'\n\nexport type PrimitiveSchemaType =\n /**\n * Text value.\n */\n | 'string'\n /**\n * Floating-point number.\n */\n | 'number'\n /**\n * Integer number.\n */\n | 'integer'\n /**\n * Big integer number.\n */\n | 'bigint'\n /**\n * Boolean value.\n */\n | 'boolean'\n /**\n * Null value.\n */\n | 'null'\n /**\n * Any value.\n */\n | 'any'\n /**\n * Unknown value.\n */\n | 'unknown'\n /**\n * No value (`void`).\n */\n | 'void'\n /**\n * Never value.\n */\n | 'never'\n /**\n * Object value.\n */\n | 'object'\n /**\n * Array value.\n */\n | 'array'\n /**\n * Date value.\n */\n | 'date'\n\n/**\n * Composite schema types.\n */\ntype ComplexSchemaType = 'tuple' | 'union' | 'intersection' | 'enum'\n\n/**\n * Schema types that need special handling in generators.\n */\ntype SpecialSchemaType = 'ref' | 'datetime' | 'time' | 'uuid' | 'email' | 'url' | 'ipv4' | 'ipv6' | 'blob'\n\n/**\n * All schema type strings.\n */\nexport type SchemaType = PrimitiveSchemaType | ComplexSchemaType | SpecialSchemaType\n\n/**\n * Scalar schema types without extra object/array/ref structure.\n */\nexport type ScalarSchemaType = Exclude<\n SchemaType,\n | 'object'\n | 'array'\n | 'tuple'\n | 'union'\n | 'intersection'\n | 'enum'\n | 'ref'\n | 'datetime'\n | 'date'\n | 'time'\n | 'string'\n | 'number'\n | 'integer'\n | 'bigint'\n | 'url'\n | 'uuid'\n | 'email'\n | 'ipv4'\n | 'ipv6'\n>\n\n/**\n * Fields shared by all schema nodes.\n */\ntype SchemaNodeBase = BaseNode & {\n /**\n * Node kind.\n */\n kind: 'Schema'\n /**\n * Schema name for named definitions (for example, `\"Pet\"`).\n * Inline schemas omit this field.\n * `null` means Kubb has processed this and determined there is no applicable name.\n * `undefined` means the name has not been set yet.\n */\n name?: string | null\n /**\n * Short schema title.\n */\n title?: string\n /**\n * Schema description text.\n */\n description?: string\n /**\n * Whether `null` is allowed.\n */\n nullable?: boolean\n /**\n * Whether the field is optional.\n */\n optional?: boolean\n /**\n * Both optional and nullable (`optional` + `nullable`).\n */\n nullish?: boolean\n /**\n * Whether the schema is deprecated.\n */\n deprecated?: boolean\n /**\n * Whether the schema is read-only.\n */\n readOnly?: boolean\n /**\n * Whether the schema is write-only.\n */\n writeOnly?: boolean\n /**\n * Default value.\n */\n default?: unknown\n /**\n * Example values from an `examples` array.\n */\n examples?: Array<unknown>\n /**\n * Base primitive type.\n * For example, this is `'string'` for a `uuid` schema.\n */\n primitive?: PrimitiveSchemaType\n /**\n * Schema `format` value.\n */\n format?: string\n}\n\n/**\n * Object schema with ordered properties.\n *\n * @example\n * ```ts\n * const objectSchema: ObjectSchemaNode = {\n * kind: 'Schema',\n * type: 'object',\n * properties: [],\n * }\n * ```\n */\nexport type ObjectSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'object'\n /**\n * Primitive type, always `'object'` for object schemas.\n */\n primitive: 'object'\n /**\n * Ordered object properties.\n */\n properties: Array<PropertyNode>\n /**\n * Additional object properties behavior:\n * - `true`: allow any value\n * - `false`: reject unknown properties\n * - `SchemaNode`: allow values that match that schema\n * - `undefined`: no additional properties constraint (open object)\n */\n additionalProperties?: SchemaNode | boolean\n /**\n * Pattern-based property schemas.\n */\n patternProperties?: Record<string, SchemaNode>\n /**\n * Minimum number of properties allowed.\n */\n minProperties?: number\n /**\n * Maximum number of properties allowed.\n */\n maxProperties?: number\n}\n\n/**\n * Array-like schema (`array` or `tuple`).\n *\n * @example\n * ```ts\n * const arraySchema: ArraySchemaNode = {\n * kind: 'Schema',\n * type: 'array',\n * items: [],\n * }\n * ```\n */\nexport type ArraySchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator (`array` or `tuple`).\n */\n type: 'array' | 'tuple'\n /**\n * Item schemas.\n */\n items?: Array<SchemaNode>\n /**\n * Tuple rest-item schema for elements beyond positional `items`.\n */\n rest?: SchemaNode\n /**\n * Minimum item count (or tuple length).\n */\n min?: number\n /**\n * Maximum item count (or tuple length).\n */\n max?: number\n /**\n * Whether all items must be unique.\n */\n unique?: boolean\n}\n\n/**\n * Shared shape for union and intersection schemas.\n */\ntype CompositeSchemaNodeBase = SchemaNodeBase & {\n /**\n * Member schemas.\n */\n members?: Array<SchemaNode>\n}\n\n/**\n * Union schema, often from `oneOf` or `anyOf`.\n *\n * @example\n * ```ts\n * const unionSchema: UnionSchemaNode = {\n * kind: 'Schema',\n * type: 'union',\n * members: [],\n * }\n * ```\n */\nexport type UnionSchemaNode = CompositeSchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'union'\n /**\n * Discriminator property name for a polymorphic union.\n */\n discriminatorPropertyName?: string\n /**\n * How many union members must be valid.\n * - `'one'`: exactly one member, from `oneOf`\n * - `'any'`: any number of members, from `anyOf`\n */\n strategy?: 'one' | 'any'\n}\n\n/**\n * Intersection schema, often from `allOf`.\n *\n * @example\n * ```ts\n * const intersectionSchema: IntersectionSchemaNode = {\n * kind: 'Schema',\n * type: 'intersection',\n * members: [],\n * }\n * ```\n */\nexport type IntersectionSchemaNode = CompositeSchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'intersection'\n}\n\n/**\n * One named enum item.\n */\ntype EnumValueNode = {\n /**\n * Enum item name.\n */\n name: string\n /**\n * Enum item value.\n */\n value: string | number | boolean\n /**\n * Primitive type of the enum value.\n */\n primitive: Extract<PrimitiveSchemaType, 'string' | 'number' | 'boolean'>\n /**\n * Label for the enum item, taken from the `x-enumDescriptions` or\n * `x-enum-descriptions` vendor extension. `@kubb/plugin-ts` renders it as\n * JSDoc on the matching enum member.\n */\n description?: string\n}\n\n/**\n * Enum schema node.\n *\n * @example\n * ```ts\n * const enumSchema: EnumSchemaNode = {\n * kind: 'Schema',\n * type: 'enum',\n * enumValues: ['a', 'b'],\n * }\n * ```\n */\nexport type EnumSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'enum'\n /**\n * Enum values in simple form.\n */\n enumValues?: Array<string | number | boolean | null>\n /**\n * Enum values in named form.\n * If present, this is used instead of `enumValues`.\n */\n namedEnumValues?: Array<EnumValueNode>\n}\n\n/**\n * Reference schema that points to another schema definition.\n *\n * @example\n * ```ts\n * const refSchema: RefSchemaNode = {\n * kind: 'Schema',\n * type: 'ref',\n * ref: '#/components/schemas/Pet',\n * }\n * ```\n */\nexport type RefSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'ref'\n /**\n * Referenced schema name.\n * `null` means Kubb has processed this and determined there is no applicable name.\n */\n name?: string | null\n /**\n * Original `$ref` path, for example, `#/components/schemas/Order`.\n * Used to resolve names later.\n */\n ref?: string\n /**\n * Pattern copied from a sibling `pattern` field.\n */\n pattern?: string\n /**\n * The fully-parsed schema this ref resolves to, so its structure (`primitive`, `properties`)\n * can be read without following the reference. Populated during parsing when the\n * definition resolves, `null` when it can't or the ref is circular, and `undefined` when\n * resolution has not been attempted.\n */\n schema?: SchemaNode | null\n}\n\n/**\n * Datetime schema.\n *\n * @example\n * ```ts\n * const datetimeSchema: DatetimeSchemaNode = { kind: 'Schema', type: 'datetime' }\n * ```\n */\nexport type DatetimeSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'datetime'\n /**\n * Whether the datetime includes a timezone offset (`dateType: 'stringOffset'`).\n */\n offset?: boolean\n /**\n * Whether the datetime is local (no timezone, `dateType: 'stringLocal'`).\n */\n local?: boolean\n}\n\n/**\n * Shared base for `date` and `time` schemas.\n */\ntype TemporalSchemaNodeBase<T extends 'date' | 'time'> = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: T\n /**\n * Output representation in generated code.\n */\n representation: 'date' | 'string'\n}\n\n/**\n * Date schema node.\n *\n * @example\n * ```ts\n * const dateSchema: DateSchemaNode = { kind: 'Schema', type: 'date', representation: 'string' }\n * ```\n */\nexport type DateSchemaNode = TemporalSchemaNodeBase<'date'>\n\n/**\n * Time schema node.\n *\n * @example\n * ```ts\n * const timeSchema: TimeSchemaNode = { kind: 'Schema', type: 'time', representation: 'string' }\n * ```\n */\nexport type TimeSchemaNode = TemporalSchemaNodeBase<'time'>\n\n/**\n * String schema node.\n *\n * @example\n * ```ts\n * const stringSchema: StringSchemaNode = { kind: 'Schema', type: 'string' }\n * ```\n */\nexport type StringSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'string'\n /**\n * Minimum string length.\n */\n min?: number\n /**\n * Maximum string length.\n */\n max?: number\n /**\n * Regex pattern.\n */\n pattern?: string\n}\n\n/**\n * Numeric schema (`number`, `integer`, or `bigint`).\n *\n * @example\n * ```ts\n * const numberSchema: NumberSchemaNode = { kind: 'Schema', type: 'number' }\n * ```\n */\nexport type NumberSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'number' | 'integer' | 'bigint'\n /**\n * Minimum value.\n */\n min?: number\n /**\n * Maximum value.\n */\n max?: number\n /**\n * Exclusive minimum value.\n */\n exclusiveMinimum?: number\n /**\n * Exclusive maximum value.\n */\n exclusiveMaximum?: number\n /**\n * The value must be a multiple of this number.\n */\n multipleOf?: number\n}\n\n/**\n * Scalar schema with no extra constraints.\n *\n * @example\n * ```ts\n * const anySchema: ScalarSchemaNode = { kind: 'Schema', type: 'any' }\n * ```\n */\nexport type ScalarSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: ScalarSchemaType\n}\n\n/**\n * URL schema node.\n * Can include a path template for template literal types.\n *\n * @example\n * ```ts\n * const urlSchema: UrlSchemaNode = { kind: 'Schema', type: 'url', path: '/pets/{petId}' }\n * ```\n */\nexport type UrlSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'url'\n /**\n * Path template, for example, `'/pets/{petId}'`.\n */\n path?: string\n /**\n * Minimum string length.\n */\n min?: number\n /**\n * Maximum string length.\n */\n max?: number\n}\n\n/**\n * Format-string schema for string-based formats that support length constraints.\n *\n * @example\n * ```ts\n * const uuidSchema: FormatStringSchemaNode = { kind: 'Schema', type: 'uuid', min: 36, max: 36 }\n * ```\n */\ntype FormatStringSchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'uuid' | 'email'\n /**\n * Minimum string length.\n */\n min?: number\n /**\n * Maximum string length.\n */\n max?: number\n}\n\n/**\n * IPv4 address schema node.\n *\n * @example\n * ```ts\n * const ipv4Schema: Ipv4SchemaNode = { kind: 'Schema', type: 'ipv4' }\n * ```\n */\ntype Ipv4SchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'ipv4'\n}\n\n/**\n * IPv6 address schema node.\n *\n * @example\n * ```ts\n * const ipv6Schema: Ipv6SchemaNode = { kind: 'Schema', type: 'ipv6' }\n * ```\n */\ntype Ipv6SchemaNode = SchemaNodeBase & {\n /**\n * Schema type discriminator.\n */\n type: 'ipv6'\n}\n\n/**\n * Mapping from schema type literals to concrete schema node types.\n * Used by `narrowSchema`.\n */\nexport type SchemaNodeByType = {\n object: ObjectSchemaNode\n array: ArraySchemaNode\n tuple: ArraySchemaNode\n union: UnionSchemaNode\n intersection: IntersectionSchemaNode\n enum: EnumSchemaNode\n ref: RefSchemaNode\n datetime: DatetimeSchemaNode\n date: DateSchemaNode\n time: TimeSchemaNode\n string: StringSchemaNode\n number: NumberSchemaNode\n integer: NumberSchemaNode\n bigint: NumberSchemaNode\n boolean: ScalarSchemaNode\n null: ScalarSchemaNode\n any: ScalarSchemaNode\n unknown: ScalarSchemaNode\n void: ScalarSchemaNode\n never: ScalarSchemaNode\n uuid: FormatStringSchemaNode\n email: FormatStringSchemaNode\n url: UrlSchemaNode\n ipv4: Ipv4SchemaNode\n ipv6: Ipv6SchemaNode\n blob: ScalarSchemaNode\n}\n\n/**\n * Union of all schema node types.\n */\nexport type SchemaNode =\n | ObjectSchemaNode\n | ArraySchemaNode\n | UnionSchemaNode\n | IntersectionSchemaNode\n | EnumSchemaNode\n | RefSchemaNode\n | DatetimeSchemaNode\n | DateSchemaNode\n | TimeSchemaNode\n | StringSchemaNode\n | NumberSchemaNode\n | UrlSchemaNode\n | FormatStringSchemaNode\n | Ipv4SchemaNode\n | Ipv6SchemaNode\n | ScalarSchemaNode\n\ntype CreateSchemaObjectInput = Omit<ObjectSchemaNode, 'kind' | 'properties' | 'primitive'> & { properties?: Array<PropertyNode>; primitive?: 'object' }\ntype CreateSchemaInput = CreateSchemaObjectInput | DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>\ntype CreateSchemaOutput<T extends CreateSchemaInput> = InferSchemaNode<T> & {\n kind: 'Schema'\n}\n\n/**\n * Maps schema `type` to its underlying `primitive`.\n * Primitive types map to themselves and special string formats map to `'string'`.\n * Any type not listed here (such as `ref`, `enum`, `union`, `intersection`, `tuple`, `ipv4`, `ipv6`, `blob`) has no `primitive`.\n */\nconst TYPE_TO_PRIMITIVE: Partial<Record<SchemaNode['type'], PrimitiveSchemaType>> = {\n string: 'string',\n number: 'number',\n integer: 'integer',\n bigint: 'bigint',\n boolean: 'boolean',\n null: 'null',\n any: 'any',\n unknown: 'unknown',\n void: 'void',\n never: 'never',\n object: 'object',\n array: 'array',\n date: 'date',\n uuid: 'string',\n email: 'string',\n url: 'string',\n datetime: 'string',\n time: 'string',\n}\n\n/**\n * Definition for the {@link SchemaNode}. Object schemas default `properties` to an\n * empty array, and `primitive` is inferred from `type` when not explicitly provided.\n */\nexport const schemaDef = defineNode<SchemaNode, CreateSchemaInput>({\n kind: 'Schema',\n build: (props) => {\n if (props.type === 'object') {\n return { properties: [], primitive: 'object' as const, ...props }\n }\n\n return { primitive: TYPE_TO_PRIMITIVE[props.type as keyof typeof TYPE_TO_PRIMITIVE], ...props }\n },\n children: ['properties', 'items', 'members', 'additionalProperties'],\n visitorKey: 'schema',\n})\n\n/**\n * Creates a `SchemaNode`, narrowed to the variant of `props.type`.\n *\n * @example\n * ```ts\n * const scalar = createSchema({ type: 'string' })\n * // { kind: 'Schema', type: 'string', primitive: 'string' }\n * ```\n *\n * @example\n * ```ts\n * const object = createSchema({ type: 'object' })\n * // { kind: 'Schema', type: 'object', primitive: 'object', properties: [] }\n * ```\n */\nexport function createSchema<T extends CreateSchemaInput>(props: T): CreateSchemaOutput<T>\nexport function createSchema(props: CreateSchemaInput): SchemaNode\nexport function createSchema(props: CreateSchemaInput): SchemaNode {\n return schemaDef.create(props)\n}\n","import type { NodeDef } from './defineNode.ts'\nimport { arrowFunctionDef, breakDef, constDef, functionDef, jsxDef, textDef, typeDef } from './nodes/code.ts'\nimport { contentDef } from './nodes/content.ts'\nimport { exportDef, fileDef, importDef, sourceDef } from './nodes/file.ts'\nimport { inputDef } from './nodes/input.ts'\nimport { operationDef } from './nodes/operation.ts'\nimport { outputDef } from './nodes/output.ts'\nimport { parameterDef } from './nodes/parameter.ts'\nimport { propertyDef } from './nodes/property.ts'\nimport { requestBodyDef } from './nodes/requestBody.ts'\nimport { responseDef } from './nodes/response.ts'\nimport { schemaDef } from './nodes/schema.ts'\n\n// Surface every def from one place so the package barrel re-exports them with `export * from './registry.ts'`.\n// Adding a node means adding its `defineNode` to a `nodes/*.ts` file and listing it in `nodeDefs` below, nothing else.\nexport {\n arrowFunctionDef,\n breakDef,\n constDef,\n contentDef,\n exportDef,\n fileDef,\n functionDef,\n importDef,\n inputDef,\n jsxDef,\n operationDef,\n outputDef,\n parameterDef,\n propertyDef,\n requestBodyDef,\n responseDef,\n schemaDef,\n sourceDef,\n textDef,\n typeDef,\n}\n\n/**\n * Every node definition. Adding a node means adding its `defineNode` to one\n * `nodes/*.ts` file and listing it here. The visitor tables in `visitor.ts` derive from it.\n */\nexport const nodeDefs = [\n inputDef,\n outputDef,\n operationDef,\n requestBodyDef,\n contentDef,\n responseDef,\n schemaDef,\n propertyDef,\n parameterDef,\n constDef,\n typeDef,\n functionDef,\n arrowFunctionDef,\n textDef,\n breakDef,\n jsxDef,\n importDef,\n exportDef,\n sourceDef,\n fileDef,\n] satisfies ReadonlyArray<NodeDef>\n","import type { VisitorDepth } from './constants.ts'\nimport { visitorDepths } from './constants.ts'\nimport type { NodeDef } from './defineNode.ts'\nimport type {\n ContentNode,\n InputNode,\n Node,\n NodeKind,\n OperationNode,\n OutputNode,\n ParameterNode,\n PropertyNode,\n RequestBodyNode,\n ResponseNode,\n SchemaNode,\n} from './nodes/index.ts'\nimport { nodeDefs } from './registry.ts'\n\n/**\n * Child node fields per node kind, in traversal order (Babel's `VISITOR_KEYS`).\n * Derived from each definition's `children`.\n */\nconst VISITOR_KEYS = Object.fromEntries(nodeDefs.flatMap((def) => (def.children ? [[def.kind, def.children] as const] : []))) as Partial<\n Record<NodeKind, ReadonlyArray<string>>\n>\n\n/**\n * Maps a node kind to the matching visitor callback name. Derived from each\n * definition's `visitorKey`.\n */\nconst VISITOR_KEY_BY_KIND = Object.fromEntries(nodeDefs.flatMap((def) => (def.visitorKey ? [[def.kind, def.visitorKey] as const] : []))) as Partial<\n Record<NodeKind, NonNullable<NodeDef['visitorKey']>>\n>\n\n/**\n * Ordered mapping of `[NodeType, ParentType]` pairs.\n *\n * `ParentOf` uses this map to find parent types.\n */\ntype ParentNodeMap = [\n [InputNode, undefined],\n [OutputNode, undefined],\n [OperationNode, InputNode],\n [RequestBodyNode, OperationNode],\n [ContentNode, RequestBodyNode | ResponseNode],\n [SchemaNode, InputNode | ContentNode | SchemaNode | PropertyNode | ParameterNode],\n [PropertyNode, SchemaNode],\n [ParameterNode, OperationNode],\n [ResponseNode, OperationNode],\n]\n\n/**\n * Resolves the parent node type for a given AST node type.\n *\n * Visitor context relies on this so `ctx.parent` is typed for each callback.\n *\n * @example\n * ```ts\n * type InputParent = ParentOf<InputNode>\n * // undefined\n * ```\n *\n * @example\n * ```ts\n * type PropertyParent = ParentOf<PropertyNode>\n * // SchemaNode\n * ```\n *\n * @example\n * ```ts\n * type SchemaParent = ParentOf<SchemaNode>\n * // InputNode | ContentNode | SchemaNode | PropertyNode | ParameterNode\n * ```\n */\nexport type ParentOf<T extends Node, TEntries extends ReadonlyArray<[Node, unknown]> = ParentNodeMap> = TEntries extends [\n infer TEntry extends [Node, unknown],\n ...infer TRest extends ReadonlyArray<[Node, unknown]>,\n]\n ? T extends TEntry[0]\n ? TEntry[1]\n : ParentOf<T, TRest>\n : Node\n\n/**\n * Traversal context passed as the second argument to every visitor callback.\n * `parent` is typed from the current node type.\n *\n * @example\n * ```ts\n * const visitor: Visitor = {\n * schema(node, { parent }) {\n * // parent type is narrowed by node kind\n * },\n * }\n * ```\n */\nexport type VisitorContext<T extends Node = Node> = {\n /**\n * Parent node of the currently visited node.\n * For `InputNode`, this is `undefined`.\n */\n parent?: ParentOf<T>\n}\n\n/**\n * Synchronous visitor consumed by `transform`. Each optional callback runs\n * for the matching node type. Return a new node to replace it, or `undefined`\n * to leave it untouched.\n *\n * Plugins typically expose `transformer` so users can supply a `Visitor` that\n * rewrites the AST before printing.\n *\n * @example Prefix every operationId\n * ```ts\n * const visitor: Visitor = {\n * operation(node) {\n * return { ...node, operationId: `api_${node.operationId}` }\n * },\n * }\n * ```\n *\n * @example Strip schema descriptions\n * ```ts\n * const visitor: Visitor = {\n * schema(node) {\n * return { ...node, description: undefined }\n * },\n * }\n * ```\n */\nexport type Visitor = {\n input?(node: InputNode, context: VisitorContext<InputNode>): undefined | null | InputNode\n output?(node: OutputNode, context: VisitorContext<OutputNode>): undefined | null | OutputNode\n operation?(node: OperationNode, context: VisitorContext<OperationNode>): undefined | null | OperationNode\n schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): undefined | null | SchemaNode\n property?(node: PropertyNode, context: VisitorContext<PropertyNode>): undefined | null | PropertyNode\n parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): undefined | null | ParameterNode\n response?(node: ResponseNode, context: VisitorContext<ResponseNode>): undefined | null | ResponseNode\n}\n\n/**\n * Visitor used by `collect`.\n *\n * @example\n * ```ts\n * const visitor: CollectVisitor<string> = {\n * operation(node) {\n * return node.operationId\n * },\n * }\n * ```\n */\ntype CollectVisitor<T> = {\n input?(node: InputNode, context: VisitorContext<InputNode>): T | null | undefined\n output?(node: OutputNode, context: VisitorContext<OutputNode>): T | null | undefined\n operation?(node: OperationNode, context: VisitorContext<OperationNode>): T | null | undefined\n schema?(node: SchemaNode, context: VisitorContext<SchemaNode>): T | null | undefined\n property?(node: PropertyNode, context: VisitorContext<PropertyNode>): T | null | undefined\n parameter?(node: ParameterNode, context: VisitorContext<ParameterNode>): T | null | undefined\n response?(node: ResponseNode, context: VisitorContext<ResponseNode>): T | null | undefined\n}\n\n/**\n * Options for `transform`.\n *\n * @example\n * ```ts\n * const options: TransformOptions = { depth: 'deep', schema: (node) => node }\n * ```\n *\n * @example\n * ```ts\n * // Only transform the current node, not nested children\n * const options: TransformOptions = { depth: 'shallow', schema: (node) => node }\n * ```\n */\nexport type TransformOptions = Visitor & {\n /**\n * Traversal depth.\n * @default 'deep'\n */\n depth?: VisitorDepth\n /**\n * Internal parent override used during recursion.\n */\n parent?: Node\n}\n\n/**\n * Options for `collect`.\n *\n * @example\n * ```ts\n * const options: CollectOptions<string> = { depth: 'shallow', schema: () => undefined }\n * ```\n */\nexport type CollectOptions<T> = CollectVisitor<T> & {\n /**\n * Traversal depth.\n * @default 'deep'\n */\n depth?: VisitorDepth\n /**\n * Internal parent override used during recursion.\n */\n parent?: Node\n}\n\nconst visitorKeysByKind = VISITOR_KEYS as Record<string, ReadonlyArray<string> | undefined>\n\n/**\n * Returns `true` when `value` is an AST node (an object carrying a `kind`).\n */\nfunction isNode(value: unknown): value is Node {\n return typeof value === 'object' && value !== null && typeof (value as { kind?: unknown }).kind === 'string'\n}\n\n/**\n * Returns the immediate traversable children of `node` based on {@link VISITOR_KEYS}.\n *\n * `Schema` children are only included when `recurse` is `true`. Shallow mode skips them.\n *\n * @example\n * ```ts\n * const children = getChildren(operationNode, true)\n * // returns parameters, the request body, and responses\n * ```\n */\nfunction* getChildren(node: Node, recurse: boolean): Generator<Node, void, undefined> {\n if (node.kind === 'Schema' && !recurse) return\n\n const keys = visitorKeysByKind[node.kind]\n if (!keys) return\n\n const record = node as unknown as Record<string, unknown>\n for (const key of keys) {\n const value = record[key]\n if (Array.isArray(value)) {\n for (const item of value) if (isNode(item)) yield item\n } else if (isNode(value)) {\n yield value\n }\n }\n}\n\n/**\n * Runs the visitor callback that matches `node.kind` with the traversal\n * context. The result is a replacement node, a collected value, or `undefined`\n * when no callback is registered for the kind.\n *\n * Shared by `transform` and `collectLazy` so node-kind dispatch lives in one place.\n * `TResult` is the caller's expected return: the same node type for `transform`,\n * the collected value type for `collectLazy`.\n */\nfunction applyVisitor<TResult>(node: Node, visitor: Visitor | CollectVisitor<unknown>, parent: Node | undefined): TResult | null | undefined {\n const key = VISITOR_KEY_BY_KIND[node.kind]\n if (!key) return undefined\n\n const fn = visitor[key] as ((node: Node, context: VisitorContext) => TResult | null | undefined) | undefined\n\n return fn?.(node, { parent })\n}\n\n/**\n * Synchronous depth-first transform. Each visitor callback can return a\n * replacement node. Returning `undefined` keeps the original.\n *\n * The original tree is never mutated, a new tree is returned. Pass\n * `depth: 'shallow'` to skip recursion into children.\n *\n * @example Prefix every operationId\n * ```ts\n * const next = transform(root, {\n * operation(node) {\n * return { ...node, operationId: `prefixed_${node.operationId}` }\n * },\n * })\n * ```\n *\n * @example Replace only the root node\n * ```ts\n * const next = transform(root, {\n * depth: 'shallow',\n * input: (node) => ({ ...node, meta: { ...node.meta, title: 'Rewritten' } }),\n * })\n * ```\n */\nexport function transform(node: InputNode, options: TransformOptions): InputNode\nexport function transform(node: OutputNode, options: TransformOptions): OutputNode\nexport function transform(node: OperationNode, options: TransformOptions): OperationNode\nexport function transform(node: SchemaNode, options: TransformOptions): SchemaNode\nexport function transform(node: PropertyNode, options: TransformOptions): PropertyNode\nexport function transform(node: ParameterNode, options: TransformOptions): ParameterNode\nexport function transform(node: ResponseNode, options: TransformOptions): ResponseNode\nexport function transform(node: Node, options: TransformOptions): Node\nexport function transform(node: Node, options: TransformOptions): Node {\n const { depth, parent, ...visitor } = options\n const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep\n\n // Split the visitor object out once here, then thread it plus `recurse`/`parent` as plain\n // arguments through the recursion. The previous code re-ran the `...visitor` rest-destructure on\n // every recursive `transform` call and rebuilt a `{ ...options, parent }` object per node, so the\n // options shape (which callbacks are present) varied call to call and the hot recursion churned.\n return transformNode(node, visitor, recurse, parent)\n}\n\n/**\n * Visits a single node, then immutably rebuilds its children. Returns the original\n * reference when neither the visitor nor the child rebuild changed anything, so callers\n * can detect \"nothing changed\" by identity and ancestors avoid reallocating.\n */\nfunction transformNode(node: Node, visitor: Visitor, recurse: boolean, parent: Node | undefined): Node {\n const visited = applyVisitor<Node>(node, visitor, parent) ?? node\n return transformChildren(visited, visitor, recurse)\n}\n\n/**\n * Immutably rebuilds a node's children using {@link VISITOR_KEYS}, transforming\n * each child node and leaving non-node values (e.g. `additionalProperties: true`) intact.\n * `Schema` children are skipped in shallow mode.\n */\nfunction transformChildren(node: Node, visitor: Visitor, recurse: boolean): Node {\n if (node.kind === 'Schema' && !recurse) return node\n\n const keys = visitorKeysByKind[node.kind]\n if (!keys) return node\n\n const record = node as unknown as Record<string, unknown>\n let updates: Record<string, unknown> | undefined\n\n for (const key of keys) {\n if (!(key in record)) continue\n const value = record[key]\n if (Array.isArray(value)) {\n // Rebuild the array lazily: allocate a new array only once a child actually changes, copying\n // the unchanged prefix at that point. An unchanged array keeps its original reference and\n // allocates nothing. This also drops the per-array `.map` closure that ran on every node.\n let mapped: Array<unknown> | undefined\n for (const [i, item] of value.entries()) {\n const next = isNode(item) ? transformNode(item, visitor, recurse, node) : item\n if (mapped) {\n mapped.push(next)\n continue\n }\n if (next !== item) mapped = [...value.slice(0, i), next]\n }\n if (mapped) (updates ??= {})[key] = mapped\n } else if (isNode(value)) {\n const next = transformNode(value, visitor, recurse, node)\n if (next !== value) (updates ??= {})[key] = next\n }\n }\n\n if (!updates) return node\n const merged = { ...node, ...updates }\n return merged as Node\n}\n/**\n * Lazy depth-first collection pass. Yields every non-null value returned by\n * the visitor callbacks. Use `collect` for the eager array form.\n *\n * @example Collect every operationId\n * ```ts\n * const ids: string[] = []\n * for (const id of collectLazy<string>(root, {\n * operation(node) {\n * return node.operationId\n * },\n * })) {\n * ids.push(id)\n * }\n * ```\n */\nexport function* collectLazy<T>(node: Node, options: CollectOptions<T>): Generator<T, void, undefined> {\n const { depth, parent, ...visitor } = options\n const recurse = (depth ?? visitorDepths.deep) === visitorDepths.deep\n\n // Thread the split-out visitor through the recursion instead of rebuilding `{ ...options, parent }`\n // for every child, mirroring `transform`. Keeps the recursive object shape stable.\n yield* collectNode<T>(node, visitor as CollectVisitor<T>, recurse, parent)\n}\n\nfunction* collectNode<T>(node: Node, visitor: CollectVisitor<T>, recurse: boolean, parent: Node | undefined): Generator<T, void, undefined> {\n const v = applyVisitor<T>(node, visitor, parent)\n if (v != null) yield v\n\n for (const child of getChildren(node, recurse)) {\n yield* collectNode<T>(child, visitor, recurse, node)\n }\n}\n\n/**\n * Eager depth-first collection pass. Gathers every non-null value the visitor\n * callbacks return into an array.\n *\n * @example Collect every operationId\n * ```ts\n * const ids = collect<string>(root, {\n * operation(node) {\n * return node.operationId\n * },\n * })\n * ```\n */\nexport function collect<T>(node: Node, options: CollectOptions<T>): Array<T> {\n return Array.from(collectLazy(node, options))\n}\n","import type { VisitorDepth } from './constants.ts'\nimport type { VisitorKey } from './defineNode.ts'\nimport { visitorKeys } from './defineNode.ts'\nimport type { Node } from './nodes/index.ts'\nimport type { Visitor, VisitorContext } from './visitor.ts'\nimport { transform } from './visitor.ts'\n\n/**\n * Ordering hint shared by macros and plugins. `pre` runs before unmarked items, `post` after,\n * and `undefined` keeps declaration order.\n */\nexport type Enforce = 'pre' | 'post'\n\n/**\n * Sort weight for an `enforce` hint. `pre` sorts before unmarked items and `post` after, so a plain\n * list keeps its authored order.\n */\nfunction enforceWeight(enforce?: Enforce): number {\n if (enforce === 'pre') return 0\n if (enforce === 'post') return 2\n return 1\n}\n\n/**\n * A named, composable transform over the Kubb AST. It carries the same per-kind callbacks as a\n * {@link Visitor} (`schema`, `operation`, …), plus a `name`, an optional `enforce` order, and an\n * optional `when` gate. Macros run on the shared AST, so the same macro works across every adapter\n * and output target. Exports follow the `macro<Name>` convention, mirroring plugins (`pluginTs`).\n */\nexport type Macro = Visitor & {\n /**\n * Macro identifier used to tell macros apart, for example `'simplify-union'`.\n */\n name: string\n /**\n * Ordering hint. `pre` macros run before unmarked macros, `post` macros run after.\n * Ordering within a bucket follows list order.\n */\n enforce?: Enforce\n /**\n * Gate checked against the current node before any callback runs. When it returns `false`\n * the macro is skipped for that node.\n */\n when?: (node: Node) => boolean\n}\n\n/**\n * Types a macro for inference and a single construction site, mirroring `definePlugin`.\n * Adds no runtime behavior.\n *\n * @example\n * ```ts\n * const macroUntagged = defineMacro({\n * name: 'untagged',\n * operation(node) {\n * return node.tags?.length ? undefined : { ...node, tags: ['untagged'] }\n * },\n * })\n * ```\n */\nexport function defineMacro(macro: Macro): Macro {\n return macro\n}\n\ntype MacroCallback = (node: Node, context: VisitorContext) => Node | null | undefined\n\ntype ChainProps = {\n macros: ReadonlyArray<Macro>\n key: VisitorKey\n node: Node\n context: VisitorContext\n}\n\n/**\n * Runs every macro's callback for one node kind in order, chaining the result so each macro sees\n * the previous macro's output. Returns `undefined` when nothing changed, so `transform` keeps the\n * original reference (structural sharing).\n */\nfunction chain({ macros, key, node, context }: ChainProps): Node | undefined {\n let current = node\n\n for (const macro of macros) {\n const callback = macro[key] as MacroCallback | undefined\n if (!callback) continue\n if (macro.when && !macro.when(current)) continue\n\n const next = callback(current, context)\n if (next != null) current = next\n }\n\n return current === node ? undefined : current\n}\n\n/**\n * Folds an ordered list of macros into a single {@link Visitor} that `transform` (and the per-plugin\n * transform layer in `@kubb/core`) can run. Macros are stable-sorted by `enforce`, then applied\n * sequentially per node so later macros see earlier output. This differs from a plain visitor, which\n * has no names, ordering, or composition.\n *\n * @example\n * ```ts\n * const visitor = composeMacros([macroSimplifyUnion, macroDiscriminatorEnum])\n * const next = transform(root, visitor)\n * ```\n */\nexport function composeMacros(macros: ReadonlyArray<Macro>): Visitor {\n const ordered = [...macros].sort((a, b) => enforceWeight(a.enforce) - enforceWeight(b.enforce))\n\n const visitor: Visitor = {}\n for (const key of visitorKeys) {\n if (!ordered.some((macro) => typeof macro[key] === 'function')) continue\n\n const callback = (node: Node, context: VisitorContext) => chain({ macros: ordered, key, node, context })\n ;(visitor as Record<VisitorKey, MacroCallback>)[key] = callback\n }\n\n return visitor\n}\n\n/**\n * Runs a list of macros over a node tree and returns the rewritten tree. Keeps `transform`'s\n * structural sharing, so an empty or no-op macro list returns the same reference. Pass\n * `depth: 'shallow'` to rewrite the root node only.\n *\n * @example\n * ```ts\n * const next = applyMacros(root, [macroIntegerToString])\n * ```\n *\n * @example Apply to the root node only\n * ```ts\n * const named = applyMacros(node, [macroEnumName({ parentName, propName, enumSuffix })], { depth: 'shallow' })\n * ```\n */\nexport function applyMacros<TNode extends Node>(root: TNode, macros: ReadonlyArray<Macro>, options?: { depth?: VisitorDepth }): TNode {\n if (macros.length === 0) return root\n\n return transform(root, { ...composeMacros(macros), ...options }) as TNode\n}\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Runtime context passed as `this` to printer handlers.\n *\n * `this.transform` dispatches to node-level handlers from `nodes`.\n *\n * @example\n * ```ts\n * const context: PrinterHandlerContext<string, {}> = {\n * options: {},\n * transform: () => 'value',\n * base: () => 'value',\n * }\n * ```\n */\ntype PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively transform a nested `SchemaNode` to `TOutput` using the node-level handlers.\n * Use `this.transform` inside `nodes` handlers and inside the `print` override.\n */\n transform: (node: SchemaNode) => TOutput | null\n /**\n * Run the printer's built-in handler for the node, ignoring any override for its type.\n * Inside an override, `this.base(node)` returns what the printer would have emitted,\n * so the override can wrap it instead of re-implementing the handler. Nested nodes\n * still dispatch through the overrides.\n */\n base: (node: SchemaNode) => TOutput | null\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for one schema node type.\n *\n * Use a regular function (not an arrow function) if you need `this`.\n *\n * @example\n * ```ts\n * const handler: PrinterHandler<string, {}, 'string'> = function () {\n * return 'string'\n * }\n * ```\n */\ntype PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null\n\n/**\n * Partial map of per-node-type handler overrides for a printer.\n *\n * Each key is a `SchemaType` string (e.g. `'date'`, `'string'`).\n * Supply only the handlers you want to replace. The printer's built-in\n * defaults fill in the rest.\n *\n * @example\n * ```ts\n * pluginZod({\n * printer: {\n * nodes: {\n * date(): string {\n * return 'z.string().date()'\n * },\n * } satisfies PrinterPartial<string, PrinterZodOptions>,\n * },\n * })\n * ```\n */\nexport type PrinterPartial<TOutput, TOptions extends object> = Partial<{\n [K in SchemaType]: PrinterHandler<TOutput, TOptions, K>\n}>\n\n/**\n * Generic shape used by `definePrinter`.\n *\n * - `TName` unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` options passed to and stored on the printer instance\n * - `TOutput` the type emitted by node handlers\n * - `TPrintOutput` type returned by public `print` (defaults to `TOutput`)\n *\n * @example\n * ```ts\n * type MyPrinter = PrinterFactoryOptions<'my', { strict: boolean }, string>\n * ```\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown, TPrintOutput = TOutput> = {\n name: TName\n options: TOptions\n output: TOutput\n printOutput: TPrintOutput\n}\n\n/**\n * Printer instance returned by a printer factory.\n *\n * @example\n * ```ts\n * const printer = definePrinter((options: {}) => ({ name: 'x', options, nodes: {} }))({})\n * ```\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Node-level dispatcher, converts a `SchemaNode` directly to `TOutput` using the `nodes` handlers.\n * Always dispatches through the `nodes` map. Never calls the `print` override.\n * Reach for it when you need the raw output (e.g. `ts.TypeNode`) without declaration wrapping.\n */\n transform: (node: SchemaNode) => T['output'] | null\n /**\n * Public printer. If the builder provides a root-level `print`, this calls that\n * higher-level function (which may produce full declarations).\n * Otherwise, falls back to the node-level dispatcher.\n */\n print: (node: SchemaNode) => T['printOutput'] | null\n}\n\n/**\n * Builder function passed to `definePrinter`.\n *\n * It receives resolved options and returns:\n * - `name`\n * - `options`\n * - `nodes` handlers\n * - optional top-level `print` override\n *\n * @example\n * ```ts\n * const build = (options: {}) => ({ name: 'x' as const, options, nodes: {} })\n * ```\n */\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * User-supplied handler overrides. An override wins over the matching `nodes` handler,\n * and can call `this.base(node)` to reuse the handler it replaced. Pass overrides here\n * instead of spreading them into `nodes`, otherwise `this.base` cannot find the original.\n */\n overrides?: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n /**\n * Optional root-level print override. When provided, becomes the public `printer.print`.\n * Use `this.transform(node)` inside this function to dispatch to the node-level handlers (`nodes`),\n * not the override itself, so recursion is safe.\n */\n print?: (this: PrinterHandlerContext<T['output'], T['options']>, node: SchemaNode) => T['printOutput'] | null\n}\n/**\n * Creates a schema printer: a function that takes a `SchemaNode` and emits\n * code in your target language. Each plugin that produces code from schemas\n * (TypeScript types, Zod schemas, Faker factories) ships a printer built\n * with this helper.\n *\n * The builder receives resolved options and returns:\n *\n * - `name` unique identifier for the printer.\n * - `options` stored on the returned printer instance.\n * - `nodes` map of `SchemaType` → handler. Handlers return the rendered\n * output (a string, a TypeScript AST node, ...) for that schema type.\n * - `overrides` (optional), user-supplied handlers that win over `nodes`.\n * An override can call `this.base(node)` to reuse the handler it replaced.\n * - `print` (optional), top-level override exposed as `printer.print`.\n * Use `this.transform(node)` inside it to dispatch to `nodes` recursively.\n *\n * Without a `print` override, `printer.print` falls back to `printer.transform`\n * (the node-level dispatcher).\n *\n * @example Tiny Zod printer\n * ```ts\n * import { createPrinter, type PrinterFactoryOptions } from '@kubb/ast'\n *\n * type PrinterZod = PrinterFactoryOptions<'zod', { strict?: boolean }, string>\n *\n * export const zodPrinter = createPrinter<PrinterZod>((options) => ({\n * name: 'zod',\n * options: { strict: options.strict ?? true },\n * nodes: {\n * string: () => 'z.string()',\n * object(node) {\n * const props = node.properties\n * .map((p) => `${p.name}: ${this.transform(p.schema)}`)\n * .join(', ')\n * return `z.object({ ${props} })`\n * },\n * },\n * }))\n * ```\n */\nexport function createPrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes, overrides, print: printOverride } = build((options ?? {}) as T['options'])\n const merged = overrides ? { ...nodes, ...overrides } : nodes\n\n const context = {\n options: resolvedOptions,\n transform: (node: SchemaNode): T['output'] | null => {\n const handler = merged[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n base: (node: SchemaNode): T['output'] | null => {\n const handler = nodes[node.type]\n if (!handler) return null\n\n return (handler as (this: typeof context, node: SchemaNode) => T['output'] | null).call(context, node)\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n transform: context.transform,\n print: (printOverride ? printOverride.bind(context) : context.transform) as (node: SchemaNode) => T['printOutput'] | null,\n }\n }\n}\n","import { narrowSchema } from '../guards.ts'\nimport { createSchema, type SchemaNode } from '../nodes/schema.ts'\n\n/**\n * Merges a run of adjacent anonymous object members into one. Named or non-object members break the\n * run and pass through unchanged. The merge follows member order, so callers control which members\n * combine by where they place them in the sequence.\n *\n * @example\n * ```ts\n * const merged = [...mergeAdjacentObjectsLazy([objectA, objectB])]\n * ```\n */\nexport function* mergeAdjacentObjectsLazy(members: Iterable<SchemaNode>): Generator<SchemaNode, void, undefined> {\n let acc: SchemaNode | undefined\n\n for (const member of members) {\n const objectMember = narrowSchema(member, 'object')\n if (objectMember && !objectMember.name && acc !== undefined) {\n const accObject = narrowSchema(acc, 'object')\n if (accObject && !accObject.name) {\n acc = createSchema({\n ...accObject,\n properties: [...(accObject.properties ?? []), ...(objectMember.properties ?? [])],\n })\n continue\n }\n }\n if (acc !== undefined) yield acc\n acc = member\n }\n\n if (acc !== undefined) yield acc\n}\n","import { pascalCase } from '@internals/utils'\nimport { narrowSchema } from '../guards.ts'\nimport type { SchemaNode } from '../nodes/index.ts'\nimport { createSchema, type SchemaType } from '../nodes/schema.ts'\n\nconst plainStringTypes = new Set<SchemaType>(['string', 'uuid', 'email', 'url', 'datetime'] as const)\n\n/**\n * Returns the last path segment of a reference string.\n *\n * @example\n * `extractRefName('#/components/schemas/Pet') // 'Pet'`\n */\nexport function extractRefName(ref: string): string {\n return ref.split('/').at(-1) ?? ref\n}\n\n/**\n * Resolves the schema name of a ref node. Uses the last segment of `ref` when set, otherwise falls\n * back to `name` then nested `schema.name`.\n *\n * Returns `null` for non-ref nodes or when no name resolves.\n *\n * @example\n * `resolveRefName({ kind: 'Schema', type: 'ref', ref: '#/components/schemas/Pet' }) // 'Pet'`\n */\nexport function resolveRefName(node: SchemaNode | undefined): string | null {\n if (!node || node.type !== 'ref') return null\n if (node.ref) return extractRefName(node.ref)\n\n return node.name ?? node.schema?.name ?? null\n}\n\n/**\n * Builds a PascalCase child schema name by joining a parent name and property name.\n * Returns `null` when there is no parent to nest under.\n *\n * @example Nested under a parent\n * `childName('Order', 'shipping_address') // 'OrderShippingAddress'`\n *\n * @example No parent\n * `childName(undefined, 'params') // null`\n */\nexport function childName(parentName: string | null | undefined, propName: string): string | null {\n return parentName ? pascalCase([parentName, propName].join(' ')) : null\n}\n\n/**\n * Builds a PascalCase enum name from the parent name, property name, and a suffix, skipping any\n * empty parts.\n *\n * @example\n * `enumPropName('Order', 'status', 'enum') // 'OrderStatusEnum'`\n */\nexport function enumPropName(parentName: string | null | undefined, propName: string, enumSuffix: string): string {\n return pascalCase([parentName, propName, enumSuffix].filter(Boolean).join(' '))\n}\n\n/**\n * Merges a ref node with its resolved schema, giving usage-site fields precedence.\n *\n * Every field set on the ref node except `kind`, `type`, `name`, `ref`, and `schema` overrides the\n * same field in the resolved `node.schema` (for example `description`, `nullable`, `readOnly`,\n * `deprecated`). Fields left `undefined` on the ref do not shadow the resolved schema. Non-ref\n * nodes and refs without a resolved `schema` are returned unchanged.\n *\n * @example\n * ```ts\n * const ref = createSchema({ type: 'ref', ref: '#/components/schemas/Pet', description: 'A cute pet' })\n * const merged = syncSchemaRef(ref) // merges with resolved Pet schema\n * ```\n */\nexport function syncSchemaRef(node: SchemaNode): SchemaNode {\n const ref = narrowSchema(node, 'ref')\n\n if (!ref) return node\n if (!ref.schema) return node\n\n const { kind: _kind, type: _type, name: _name, ref: _ref, schema: _schema, ...overrides } = ref\n\n // Filter out undefined override values so they don't shadow the resolved schema's fields.\n const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, v]) => v !== undefined))\n\n return createSchema({ ...ref.schema, ...definedOverrides })\n}\n\n/**\n * Returns `true` when a schema emits as a plain `string` type.\n *\n * Covers `string`, `uuid`, `email`, `url`, and `datetime` types. For `date` and `time`\n * types, returns `true` only when `representation` is `'string'` rather than `'date'`.\n */\nexport function isStringType(node: SchemaNode): boolean {\n if (plainStringTypes.has(node.type)) {\n return true\n }\n\n const temporal = narrowSchema(node, 'date') ?? narrowSchema(node, 'time')\n if (temporal) {\n return temporal.representation !== 'date'\n }\n\n return false\n}\n","import { memoize } from '@internals/utils'\nimport type { OperationNode, SchemaNode } from '../nodes/index.ts'\nimport { collect, collectLazy } from '../visitor.ts'\nimport { resolveRefName } from './refs.ts'\n\n/**\n * Memoized inner pass that walks a single node and returns the names of every schema it references.\n */\nconst collectSchemaRefs = memoize(new WeakMap<SchemaNode, ReadonlySet<string>>(), (node: SchemaNode): ReadonlySet<string> => {\n const refs = new Set<string>()\n collect<void>(node, {\n schema(child) {\n if (child.type === 'ref') {\n const name = resolveRefName(child)\n if (name) refs.add(name)\n }\n },\n })\n return refs\n})\n\n/**\n * Collects the names of every ref found anywhere inside a node's own subtree.\n *\n * Each ref contributes its name only, so the schema it points to is never traversed here. Pass `out`\n * to accumulate names from several nodes into one set.\n *\n * @example Collect refs from a single schema\n * ```ts\n * const names = collectReferencedSchemaNames(petSchema)\n * // Set { 'Category', 'Tag' }\n * ```\n *\n * @example Accumulate refs from multiple schemas into one set\n * ```ts\n * const out = new Set<string>()\n * for (const schema of schemas) {\n * collectReferencedSchemaNames(schema, out)\n * }\n * ```\n */\nexport function collectReferencedSchemaNames(node: SchemaNode | undefined, out: Set<string> = new Set()): Set<string> {\n if (!node) return out\n for (const name of collectSchemaRefs(node)) out.add(name)\n return out\n}\n\n/**\n * Memoized two-level cache keyed first on the operations array, then on the schemas array.\n */\nconst collectUsedSchemaNamesMemo = memoize(new WeakMap<ReadonlyArray<OperationNode>, (schemas: ReadonlyArray<SchemaNode>) => Set<string>>(), (ops) =>\n memoize(new WeakMap<ReadonlyArray<SchemaNode>, Set<string>>(), (schemas) => computeUsedSchemaNames(ops, schemas)),\n)\n\nfunction computeUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string> {\n const schemaMap = new Map<string, SchemaNode>()\n for (const schema of schemas) {\n if (schema.name) schemaMap.set(schema.name, schema)\n }\n\n const result = new Set<string>()\n\n function visitSchema(schema: SchemaNode): void {\n const directRefs = collectReferencedSchemaNames(schema)\n for (const name of directRefs) {\n if (!result.has(name)) {\n result.add(name)\n const namedSchema = schemaMap.get(name)\n if (namedSchema) visitSchema(namedSchema)\n }\n }\n }\n\n for (const op of operations) {\n for (const schema of collectLazy<SchemaNode>(op, { depth: 'shallow', schema: (node) => node })) {\n visitSchema(schema)\n }\n }\n\n return result\n}\n\n/**\n * Collects the names of all top-level schemas transitively used by a set of operations.\n *\n * An operation uses a schema when its parameters, request body, or responses reference it, directly\n * or through other named schemas. Once a name is added to the result it is not revisited, so\n * reference cycles terminate.\n *\n * Pair it with `include` filters so schemas reachable only from excluded operations stay ungenerated.\n *\n * @example Only generate schemas referenced by included operations\n * ```ts\n * const includedOps = operations.filter((op) => resolver.default.options(op, { options, include }) !== null)\n * const allowed = collectUsedSchemaNames(includedOps, schemas)\n *\n * for (const schema of schemas) {\n * if (schema.name && !allowed.has(schema.name)) continue\n * // generate schema\n * }\n * ```\n */\nexport function collectUsedSchemaNames(operations: ReadonlyArray<OperationNode>, schemas: ReadonlyArray<SchemaNode>): Set<string> {\n return collectUsedSchemaNamesMemo(operations)(schemas)\n}\n\nconst EMPTY_CIRCULAR_SET = new Set<string>()\n\nconst findCircularSchemasMemo = memoize(new WeakMap<ReadonlyArray<SchemaNode>, Set<string>>(), (schemas: ReadonlyArray<SchemaNode>): Set<string> => {\n const graph = new Map<string, Set<string>>()\n\n for (const schema of schemas) {\n if (!schema.name) continue\n graph.set(schema.name, collectReferencedSchemaNames(schema))\n }\n\n const circular = new Set<string>()\n for (const start of graph.keys()) {\n const visited = new Set<string>()\n const stack: Array<string> = [...(graph.get(start) ?? [])]\n while (stack.length > 0) {\n const node = stack.pop()!\n if (node === start) {\n circular.add(start)\n break\n }\n if (visited.has(node)) continue\n visited.add(node)\n\n const next = graph.get(node)\n if (next) for (const r of next) stack.push(r)\n }\n }\n\n return circular\n})\n\n/**\n * Finds every schema that takes part in a circular dependency chain, including direct self-loops.\n *\n * Wrap the returned schema positions in a deferred construct (a lazy getter or `z.lazy(() => …)`) so\n * the generated code does not recurse forever. Refs are followed by name only, so the walk stays\n * linear in the size of the schema graph.\n *\n * @note Call this once on the full graph, then check individual schemas with `containsCircularRef()`.\n */\nexport function findCircularSchemas(schemas: ReadonlyArray<SchemaNode>): Set<string> {\n if (schemas.length === 0) return EMPTY_CIRCULAR_SET\n return findCircularSchemasMemo(schemas)\n}\n\n/**\n * Returns `true` when a schema, or anything nested inside it, references a circular schema.\n *\n * Pass `excludeName` to skip refs to a specific schema, which helps when self-references are handled\n * on their own. Pair it with `findCircularSchemas()` to decide where lazy wrappers go.\n *\n * @note Stops at the first matching circular ref.\n */\nexport function containsCircularRef(\n node: SchemaNode | undefined,\n { circularSchemas, excludeName }: { circularSchemas: ReadonlySet<string>; excludeName?: string },\n): boolean {\n if (!node || circularSchemas.size === 0) return false\n\n for (const _ of collectLazy<true>(node, {\n schema(child) {\n if (child.type !== 'ref') return null\n const name = resolveRefName(child)\n return name && name !== excludeName && circularSchemas.has(name) ? true : null\n },\n })) {\n return true\n }\n\n return false\n}\n","import type { ArraySchemaNode, IntersectionSchemaNode, ObjectSchemaNode, PropertyNode, SchemaNode, UnionSchemaNode } from '../nodes/index.ts'\n\n/**\n * Converts a child schema to printer output. Plugins instantiate it with their own output type:\n * `string` for the zod and faker printers, `ts.TypeNode` for the TypeScript printer. A printer's\n * `this.transform` fits directly, so its `null` for an empty result carries through to `output`.\n */\nexport type SchemaTransform<TOutput> = (schema: SchemaNode) => TOutput\n\n/**\n * A union or intersection member, or an array or tuple item, paired with its transformed output.\n */\nexport type MappedSchema<TOutput> = {\n /**\n * The original child schema, kept so the printer can read its metadata for leaf formatting.\n */\n schema: SchemaNode\n /**\n * The child schema after being run through the transform.\n */\n output: TOutput\n}\n\n/**\n * An object property paired with its transformed output.\n */\nexport type MappedProperty<TOutput> = {\n /**\n * The property name as written on the schema, before any identifier quoting.\n */\n name: string\n /**\n * The original property node, kept so the printer can read `required`, `schema`, and metadata.\n */\n property: PropertyNode\n /**\n * The property schema after being run through the transform.\n */\n output: TOutput\n}\n\n/**\n * Maps each property of an object schema to its transformed output. Pairs every result with the\n * original property so the printer keeps full control over modifiers, getters, and key syntax.\n *\n * @example\n * ```ts\n * const entries = mapSchemaProperties(node, (schema) => this.transform(schema))\n * // entries: [{ name: 'id', property, output: 'z.number()' }, ...]\n * ```\n */\nexport function mapSchemaProperties<TOutput>(node: ObjectSchemaNode, transform: SchemaTransform<TOutput>): Array<MappedProperty<TOutput>> {\n return node.properties.map((property) => ({ name: property.name, property, output: transform(property.schema) }))\n}\n\n/**\n * Maps each member of a union or intersection schema to its transformed output, pairing every\n * result with the original member.\n */\nexport function mapSchemaMembers<TOutput>(node: UnionSchemaNode | IntersectionSchemaNode, transform: SchemaTransform<TOutput>): Array<MappedSchema<TOutput>> {\n return (node.members ?? []).map((schema) => ({ schema, output: transform(schema) }))\n}\n\n/**\n * Maps each item of an array or tuple schema to its transformed output, pairing every result with\n * the original item.\n */\nexport function mapSchemaItems<TOutput>(node: ArraySchemaNode, transform: SchemaTransform<TOutput>): Array<MappedSchema<TOutput>> {\n return (node.items ?? []).map((schema) => ({ schema, output: transform(schema) }))\n}\n","import { defineMacro } from '../defineMacro.ts'\nimport { narrowSchema } from '../guards.ts'\nimport { createProperty } from '../nodes/property.ts'\nimport { createSchema } from '../nodes/schema.ts'\n\ntype Props = {\n propertyName: string\n values: Array<string>\n enumName?: string\n}\n\n/**\n * Builds a macro that replaces a discriminator property's schema with a string enum of the given\n * values. Object schemas that lack the property are returned unchanged.\n *\n * @example\n * ```ts\n * const macro = macroDiscriminatorEnum({ propertyName: 'type', values: ['dog', 'cat'] })\n * const next = applyMacros(objectSchema, [macro], { depth: 'shallow' })\n * ```\n */\nexport function macroDiscriminatorEnum({ propertyName, values, enumName }: Props) {\n return defineMacro({\n name: 'discriminator-enum',\n schema(node) {\n const objectNode = narrowSchema(node, 'object')\n if (!objectNode?.properties?.length) return undefined\n if (!objectNode.properties.some((prop) => prop.name === propertyName)) return undefined\n\n return createSchema({\n ...objectNode,\n properties: objectNode.properties.map((prop) => {\n if (prop.name !== propertyName) return prop\n\n return createProperty({\n ...prop,\n schema: createSchema({\n type: 'enum',\n primitive: 'string',\n enumValues: values,\n name: enumName,\n readOnly: prop.schema.readOnly,\n writeOnly: prop.schema.writeOnly,\n }),\n })\n }),\n })\n },\n })\n}\n","import { defineMacro } from '../defineMacro.ts'\nimport { narrowSchema } from '../guards.ts'\nimport { enumPropName } from '../utils/refs.ts'\n\ntype Props = {\n parentName: string | null | undefined\n propName: string\n enumSuffix: string\n}\n\n/**\n * Builds a macro that names an inline enum schema from its parent and property name. Boolean enums\n * are left anonymous. Non-enum nodes are returned unchanged.\n *\n * @example\n * ```ts\n * const macro = macroEnumName({ parentName: 'Pet', propName: 'status', enumSuffix: 'enum' })\n * const named = applyMacros(propSchema, [macro], { depth: 'shallow' })\n * ```\n */\nexport function macroEnumName({ parentName, propName, enumSuffix }: Props) {\n return defineMacro({\n name: 'enum-name',\n schema(node) {\n const enumNode = narrowSchema(node, 'enum')\n\n if (enumNode?.primitive === 'boolean') return { ...node, name: null }\n if (enumNode) return { ...node, name: enumPropName(parentName, propName, enumSuffix) }\n\n return undefined\n },\n })\n}\n","import { defineMacro } from '../defineMacro.ts'\nimport { narrowSchema } from '../guards.ts'\nimport type { SchemaNode } from '../nodes/schema.ts'\n\ntype ScalarPrimitive = 'string' | 'number' | 'integer' | 'bigint' | 'boolean'\n\n/**\n * Scalar primitive schema types used for union simplification and type narrowing.\n */\nconst SCALAR_PRIMITIVE_TYPES = new Set<ScalarPrimitive>(['string', 'number', 'integer', 'bigint', 'boolean'])\n\nfunction isScalarPrimitive(type: string): type is ScalarPrimitive {\n return SCALAR_PRIMITIVE_TYPES.has(type as ScalarPrimitive)\n}\n\n/**\n * Filters union members, dropping enum members that a broader scalar primitive already covers.\n */\nfunction simplifyUnionMembers(members: Array<SchemaNode>): Array<SchemaNode> {\n const scalarPrimitives = new Set(members.filter((member) => isScalarPrimitive(member.type)).map((m) => m.type))\n if (!scalarPrimitives.size) return members\n\n return members.filter((member) => {\n const enumNode = narrowSchema(member, 'enum')\n if (!enumNode) return true\n\n const primitive = enumNode.primitive\n if (!primitive) return true\n\n const enumValueCount = enumNode.namedEnumValues?.length ?? enumNode.enumValues?.length ?? 0\n if (enumValueCount <= 1) return true\n\n if (scalarPrimitives.has(primitive)) return false\n if ((primitive === 'integer' || primitive === 'number') && (scalarPrimitives.has('integer') || scalarPrimitives.has('number'))) return false\n\n return true\n })\n}\n\n/**\n * Removes union members a broader scalar primitive already covers, such as a multi-value string enum\n * sitting next to a plain `string`. Single-value enums are kept.\n *\n * @example\n * ```ts\n * const next = applyMacros(unionSchema, [macroSimplifyUnion], { depth: 'shallow' })\n * ```\n */\nexport const macroSimplifyUnion = defineMacro({\n name: 'simplify-union',\n schema(node) {\n const unionNode = narrowSchema(node, 'union')\n if (!unionNode?.members?.length) return undefined\n\n const simplified = simplifyUnionMembers(unionNode.members)\n if (simplified.length === unionNode.members.length) return undefined\n\n return { ...unionNode, members: simplified }\n },\n})\n","import type { Node } from './nodes/index.ts'\n\nexport { createArrowFunction, createBreak, createConst, createFunction, createJsx, createText, createType } from './nodes/code.ts'\nexport { createContent } from './nodes/content.ts'\nexport { createExport, createFile, createImport, createSource } from './nodes/file.ts'\nexport type { UserFileNode } from './nodes/file.ts'\nexport { createInput } from './nodes/input.ts'\nexport { createOperation } from './nodes/operation.ts'\nexport { createOutput } from './nodes/output.ts'\nexport { createParameter } from './nodes/parameter.ts'\nexport { createProperty } from './nodes/property.ts'\nexport { createRequestBody } from './nodes/requestBody.ts'\nexport { createResponse } from './nodes/response.ts'\nexport { createSchema } from './nodes/schema.ts'\n\n/**\n * Identity-preserving node update: returns `node` unchanged when every field in\n * `changes` already equals (by reference) the current value, otherwise a new node\n * with the changes applied.\n *\n * Mirrors the TypeScript compiler's `factory.updateX` contract. Pair it with the\n * structural sharing in {@link transform} so a no-op rewrite does not allocate and\n * downstream passes can detect \"nothing changed\" by identity. Comparison is shallow,\n * so a structurally equal but newly allocated array or object counts as a change.\n *\n * @example\n * ```ts\n * update(node, { name: node.name }) // -> same `node` reference\n * update(node, { name: 'renamed' }) // -> new node, `name` replaced\n * ```\n */\nexport function update<T extends Node>(node: T, changes: Partial<T>): T {\n for (const key in changes) {\n if (changes[key] !== node[key as keyof T]) {\n return { ...node, ...changes }\n }\n }\n\n return node\n}\n","export { schemaTypes } from './constants.ts'\nexport { isHttpOperationNode, narrowSchema } from './guards.ts'\nexport { applyMacros, composeMacros, defineMacro } from './defineMacro.ts'\nexport { defineNode } from './defineNode.ts'\nexport { optionality } from './optionality.ts'\nexport { createPrinter } from './createPrinter.ts'\nexport { collect, transform } from './visitor.ts'\nexport * from './utils/index.ts'\nexport * from './macros/index.ts'\n\nexport * as factory from './factory.ts'\nexport * from './registry.ts'\nexport type * from './types.ts'\n"],"mappings":"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"}
|