🚀. Socket Launch Week Day 3:Socket Firewall Now Blocks Malicious VS Code and Open VSX Extensions.Learn more
Sign In

@kubb/parser-ts

Package Overview
Dependencies
Maintainers
1
Versions
489
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kubb/parser-ts - npm Package Compare versions

Comparing version
5.0.0-beta.54
to
5.0.0-beta.55
+16
-7
dist/index.cjs

@@ -28,3 +28,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

typescript = __toESM(typescript, 1);
//#region ../../internals/utils/src/fs.ts
/**
* Strips the file extension from a path or file name.
* Only removes the last `.ext` segment when the dot is not part of a directory name.
*
* @example
* trimExtName('petStore.ts') // 'petStore'
* trimExtName('/src/models/pet.ts') // '/src/models/pet'
* trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
* trimExtName('noExtension') // 'noExtension'
*/
function trimExtName(text) {
const dotIndex = text.lastIndexOf(".");
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
return text;
}
/**
* Indentation unit prepended once per nesting level when pretty-printing.

@@ -78,9 +94,2 @@ */

/**
* Strips the trailing file extension (for example `.ts`) from a path.
* Preserves intermediate dots like `foo.bar.ts` → `foo.bar`.
*/
function trimExtName(text) {
return text.replace(FILE_EXTENSION_PATTERN, "");
}
/**
* Rewrites an import/export path so its extension matches the caller-supplied

@@ -87,0 +96,0 @@ * `options.extname`. When the source path has no extension the original is kept,

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","names":["ts"],"sources":["../src/constants.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["/**\n * Character used for a single indent step. Set to `'\\t'` to emit tab-indented output.\n */\nexport const INDENT_CHAR = ' '\n\n/**\n * Number of {@link INDENT_CHAR} repeats that make up one nesting level.\n */\nconst INDENT_SIZE = 2 as const\n\n/**\n * Indentation unit prepended once per nesting level when pretty-printing.\n */\nexport const INDENT = INDENT_CHAR.repeat(INDENT_SIZE)\n\n/**\n * Matches the trailing `.<ext>` segment of a path (keeps segments like `foo.bar.ts`\n * intact by only trimming the last run of non-`/`/`.` characters).\n */\nexport const FILE_EXTENSION_PATTERN = /\\.[^/.]+$/\n\n/**\n * Matches Windows-style backslash path separators.\n */\nexport const WINDOWS_PATH_SEPARATOR = /\\\\/g\n\n/**\n * Matches `*\\/` in free-form text so JSDoc bodies can neutralize premature\n * comment terminators (`*\\/` → `* /`).\n */\nexport const JSDOC_TERMINATOR_PATTERN = /\\*\\//g\n\n/**\n * Matches carriage returns for normalizing CRLF/CR line endings to LF.\n */\nexport const CARRIAGE_RETURN_PATTERN = /\\r/g\n\n/**\n * Matches CRLF sequences used when normalizing TypeScript printer output.\n */\nexport const CRLF_PATTERN = /\\r\\n/g\n\n/**\n * Matches an identifier that starts with a digit. JavaScript disallows this,\n * so the printer prefixes such names with `_`.\n */\nexport const LEADING_DIGIT_PATTERN = /^\\d/\n\n/**\n * Relative path prefix used to detect traversal segments (`../`).\n */\nexport const PARENT_DIRECTORY_PREFIX = '../' as const\n\n/**\n * Relative path prefix used when resolving imports within the output root.\n */\nexport const CURRENT_DIRECTORY_PREFIX = './' as const\n","import { normalize, relative } from 'node:path'\nimport type { ArrowFunctionNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, SourceNode, TextNode, TypeNode } from '@kubb/ast'\nimport ts from 'typescript'\nimport {\n CARRIAGE_RETURN_PATTERN,\n CRLF_PATTERN,\n CURRENT_DIRECTORY_PREFIX,\n FILE_EXTENSION_PATTERN,\n INDENT,\n INDENT_CHAR,\n JSDOC_TERMINATOR_PATTERN,\n LEADING_DIGIT_PATTERN,\n PARENT_DIRECTORY_PREFIX,\n WINDOWS_PATH_SEPARATOR,\n} from './constants.ts'\n\nconst { factory } = ts\n\n/**\n * Normalizes a file-system path to POSIX separators and strips any leading `../` segment.\n */\nexport function slash(path: string): string {\n return normalize(path).replaceAll(WINDOWS_PATH_SEPARATOR, '/').replace(PARENT_DIRECTORY_PREFIX, '')\n}\n\n/**\n * Resolves `filePath` relative to `rootDir` and returns a POSIX-style path\n * prefixed with `./` when the target sits inside the root, or `../` when it escapes it.\n */\nexport function getRelativePath(rootDir: string, filePath: string): string {\n const rel = relative(rootDir, filePath)\n const slashed = slash(rel)\n return slashed.startsWith(PARENT_DIRECTORY_PREFIX) ? slashed : `${CURRENT_DIRECTORY_PREFIX}${slashed}`\n}\n\n/**\n * Strips the trailing file extension (for example `.ts`) from a path.\n * Preserves intermediate dots like `foo.bar.ts` → `foo.bar`.\n */\nexport function trimExtName(text: string): string {\n return text.replace(FILE_EXTENSION_PATTERN, '')\n}\n\n/**\n * Rewrites an import/export path so its extension matches the caller-supplied\n * `options.extname`. When the source path has no extension the original is kept,\n * so virtual/module-only paths flow through unchanged.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = FILE_EXTENSION_PATTERN.test(path)\n if (options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Serializes a `nodes` array into source text. Each entry is rendered via {@link printCodeNode}\n * and joined with a single newline; a `Break` node (`<br/>`) inserts one blank line between\n * statements. Consecutive breaks, and breaks at the very start or end, are folded into the\n * separator, so a double `<br/>` never emits more than one blank line.\n */\nexport function printNodes(nodes: Array<CodeNode> | undefined): string {\n if (!nodes || nodes.length === 0) return ''\n\n let result = ''\n let hasContent = false\n let pendingBreak = false\n\n for (const node of nodes) {\n if (node.kind === 'Break') {\n if (hasContent) pendingBreak = true\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (hasContent) result += pendingBreak ? '\\n\\n' : '\\n'\n result += text\n hasContent = true\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by one indent unit. Pass a number to repeat\n * {@link INDENT_CHAR} that many times, or a string to use as the indent verbatim.\n */\nexport function indentLines(text: string, indent: number | string = INDENT): string {\n if (!text) return ''\n const pad = typeof indent === 'string' ? indent : INDENT_CHAR.repeat(indent)\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Removes the common leading whitespace shared by every non-blank line and trims\n * surrounding blank lines, normalizing multi-line content authored inside an\n * indented template literal back to a column-zero baseline. Leading whitespace is\n * counted by character, so N tabs and N spaces are treated as the same depth.\n *\n * @example\n * ```ts\n * dedent('\\n foo\\n bar\\n ')\n * // 'foo\\n bar'\n * ```\n */\nexport function dedent(text: string): string {\n if (!text) return ''\n\n const lines = text.split('\\n')\n const isBlank = (line: string) => line.trim() === ''\n\n const start = lines.findIndex((line) => !isBlank(line))\n if (start === -1) return ''\n const end = lines.findLastIndex((line) => !isBlank(line))\n\n const trimmed = lines.slice(start, end + 1)\n const indents = trimmed.filter((line) => !isBlank(line)).map((line) => line.match(/^\\s*/)?.[0].length ?? 0)\n const min = indents.length ? Math.min(...indents) : 0\n\n return trimmed.map((line) => (isBlank(line) ? '' : line.slice(min))).join('\\n')\n}\n\n/**\n * Renders the generic clause (`<T, U>`) shared by function and arrow-function nodes.\n * Accepts either a raw string (rendered verbatim) or an array of type-parameter names.\n */\nexport function formatGenerics(generics: FunctionNode['generics'] | ArrowFunctionNode['generics']): string {\n if (!generics) return ''\n return `<${Array.isArray(generics) ? generics.join(', ') : generics}>`\n}\n\n/**\n * Renders the return-type suffix (`: T` or `: Promise<T>` when `isAsync` is true).\n * Returns an empty string when no return type is provided.\n */\nexport function formatReturnType(returnType: string | null | undefined, isAsync: boolean | null | undefined): string {\n if (!returnType) return ''\n return isAsync ? `: Promise<${returnType}>` : `: ${returnType}`\n}\n\n/**\n * Module-scoped TypeScript printer instance. `ts.createPrinter()` is stateless across calls\n * (it does not mutate the source file) so a single instance can be safely reused for every\n * `print()` call. Hoisting it out of `print()` avoids re-running the printer initialization\n * for each file's import/export section.\n */\nconst TS_PRINTER = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n})\n\n/**\n * Module-scoped source file used as the print target. `printList` only reads the source\n * file's compiler options / language version. It never mutates it.\n */\nconst PRINT_SOURCE_FILE = ts.createSourceFile('print.tsx', '', ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX)\n\n// Pre-warm the printer at module load. The first `printList` call lazily initializes\n// the printer's internal string-builder and identifier tables. Doing it once at import\n// time keeps that cost off the critical path for short-lived CLI builds.\nTS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray([]), PRINT_SOURCE_FILE)\n\n/**\n * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.\n */\nexport function print(...elements: Array<ts.Node>): string {\n const filtered = elements.filter(Boolean)\n if (filtered.length === 0) return ''\n\n const output = TS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray(filtered), PRINT_SOURCE_FILE)\n\n return output.replace(CRLF_PATTERN, '\\n')\n}\n\n/**\n * Converts a {@link JSDocNode} to a JSDoc comment block string.\n *\n * @example\n * ```ts\n * printJSDoc({ comments: ['@description A pet', '@deprecated'] })\n * // /**\n * // * @description A pet\n * // * @deprecated\n * // *\\/\n * ```\n */\nexport function printJSDoc(jsDoc: JSDocNode): string {\n const comments = (jsDoc.comments ?? []).filter((c) => c != null)\n if (comments.length === 0) return ''\n\n const lines = comments\n .flatMap((c) => c.split(/\\r?\\n/))\n .map((l) => l.replace(JSDOC_TERMINATOR_PATTERN, '* /').replace(CARRIAGE_RETURN_PATTERN, ''))\n .filter((l) => l.trim().length > 0)\n\n if (lines.length === 0) return ''\n\n return ['/**', ...lines.map((l) => ` * ${l}`), ' */'].join('\\n')\n}\n\n/**\n * Converts a {@link ConstNode} to a TypeScript `const` declaration string.\n *\n * Mirrors the `Const` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printConst(createConst({ name: 'pet', export: true, nodes: ['{}'] }))\n * // 'export const pet = {}'\n * ```\n *\n * @example With type and `as const`\n * ```ts\n * printConst(createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true, nodes: ['[]'] }))\n * // 'export const pets: Pet[] = [] as const'\n * ```\n */\nexport function printConst(node: ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('const ')\n parts.push(name)\n if (type) {\n parts.push(`: ${type}`)\n }\n parts.push(' = ')\n parts.push(body)\n if (asConst) parts.push(' as const')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link TypeNode} to a TypeScript `type` alias declaration string.\n *\n * Mirrors the `Type` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printType(createType({ name: 'Pet', export: true, nodes: ['{ id: number }'] }))\n * // 'export type Pet = { id: number }'\n * ```\n */\nexport function printType(node: TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('type ')\n parts.push(name)\n parts.push(' = ')\n parts.push(body)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link FunctionNode} to a TypeScript `function` declaration string.\n *\n * Mirrors the `Function` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printFunction(createFunction({ name: 'getPet', export: true, params: 'id: string', returnType: 'Pet', nodes: ['return fetch(id)'] }))\n * // 'export function getPet(id: string): Pet {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Async with generics\n * ```ts\n * printFunction(createFunction({ name: 'fetchPet', export: true, async: true, generics: ['T'], params: 'id: string', returnType: 'T' }))\n * // 'export async function fetchPet<T>(id: string): Promise<T> {\\n}'\n * ```\n */\nexport function printFunction(node: FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const indented = body ? indentLines(body) : ''\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n if (isAsync) parts.push('async ')\n parts.push('function ')\n parts.push(name)\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(' {')\n if (indented) {\n parts.push(`\\n${indented}\\n`)\n }\n parts.push('}')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts an {@link ArrowFunctionNode} to a TypeScript arrow function declaration string.\n *\n * Mirrors the `Function.Arrow` component from `@kubb/renderer-jsx`.\n *\n * @example Multi-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'getPet', export: true, params: 'id: string', nodes: ['return fetch(id)'] }))\n * // 'export const getPet = (id: string) => {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Single-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'double', params: 'n: number', singleLine: true, nodes: ['n * 2'] }))\n * // 'const double = (n: number) => n * 2'\n * ```\n */\nexport function printArrowFunction(node: ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n parts.push('const ')\n parts.push(name)\n parts.push(' = ')\n if (isAsync) parts.push('async ')\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(arrowBody)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link CodeNode} to its TypeScript string representation.\n *\n * Dispatches to the appropriate printer based on the node's `kind`.\n *\n * @example\n * ```ts\n * printCodeNode(createConst({ name: 'x', nodes: ['1'] }))\n * // 'const x = 1'\n * ```\n */\nexport function printCodeNode(node: CodeNode): string {\n if (node.kind === 'Break') return ''\n if (node.kind === 'Text') return dedent((node as TextNode).value)\n if (node.kind === 'Jsx') return dedent((node as JsxNode).value)\n if (node.kind === 'Const') return printConst(node)\n if (node.kind === 'Type') return printType(node)\n if (node.kind === 'Function') return printFunction(node)\n if (node.kind === 'ArrowFunction') return printArrowFunction(node)\n return ''\n}\n\n/**\n * Converts a {@link SourceNode} to its TypeScript string representation.\n *\n * Iterates `nodes` in DOM order, rendering each {@link CodeNode} via\n * {@link printCodeNode}.\n *\n * Top-level declarations are separated by a blank line so the source reads\n * cleanly without an external formatter.\n *\n * @example From nodes\n * ```ts\n * printSource({ kind: 'Source', nodes: [createConst({ name: 'x', nodes: [createText('1')] }), createText('x.toString()')] })\n * // 'const x = 1\\n\\nx.toString()'\n * ```\n */\nexport function printSource(node: SourceNode): string {\n const nodes = node.nodes\n\n if (!nodes || nodes.length === 0) return ''\n\n return nodes\n .map((child) => printCodeNode(child as CodeNode))\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping any embedded backslash or quote so the emitted\n * statement stays valid even for unusual paths.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an import declaration string in the repo style (single quotes, no semicolons), covering\n * default, namespace (`* as`), and named imports with `{ a as b }` aliases, each optionally\n * `type`-only. `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printImport({ name: ['z'], path: './zod.ts' })\n * // \"import { z } from './zod.ts'\"\n * ```\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n isTypeOnly?: boolean | null\n isNameSpace?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (!Array.isArray(name)) {\n if (isNameSpace) return `import ${typePrefix}* as ${name} from ${from}`\n return `import ${typePrefix}${name} from ${from}`\n }\n\n const specifiers = name.map((item) => {\n if (typeof item === 'object') {\n return item.name ? `${item.propertyName} as ${item.name}` : item.propertyName\n }\n return item\n })\n\n return `import ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n}\n\n/**\n * Renders an export declaration string in the repo style (single quotes, no semicolons), covering\n * named re-exports, namespace alias (`* as name`), and wildcard, each optionally `type`-only.\n * `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printExport({ name: ['Pet', 'Order'], path: './models.ts' })\n * // \"export { Pet, Order } from './models.ts'\"\n * ```\n */\nexport function printExport({\n path,\n name,\n isTypeOnly = false,\n asAlias = false,\n}: {\n path: string\n name?: string | Array<ts.Identifier | string> | null\n isTypeOnly?: boolean | null\n asAlias?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n const specifiers = name.map((item) => (typeof item === 'string' ? item : item.text))\n return `export ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n const parsedName = LEADING_DIGIT_PATTERN.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n console.warn(`When using name as string, asAlias should be true: ${name}`)\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import type { FileNode, SourceNode } from '@kubb/ast'\nimport { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath } from './utils.ts'\n\n/**\n * Default Kubb parser for `.ts` and `.js` files. Takes the universal AST\n * produced by an adapter and prints it as TypeScript source using the official\n * TypeScript compiler. Imports and exports are rewritten based on each file's\n * metadata.\n *\n * Used automatically when no `parsers` option is set on `defineConfig`. Use\n * `parserTsx` instead for React projects that emit JSX.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTs } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.ts' }) {\n const sourceParts: Array<string> = []\n for (const item of file.sources) {\n const sourceStr = printSource(item as SourceNode)\n if (sourceStr) {\n sourceParts.push(sourceStr.trimEnd())\n }\n }\n const source = sourceParts.join('\\n\\n')\n\n const importLines: Array<string> = []\n for (const item of (file as FileNode).imports) {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n importLines.push(\n printImport({\n name: item.name as string | Array<string | { propertyName: string; name?: string }>,\n path: resolveOutputPath(importPath, options, Boolean(item.root)),\n isTypeOnly: item.isTypeOnly,\n isNameSpace: item.isNameSpace,\n }),\n )\n }\n\n const exportLines: Array<string> = []\n for (const item of (file as FileNode).exports) {\n exportLines.push(\n printExport({\n name: item.name as string | Array<ts.Identifier | string> | null | undefined,\n path: resolveOutputPath(item.path, options, true),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n }),\n )\n }\n\n const importExportBlock = [...importLines, ...exportLines].join('\\n')\n\n const parts = [file.banner, importExportBlock, source, file.footer].filter((segment): segment is string => Boolean(segment)).map((s) => s.trimEnd())\n return parts.join('\\n\\n')\n },\n})\n","import { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { parserTs } from './parserTs.ts'\nimport { print } from './utils.ts'\n\n/**\n * Kubb parser for `.tsx` and `.jsx` files. Delegates to `parserTs` because the\n * TypeScript compiler handles JSX natively via `ScriptKind.TSX`.\n *\n * Add to the `parsers` array on `defineConfig` when generating components for\n * React (or any framework that emits JSX).\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTsx } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineParser({\n name: 'tsx',\n extNames: ['.tsx', '.jsx'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.tsx' }) {\n return parserTs.parse(file, options)\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,MAAa,SAAA,IAAqB,OAAO,CAAW;;;;;AAMpD,MAAa,yBAAyB;;;;AAKtC,MAAa,yBAAyB;;;;;AAMtC,MAAa,2BAA2B;;;;AAKxC,MAAa,0BAA0B;;;;AAKvC,MAAa,eAAe;;;;;AAM5B,MAAa,wBAAwB;;;AC9BrC,MAAM,EAAE,YAAYA,WAAAA;;;;AAKpB,SAAgB,MAAM,MAAsB;CAC1C,QAAA,GAAA,UAAA,UAAA,CAAiB,IAAI,CAAC,CAAC,WAAW,wBAAwB,GAAG,CAAC,CAAC,QAAA,OAAiC,EAAE;AACpG;;;;;AAMA,SAAgB,gBAAgB,SAAiB,UAA0B;CAEzE,MAAM,UAAU,OAAA,GAAA,UAAA,SAAA,CADK,SAAS,QACN,CAAC;CACzB,OAAO,QAAQ,WAAA,KAAkC,IAAI,UAAU,KAA8B;AAC/F;;;;;AAMA,SAAgB,YAAY,MAAsB;CAChD,OAAO,KAAK,QAAQ,wBAAwB,EAAE;AAChD;;;;;;AAOA,SAAgB,kBAAkB,MAAc,SAA2C,WAA4B;CACrH,MAAM,aAAa,uBAAuB,KAAK,IAAI;CACnD,IAAI,SAAS,WAAW,YACtB,OAAO,GAAG,YAAY,IAAI,IAAI,QAAQ;CAExC,OAAO,YAAY,YAAY,IAAI,IAAI;AACzC;;;;;;;AAQA,SAAgB,WAAW,OAA4C;CACrE,IAAI,CAAC,SAAS,MAAM,WAAW,GAAG,OAAO;CAEzC,IAAI,SAAS;CACb,IAAI,aAAa;CACjB,IAAI,eAAe;CAEnB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,KAAK,SAAS,SAAS;GACzB,IAAI,YAAY,eAAe;GAC/B;EACF;EAEA,MAAM,OAAO,cAAc,IAAI;EAC/B,IAAI,CAAC,MAAM;EAEX,IAAI,YAAY,UAAU,eAAe,SAAS;EAClD,UAAU;EACV,aAAa;EACb,eAAe;CACjB;CAEA,OAAO;AACT;;;;;AAMA,SAAgB,YAAY,MAAc,SAA0B,QAAgB;CAClF,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,MAAM,OAAO,WAAW,WAAW,SAAA,IAAqB,OAAO,MAAM;CAC3E,OAAO,KACJ,MAAM,IAAI,CAAC,CACX,KAAK,SAAU,KAAK,KAAK,IAAI,GAAG,MAAM,SAAS,EAAG,CAAC,CACnD,KAAK,IAAI;AACd;;;;;;;;;;;;;AAcA,SAAgB,OAAO,MAAsB;CAC3C,IAAI,CAAC,MAAM,OAAO;CAElB,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,MAAM,WAAW,SAAiB,KAAK,KAAK,MAAM;CAElD,MAAM,QAAQ,MAAM,WAAW,SAAS,CAAC,QAAQ,IAAI,CAAC;CACtD,IAAI,UAAU,IAAI,OAAO;CACzB,MAAM,MAAM,MAAM,eAAe,SAAS,CAAC,QAAQ,IAAI,CAAC;CAExD,MAAM,UAAU,MAAM,MAAM,OAAO,MAAM,CAAC;CAC1C,MAAM,UAAU,QAAQ,QAAQ,SAAS,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,KAAK,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC;CAC1G,MAAM,MAAM,QAAQ,SAAS,KAAK,IAAI,GAAG,OAAO,IAAI;CAEpD,OAAO,QAAQ,KAAK,SAAU,QAAQ,IAAI,IAAI,KAAK,KAAK,MAAM,GAAG,CAAE,CAAC,CAAC,KAAK,IAAI;AAChF;;;;;AAMA,SAAgB,eAAe,UAA4E;CACzG,IAAI,CAAC,UAAU,OAAO;CACtB,OAAO,IAAI,MAAM,QAAQ,QAAQ,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS;AACtE;;;;;AAMA,SAAgB,iBAAiB,YAAuC,SAA6C;CACnH,IAAI,CAAC,YAAY,OAAO;CACxB,OAAO,UAAU,aAAa,WAAW,KAAK,KAAK;AACrD;;;;;;;AAQA,MAAM,aAAaA,WAAAA,QAAG,cAAc;CAClC,uBAAuB;CACvB,SAASA,WAAAA,QAAG,YAAY;CACxB,gBAAgB;CAChB,eAAe;AACjB,CAAC;;;;;AAMD,MAAM,oBAAoBA,WAAAA,QAAG,iBAAiB,aAAa,IAAIA,WAAAA,QAAG,aAAa,QAAQ,MAAMA,WAAAA,QAAG,WAAW,GAAG;AAK9G,WAAW,UAAUA,WAAAA,QAAG,WAAW,WAAW,QAAQ,gBAAgB,CAAC,CAAC,GAAG,iBAAiB;;;;AAK5F,SAAgB,MAAM,GAAG,UAAkC;CACzD,MAAM,WAAW,SAAS,OAAO,OAAO;CACxC,IAAI,SAAS,WAAW,GAAG,OAAO;CAIlC,OAFe,WAAW,UAAUA,WAAAA,QAAG,WAAW,WAAW,QAAQ,gBAAgB,QAAQ,GAAG,iBAEpF,CAAC,CAAC,QAAQ,cAAc,IAAI;AAC1C;;;;;;;;;;;;;AAcA,SAAgB,WAAW,OAA0B;CACnD,MAAM,YAAY,MAAM,YAAY,CAAC,EAAA,CAAG,QAAQ,MAAM,KAAK,IAAI;CAC/D,IAAI,SAAS,WAAW,GAAG,OAAO;CAElC,MAAM,QAAQ,SACX,SAAS,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAChC,KAAK,MAAM,EAAE,QAAQ,0BAA0B,KAAK,CAAC,CAAC,QAAQ,yBAAyB,EAAE,CAAC,CAAC,CAC3F,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC;CAEpC,IAAI,MAAM,WAAW,GAAG,OAAO;CAE/B,OAAO;EAAC;EAAO,GAAG,MAAM,KAAK,MAAM,MAAM,GAAG;EAAG;CAAK,CAAC,CAAC,KAAK,IAAI;AACjE;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,WAAW,MAAyB;CAClD,MAAM,EAAE,MAAM,QAAQ,WAAW,MAAM,OAAO,SAAS,UAAU;CAEjE,MAAM,WAAW,QAAQ,WAAW,KAAK,IAAI;CAC7C,MAAM,OAAO,WAAW,KAAK;CAE7B,MAAM,QAAuB,CAAC;CAC9B,IAAI,WAAW,MAAM,KAAK,SAAS;CACnC,MAAM,KAAK,QAAQ;CACnB,MAAM,KAAK,IAAI;CACf,IAAI,MACF,MAAM,KAAK,KAAK,MAAM;CAExB,MAAM,KAAK,KAAK;CAChB,MAAM,KAAK,IAAI;CACf,IAAI,SAAS,MAAM,KAAK,WAAW;CAGnC,OAAO,CAAC,UADY,MAAM,KAAK,EACH,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;AAC1D;;;;;;;;;;;;AAaA,SAAgB,UAAU,MAAwB;CAChD,MAAM,EAAE,MAAM,QAAQ,WAAW,OAAO,UAAU;CAElD,MAAM,WAAW,QAAQ,WAAW,KAAK,IAAI;CAC7C,MAAM,OAAO,WAAW,KAAK;CAE7B,MAAM,QAAuB,CAAC;CAC9B,IAAI,WAAW,MAAM,KAAK,SAAS;CACnC,MAAM,KAAK,OAAO;CAClB,MAAM,KAAK,IAAI;CACf,MAAM,KAAK,KAAK;CAChB,MAAM,KAAK,IAAI;CAGf,OAAO,CAAC,UADY,MAAM,KAAK,EACH,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;AAC1D;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,cAAc,MAA4B;CACxD,MAAM,EAAE,MAAM,SAAS,WAAW,QAAQ,WAAW,OAAO,SAAS,UAAU,QAAQ,YAAY,OAAO,UAAU;CAEpH,MAAM,WAAW,QAAQ,WAAW,KAAK,IAAI;CAC7C,MAAM,OAAO,WAAW,KAAK;CAC7B,MAAM,WAAW,OAAO,YAAY,IAAI,IAAI;CAE5C,MAAM,QAAuB,CAAC;CAC9B,IAAI,WAAW,MAAM,KAAK,SAAS;CACnC,IAAI,WAAW,MAAM,KAAK,UAAU;CACpC,IAAI,SAAS,MAAM,KAAK,QAAQ;CAChC,MAAM,KAAK,WAAW;CACtB,MAAM,KAAK,IAAI;CACf,MAAM,KAAK,eAAe,QAAQ,CAAC;CACnC,MAAM,KAAK,IAAI,UAAU,GAAG,EAAE;CAC9B,MAAM,KAAK,iBAAiB,YAAY,OAAO,CAAC;CAChD,MAAM,KAAK,IAAI;CACf,IAAI,UACF,MAAM,KAAK,KAAK,SAAS,GAAG;CAE9B,MAAM,KAAK,GAAG;CAGd,OAAO,CAAC,UADY,MAAM,KAAK,EACH,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;AAC1D;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,mBAAmB,MAAiC;CAClE,MAAM,EAAE,MAAM,SAAS,WAAW,QAAQ,WAAW,OAAO,SAAS,UAAU,QAAQ,YAAY,OAAO,OAAO,eAAe;CAEhI,MAAM,WAAW,QAAQ,WAAW,KAAK,IAAI;CAC7C,MAAM,OAAO,WAAW,KAAK;CAC7B,MAAM,YAAY,aAAa,OAAO,SAAS,OAAO,UAAU,YAAY,IAAI,EAAE,OAAO;CAEzF,MAAM,QAAuB,CAAC;CAC9B,IAAI,WAAW,MAAM,KAAK,SAAS;CACnC,IAAI,WAAW,MAAM,KAAK,UAAU;CACpC,MAAM,KAAK,QAAQ;CACnB,MAAM,KAAK,IAAI;CACf,MAAM,KAAK,KAAK;CAChB,IAAI,SAAS,MAAM,KAAK,QAAQ;CAChC,MAAM,KAAK,eAAe,QAAQ,CAAC;CACnC,MAAM,KAAK,IAAI,UAAU,GAAG,EAAE;CAC9B,MAAM,KAAK,iBAAiB,YAAY,OAAO,CAAC;CAChD,MAAM,KAAK,SAAS;CAGpB,OAAO,CAAC,UADY,MAAM,KAAK,EACH,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;AAC1D;;;;;;;;;;;;AAaA,SAAgB,cAAc,MAAwB;CACpD,IAAI,KAAK,SAAS,SAAS,OAAO;CAClC,IAAI,KAAK,SAAS,QAAQ,OAAO,OAAQ,KAAkB,KAAK;CAChE,IAAI,KAAK,SAAS,OAAO,OAAO,OAAQ,KAAiB,KAAK;CAC9D,IAAI,KAAK,SAAS,SAAS,OAAO,WAAW,IAAI;CACjD,IAAI,KAAK,SAAS,QAAQ,OAAO,UAAU,IAAI;CAC/C,IAAI,KAAK,SAAS,YAAY,OAAO,cAAc,IAAI;CACvD,IAAI,KAAK,SAAS,iBAAiB,OAAO,mBAAmB,IAAI;CACjE,OAAO;AACT;;;;;;;;;;;;;;;;AAiBA,SAAgB,YAAY,MAA0B;CACpD,MAAM,QAAQ,KAAK;CAEnB,IAAI,CAAC,SAAS,MAAM,WAAW,GAAG,OAAO;CAEzC,OAAO,MACJ,KAAK,UAAU,cAAc,KAAiB,CAAC,CAAC,CAChD,OAAO,OAAO,CAAC,CACf,KAAK,MAAM;AAChB;;;;;AAMA,SAAS,gBAAgB,MAAsB;CAC7C,OAAO,IAAI,KAAK,QAAQ,OAAO,MAAM,CAAC,CAAC,QAAQ,MAAM,KAAK,EAAE;AAC9D;;;;;;;;;;;;AAaA,SAAgB,YAAY,EAC1B,MACA,MACA,aAAa,OACb,cAAc,SAML;CACT,MAAM,aAAa,aAAa,UAAU;CAC1C,MAAM,OAAO,gBAAgB,IAAI;CAEjC,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;EACxB,IAAI,aAAa,OAAO,UAAU,WAAW,OAAO,KAAK,QAAQ;EACjE,OAAO,UAAU,aAAa,KAAK,QAAQ;CAC7C;CASA,OAAO,UAAU,WAAW,IAPT,KAAK,KAAK,SAAS;EACpC,IAAI,OAAO,SAAS,UAClB,OAAO,KAAK,OAAO,GAAG,KAAK,aAAa,MAAM,KAAK,SAAS,KAAK;EAEnE,OAAO;CACT,CAEyC,CAAC,CAAC,KAAK,IAAI,EAAE,UAAU;AAClE;;;;;;;;;;;;AAaA,SAAgB,YAAY,EAC1B,MACA,MACA,aAAa,OACb,UAAU,SAMD;CACT,MAAM,aAAa,aAAa,UAAU;CAC1C,MAAM,OAAO,gBAAgB,IAAI;CAEjC,IAAI,MAAM,QAAQ,IAAI,GAEpB,OAAO,UAAU,WAAW,IADT,KAAK,KAAK,SAAU,OAAO,SAAS,WAAW,OAAO,KAAK,IACrC,CAAC,CAAC,KAAK,IAAI,EAAE,UAAU;CAGlE,IAAI,WAAW,MAEb,OAAO,UAAU,WAAW,OADT,sBAAsB,KAAK,IAAI,IAAI,IAAI,KAAK,MAAM,CAAC,MAAM,KAC9B,QAAQ;CAGxD,IAAI,MACF,QAAQ,KAAK,sDAAsD,MAAM;CAG3E,OAAO,UAAU,WAAW,SAAS;AACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjdA,MAAa,YAAA,GAAA,WAAA,aAAA,CAAwB;CACnC,MAAM;CACN,UAAU,CAAC,OAAO,KAAK;CACvB,MAAM,GAAG,OAAuB;EAC9B,OAAO,MAAM,GAAG,KAAK;CACvB;CACA,MAAM,MAAM,UAAU,EAAE,SAAS,MAAM,GAAG;EACxC,MAAM,cAA6B,CAAC;EACpC,KAAK,MAAM,QAAQ,KAAK,SAAS;GAC/B,MAAM,YAAY,YAAY,IAAkB;GAChD,IAAI,WACF,YAAY,KAAK,UAAU,QAAQ,CAAC;EAExC;EACA,MAAM,SAAS,YAAY,KAAK,MAAM;EAEtC,MAAM,cAA6B,CAAC;EACpC,KAAK,MAAM,QAAS,KAAkB,SAAS;GAC7C,MAAM,aAAa,KAAK,OAAO,gBAAgB,KAAK,MAAM,KAAK,IAAI,IAAI,KAAK;GAC5E,YAAY,KACV,YAAY;IACV,MAAM,KAAK;IACX,MAAM,kBAAkB,YAAY,SAAS,QAAQ,KAAK,IAAI,CAAC;IAC/D,YAAY,KAAK;IACjB,aAAa,KAAK;GACpB,CAAC,CACH;EACF;EAEA,MAAM,cAA6B,CAAC;EACpC,KAAK,MAAM,QAAS,KAAkB,SACpC,YAAY,KACV,YAAY;GACV,MAAM,KAAK;GACX,MAAM,kBAAkB,KAAK,MAAM,SAAS,IAAI;GAChD,YAAY,KAAK;GACjB,SAAS,KAAK;EAChB,CAAC,CACH;EAGF,MAAM,oBAAoB,CAAC,GAAG,aAAa,GAAG,WAAW,CAAC,CAAC,KAAK,IAAI;EAGpE,OADc;GAAC,KAAK;GAAQ;GAAmB;GAAQ,KAAK;EAAM,CAAC,CAAC,QAAQ,YAA+B,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,QAAQ,CACvI,CAAC,CAAC,KAAK,MAAM;CAC1B;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;AChDD,MAAa,aAAA,GAAA,WAAA,aAAA,CAAyB;CACpC,MAAM;CACN,UAAU,CAAC,QAAQ,MAAM;CACzB,MAAM,GAAG,OAAuB;EAC9B,OAAO,MAAM,GAAG,KAAK;CACvB;CACA,MAAM,MAAM,UAAU,EAAE,SAAS,OAAO,GAAG;EACzC,OAAO,SAAS,MAAM,MAAM,OAAO;CACrC;AACF,CAAC"}
{"version":3,"file":"index.cjs","names":["ts"],"sources":["../../../internals/utils/src/fs.ts","../src/constants.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["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","/**\n * Character used for a single indent step. Set to `'\\t'` to emit tab-indented output.\n */\nexport const INDENT_CHAR = ' '\n\n/**\n * Number of {@link INDENT_CHAR} repeats that make up one nesting level.\n */\nconst INDENT_SIZE = 2 as const\n\n/**\n * Indentation unit prepended once per nesting level when pretty-printing.\n */\nexport const INDENT = INDENT_CHAR.repeat(INDENT_SIZE)\n\n/**\n * Matches the trailing `.<ext>` segment of a path (keeps segments like `foo.bar.ts`\n * intact by only trimming the last run of non-`/`/`.` characters).\n */\nexport const FILE_EXTENSION_PATTERN = /\\.[^/.]+$/\n\n/**\n * Matches Windows-style backslash path separators.\n */\nexport const WINDOWS_PATH_SEPARATOR = /\\\\/g\n\n/**\n * Matches `*\\/` in free-form text so JSDoc bodies can neutralize premature\n * comment terminators (`*\\/` → `* /`).\n */\nexport const JSDOC_TERMINATOR_PATTERN = /\\*\\//g\n\n/**\n * Matches carriage returns for normalizing CRLF/CR line endings to LF.\n */\nexport const CARRIAGE_RETURN_PATTERN = /\\r/g\n\n/**\n * Matches CRLF sequences used when normalizing TypeScript printer output.\n */\nexport const CRLF_PATTERN = /\\r\\n/g\n\n/**\n * Matches an identifier that starts with a digit. JavaScript disallows this,\n * so the printer prefixes such names with `_`.\n */\nexport const LEADING_DIGIT_PATTERN = /^\\d/\n\n/**\n * Relative path prefix used to detect traversal segments (`../`).\n */\nexport const PARENT_DIRECTORY_PREFIX = '../' as const\n\n/**\n * Relative path prefix used when resolving imports within the output root.\n */\nexport const CURRENT_DIRECTORY_PREFIX = './' as const\n","import { normalize, relative } from 'node:path'\nimport { trimExtName } from '@internals/utils'\nimport type { ArrowFunctionNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, SourceNode, TextNode, TypeNode } from '@kubb/ast'\nimport ts from 'typescript'\nimport {\n CARRIAGE_RETURN_PATTERN,\n CRLF_PATTERN,\n CURRENT_DIRECTORY_PREFIX,\n FILE_EXTENSION_PATTERN,\n INDENT,\n INDENT_CHAR,\n JSDOC_TERMINATOR_PATTERN,\n LEADING_DIGIT_PATTERN,\n PARENT_DIRECTORY_PREFIX,\n WINDOWS_PATH_SEPARATOR,\n} from './constants.ts'\n\nconst { factory } = ts\n\n/**\n * Normalizes a file-system path to POSIX separators and strips any leading `../` segment.\n */\nexport function slash(path: string): string {\n return normalize(path).replaceAll(WINDOWS_PATH_SEPARATOR, '/').replace(PARENT_DIRECTORY_PREFIX, '')\n}\n\n/**\n * Resolves `filePath` relative to `rootDir` and returns a POSIX-style path\n * prefixed with `./` when the target sits inside the root, or `../` when it escapes it.\n */\nexport function getRelativePath(rootDir: string, filePath: string): string {\n const rel = relative(rootDir, filePath)\n const slashed = slash(rel)\n return slashed.startsWith(PARENT_DIRECTORY_PREFIX) ? slashed : `${CURRENT_DIRECTORY_PREFIX}${slashed}`\n}\n\n/**\n * Rewrites an import/export path so its extension matches the caller-supplied\n * `options.extname`. When the source path has no extension the original is kept,\n * so virtual/module-only paths flow through unchanged.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = FILE_EXTENSION_PATTERN.test(path)\n if (options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Serializes a `nodes` array into source text. Each entry is rendered via {@link printCodeNode}\n * and joined with a single newline; a `Break` node (`<br/>`) inserts one blank line between\n * statements. Consecutive breaks, and breaks at the very start or end, are folded into the\n * separator, so a double `<br/>` never emits more than one blank line.\n */\nexport function printNodes(nodes: Array<CodeNode> | undefined): string {\n if (!nodes || nodes.length === 0) return ''\n\n let result = ''\n let hasContent = false\n let pendingBreak = false\n\n for (const node of nodes) {\n if (node.kind === 'Break') {\n if (hasContent) pendingBreak = true\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (hasContent) result += pendingBreak ? '\\n\\n' : '\\n'\n result += text\n hasContent = true\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by one indent unit. Pass a number to repeat\n * {@link INDENT_CHAR} that many times, or a string to use as the indent verbatim.\n */\nexport function indentLines(text: string, indent: number | string = INDENT): string {\n if (!text) return ''\n const pad = typeof indent === 'string' ? indent : INDENT_CHAR.repeat(indent)\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Removes the common leading whitespace shared by every non-blank line and trims\n * surrounding blank lines, normalizing multi-line content authored inside an\n * indented template literal back to a column-zero baseline. Leading whitespace is\n * counted by character, so N tabs and N spaces are treated as the same depth.\n *\n * @example\n * ```ts\n * dedent('\\n foo\\n bar\\n ')\n * // 'foo\\n bar'\n * ```\n */\nexport function dedent(text: string): string {\n if (!text) return ''\n\n const lines = text.split('\\n')\n const isBlank = (line: string) => line.trim() === ''\n\n const start = lines.findIndex((line) => !isBlank(line))\n if (start === -1) return ''\n const end = lines.findLastIndex((line) => !isBlank(line))\n\n const trimmed = lines.slice(start, end + 1)\n const indents = trimmed.filter((line) => !isBlank(line)).map((line) => line.match(/^\\s*/)?.[0].length ?? 0)\n const min = indents.length ? Math.min(...indents) : 0\n\n return trimmed.map((line) => (isBlank(line) ? '' : line.slice(min))).join('\\n')\n}\n\n/**\n * Renders the generic clause (`<T, U>`) shared by function and arrow-function nodes.\n * Accepts either a raw string (rendered verbatim) or an array of type-parameter names.\n */\nexport function formatGenerics(generics: FunctionNode['generics'] | ArrowFunctionNode['generics']): string {\n if (!generics) return ''\n return `<${Array.isArray(generics) ? generics.join(', ') : generics}>`\n}\n\n/**\n * Renders the return-type suffix (`: T` or `: Promise<T>` when `isAsync` is true).\n * Returns an empty string when no return type is provided.\n */\nexport function formatReturnType(returnType: string | null | undefined, isAsync: boolean | null | undefined): string {\n if (!returnType) return ''\n return isAsync ? `: Promise<${returnType}>` : `: ${returnType}`\n}\n\n/**\n * Module-scoped TypeScript printer instance. `ts.createPrinter()` is stateless across calls\n * (it does not mutate the source file) so a single instance can be safely reused for every\n * `print()` call. Hoisting it out of `print()` avoids re-running the printer initialization\n * for each file's import/export section.\n */\nconst TS_PRINTER = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n})\n\n/**\n * Module-scoped source file used as the print target. `printList` only reads the source\n * file's compiler options / language version. It never mutates it.\n */\nconst PRINT_SOURCE_FILE = ts.createSourceFile('print.tsx', '', ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX)\n\n// Pre-warm the printer at module load. The first `printList` call lazily initializes\n// the printer's internal string-builder and identifier tables. Doing it once at import\n// time keeps that cost off the critical path for short-lived CLI builds.\nTS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray([]), PRINT_SOURCE_FILE)\n\n/**\n * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.\n */\nexport function print(...elements: Array<ts.Node>): string {\n const filtered = elements.filter(Boolean)\n if (filtered.length === 0) return ''\n\n const output = TS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray(filtered), PRINT_SOURCE_FILE)\n\n return output.replace(CRLF_PATTERN, '\\n')\n}\n\n/**\n * Converts a {@link JSDocNode} to a JSDoc comment block string.\n *\n * @example\n * ```ts\n * printJSDoc({ comments: ['@description A pet', '@deprecated'] })\n * // /**\n * // * @description A pet\n * // * @deprecated\n * // *\\/\n * ```\n */\nexport function printJSDoc(jsDoc: JSDocNode): string {\n const comments = (jsDoc.comments ?? []).filter((c) => c != null)\n if (comments.length === 0) return ''\n\n const lines = comments\n .flatMap((c) => c.split(/\\r?\\n/))\n .map((l) => l.replace(JSDOC_TERMINATOR_PATTERN, '* /').replace(CARRIAGE_RETURN_PATTERN, ''))\n .filter((l) => l.trim().length > 0)\n\n if (lines.length === 0) return ''\n\n return ['/**', ...lines.map((l) => ` * ${l}`), ' */'].join('\\n')\n}\n\n/**\n * Converts a {@link ConstNode} to a TypeScript `const` declaration string.\n *\n * Mirrors the `Const` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printConst(createConst({ name: 'pet', export: true, nodes: ['{}'] }))\n * // 'export const pet = {}'\n * ```\n *\n * @example With type and `as const`\n * ```ts\n * printConst(createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true, nodes: ['[]'] }))\n * // 'export const pets: Pet[] = [] as const'\n * ```\n */\nexport function printConst(node: ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('const ')\n parts.push(name)\n if (type) {\n parts.push(`: ${type}`)\n }\n parts.push(' = ')\n parts.push(body)\n if (asConst) parts.push(' as const')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link TypeNode} to a TypeScript `type` alias declaration string.\n *\n * Mirrors the `Type` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printType(createType({ name: 'Pet', export: true, nodes: ['{ id: number }'] }))\n * // 'export type Pet = { id: number }'\n * ```\n */\nexport function printType(node: TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('type ')\n parts.push(name)\n parts.push(' = ')\n parts.push(body)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link FunctionNode} to a TypeScript `function` declaration string.\n *\n * Mirrors the `Function` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printFunction(createFunction({ name: 'getPet', export: true, params: 'id: string', returnType: 'Pet', nodes: ['return fetch(id)'] }))\n * // 'export function getPet(id: string): Pet {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Async with generics\n * ```ts\n * printFunction(createFunction({ name: 'fetchPet', export: true, async: true, generics: ['T'], params: 'id: string', returnType: 'T' }))\n * // 'export async function fetchPet<T>(id: string): Promise<T> {\\n}'\n * ```\n */\nexport function printFunction(node: FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const indented = body ? indentLines(body) : ''\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n if (isAsync) parts.push('async ')\n parts.push('function ')\n parts.push(name)\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(' {')\n if (indented) {\n parts.push(`\\n${indented}\\n`)\n }\n parts.push('}')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts an {@link ArrowFunctionNode} to a TypeScript arrow function declaration string.\n *\n * Mirrors the `Function.Arrow` component from `@kubb/renderer-jsx`.\n *\n * @example Multi-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'getPet', export: true, params: 'id: string', nodes: ['return fetch(id)'] }))\n * // 'export const getPet = (id: string) => {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Single-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'double', params: 'n: number', singleLine: true, nodes: ['n * 2'] }))\n * // 'const double = (n: number) => n * 2'\n * ```\n */\nexport function printArrowFunction(node: ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n parts.push('const ')\n parts.push(name)\n parts.push(' = ')\n if (isAsync) parts.push('async ')\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(arrowBody)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link CodeNode} to its TypeScript string representation.\n *\n * Dispatches to the appropriate printer based on the node's `kind`.\n *\n * @example\n * ```ts\n * printCodeNode(createConst({ name: 'x', nodes: ['1'] }))\n * // 'const x = 1'\n * ```\n */\nexport function printCodeNode(node: CodeNode): string {\n if (node.kind === 'Break') return ''\n if (node.kind === 'Text') return dedent((node as TextNode).value)\n if (node.kind === 'Jsx') return dedent((node as JsxNode).value)\n if (node.kind === 'Const') return printConst(node)\n if (node.kind === 'Type') return printType(node)\n if (node.kind === 'Function') return printFunction(node)\n if (node.kind === 'ArrowFunction') return printArrowFunction(node)\n return ''\n}\n\n/**\n * Converts a {@link SourceNode} to its TypeScript string representation.\n *\n * Iterates `nodes` in DOM order, rendering each {@link CodeNode} via\n * {@link printCodeNode}.\n *\n * Top-level declarations are separated by a blank line so the source reads\n * cleanly without an external formatter.\n *\n * @example From nodes\n * ```ts\n * printSource({ kind: 'Source', nodes: [createConst({ name: 'x', nodes: [createText('1')] }), createText('x.toString()')] })\n * // 'const x = 1\\n\\nx.toString()'\n * ```\n */\nexport function printSource(node: SourceNode): string {\n const nodes = node.nodes\n\n if (!nodes || nodes.length === 0) return ''\n\n return nodes\n .map((child) => printCodeNode(child as CodeNode))\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping any embedded backslash or quote so the emitted\n * statement stays valid even for unusual paths.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an import declaration string in the repo style (single quotes, no semicolons), covering\n * default, namespace (`* as`), and named imports with `{ a as b }` aliases, each optionally\n * `type`-only. `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printImport({ name: ['z'], path: './zod.ts' })\n * // \"import { z } from './zod.ts'\"\n * ```\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n isTypeOnly?: boolean | null\n isNameSpace?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (!Array.isArray(name)) {\n if (isNameSpace) return `import ${typePrefix}* as ${name} from ${from}`\n return `import ${typePrefix}${name} from ${from}`\n }\n\n const specifiers = name.map((item) => {\n if (typeof item === 'object') {\n return item.name ? `${item.propertyName} as ${item.name}` : item.propertyName\n }\n return item\n })\n\n return `import ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n}\n\n/**\n * Renders an export declaration string in the repo style (single quotes, no semicolons), covering\n * named re-exports, namespace alias (`* as name`), and wildcard, each optionally `type`-only.\n * `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printExport({ name: ['Pet', 'Order'], path: './models.ts' })\n * // \"export { Pet, Order } from './models.ts'\"\n * ```\n */\nexport function printExport({\n path,\n name,\n isTypeOnly = false,\n asAlias = false,\n}: {\n path: string\n name?: string | Array<ts.Identifier | string> | null\n isTypeOnly?: boolean | null\n asAlias?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n const specifiers = name.map((item) => (typeof item === 'string' ? item : item.text))\n return `export ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n const parsedName = LEADING_DIGIT_PATTERN.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n console.warn(`When using name as string, asAlias should be true: ${name}`)\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import type { FileNode, SourceNode } from '@kubb/ast'\nimport { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath } from './utils.ts'\n\n/**\n * Default Kubb parser for `.ts` and `.js` files. Takes the universal AST\n * produced by an adapter and prints it as TypeScript source using the official\n * TypeScript compiler. Imports and exports are rewritten based on each file's\n * metadata.\n *\n * Used automatically when no `parsers` option is set on `defineConfig`. Use\n * `parserTsx` instead for React projects that emit JSX.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTs } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.ts' }) {\n const sourceParts: Array<string> = []\n for (const item of file.sources) {\n const sourceStr = printSource(item as SourceNode)\n if (sourceStr) {\n sourceParts.push(sourceStr.trimEnd())\n }\n }\n const source = sourceParts.join('\\n\\n')\n\n const importLines: Array<string> = []\n for (const item of (file as FileNode).imports) {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n importLines.push(\n printImport({\n name: item.name as string | Array<string | { propertyName: string; name?: string }>,\n path: resolveOutputPath(importPath, options, Boolean(item.root)),\n isTypeOnly: item.isTypeOnly,\n isNameSpace: item.isNameSpace,\n }),\n )\n }\n\n const exportLines: Array<string> = []\n for (const item of (file as FileNode).exports) {\n exportLines.push(\n printExport({\n name: item.name as string | Array<ts.Identifier | string> | null | undefined,\n path: resolveOutputPath(item.path, options, true),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n }),\n )\n }\n\n const importExportBlock = [...importLines, ...exportLines].join('\\n')\n\n const parts = [file.banner, importExportBlock, source, file.footer].filter((segment): segment is string => Boolean(segment)).map((s) => s.trimEnd())\n\n return parts.join('\\n\\n')\n },\n})\n","import { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { parserTs } from './parserTs.ts'\nimport { print } from './utils.ts'\n\n/**\n * Kubb parser for `.tsx` and `.jsx` files. Delegates to `parserTs` because the\n * TypeScript compiler handles JSX natively via `ScriptKind.TSX`.\n *\n * Add to the `parsers` array on `defineConfig` when generating components for\n * React (or any framework that emits JSX).\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTsx } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineParser({\n name: 'tsx',\n extNames: ['.tsx', '.jsx'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.tsx' }) {\n return parserTs.parse(file, options)\n },\n})\n"],"mappings":"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"}

@@ -5,3 +5,19 @@ import "./chunk-C0LytTxp.js";

import ts from "typescript";
//#region ../../internals/utils/src/fs.ts
/**
* Strips the file extension from a path or file name.
* Only removes the last `.ext` segment when the dot is not part of a directory name.
*
* @example
* trimExtName('petStore.ts') // 'petStore'
* trimExtName('/src/models/pet.ts') // '/src/models/pet'
* trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
* trimExtName('noExtension') // 'noExtension'
*/
function trimExtName(text) {
const dotIndex = text.lastIndexOf(".");
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
return text;
}
/**
* Indentation unit prepended once per nesting level when pretty-printing.

@@ -55,9 +71,2 @@ */

/**
* Strips the trailing file extension (for example `.ts`) from a path.
* Preserves intermediate dots like `foo.bar.ts` → `foo.bar`.
*/
function trimExtName(text) {
return text.replace(FILE_EXTENSION_PATTERN, "");
}
/**
* Rewrites an import/export path so its extension matches the caller-supplied

@@ -64,0 +73,0 @@ * `options.extname`. When the source path has no extension the original is kept,

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["/**\n * Character used for a single indent step. Set to `'\\t'` to emit tab-indented output.\n */\nexport const INDENT_CHAR = ' '\n\n/**\n * Number of {@link INDENT_CHAR} repeats that make up one nesting level.\n */\nconst INDENT_SIZE = 2 as const\n\n/**\n * Indentation unit prepended once per nesting level when pretty-printing.\n */\nexport const INDENT = INDENT_CHAR.repeat(INDENT_SIZE)\n\n/**\n * Matches the trailing `.<ext>` segment of a path (keeps segments like `foo.bar.ts`\n * intact by only trimming the last run of non-`/`/`.` characters).\n */\nexport const FILE_EXTENSION_PATTERN = /\\.[^/.]+$/\n\n/**\n * Matches Windows-style backslash path separators.\n */\nexport const WINDOWS_PATH_SEPARATOR = /\\\\/g\n\n/**\n * Matches `*\\/` in free-form text so JSDoc bodies can neutralize premature\n * comment terminators (`*\\/` → `* /`).\n */\nexport const JSDOC_TERMINATOR_PATTERN = /\\*\\//g\n\n/**\n * Matches carriage returns for normalizing CRLF/CR line endings to LF.\n */\nexport const CARRIAGE_RETURN_PATTERN = /\\r/g\n\n/**\n * Matches CRLF sequences used when normalizing TypeScript printer output.\n */\nexport const CRLF_PATTERN = /\\r\\n/g\n\n/**\n * Matches an identifier that starts with a digit. JavaScript disallows this,\n * so the printer prefixes such names with `_`.\n */\nexport const LEADING_DIGIT_PATTERN = /^\\d/\n\n/**\n * Relative path prefix used to detect traversal segments (`../`).\n */\nexport const PARENT_DIRECTORY_PREFIX = '../' as const\n\n/**\n * Relative path prefix used when resolving imports within the output root.\n */\nexport const CURRENT_DIRECTORY_PREFIX = './' as const\n","import { normalize, relative } from 'node:path'\nimport type { ArrowFunctionNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, SourceNode, TextNode, TypeNode } from '@kubb/ast'\nimport ts from 'typescript'\nimport {\n CARRIAGE_RETURN_PATTERN,\n CRLF_PATTERN,\n CURRENT_DIRECTORY_PREFIX,\n FILE_EXTENSION_PATTERN,\n INDENT,\n INDENT_CHAR,\n JSDOC_TERMINATOR_PATTERN,\n LEADING_DIGIT_PATTERN,\n PARENT_DIRECTORY_PREFIX,\n WINDOWS_PATH_SEPARATOR,\n} from './constants.ts'\n\nconst { factory } = ts\n\n/**\n * Normalizes a file-system path to POSIX separators and strips any leading `../` segment.\n */\nexport function slash(path: string): string {\n return normalize(path).replaceAll(WINDOWS_PATH_SEPARATOR, '/').replace(PARENT_DIRECTORY_PREFIX, '')\n}\n\n/**\n * Resolves `filePath` relative to `rootDir` and returns a POSIX-style path\n * prefixed with `./` when the target sits inside the root, or `../` when it escapes it.\n */\nexport function getRelativePath(rootDir: string, filePath: string): string {\n const rel = relative(rootDir, filePath)\n const slashed = slash(rel)\n return slashed.startsWith(PARENT_DIRECTORY_PREFIX) ? slashed : `${CURRENT_DIRECTORY_PREFIX}${slashed}`\n}\n\n/**\n * Strips the trailing file extension (for example `.ts`) from a path.\n * Preserves intermediate dots like `foo.bar.ts` → `foo.bar`.\n */\nexport function trimExtName(text: string): string {\n return text.replace(FILE_EXTENSION_PATTERN, '')\n}\n\n/**\n * Rewrites an import/export path so its extension matches the caller-supplied\n * `options.extname`. When the source path has no extension the original is kept,\n * so virtual/module-only paths flow through unchanged.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = FILE_EXTENSION_PATTERN.test(path)\n if (options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Serializes a `nodes` array into source text. Each entry is rendered via {@link printCodeNode}\n * and joined with a single newline; a `Break` node (`<br/>`) inserts one blank line between\n * statements. Consecutive breaks, and breaks at the very start or end, are folded into the\n * separator, so a double `<br/>` never emits more than one blank line.\n */\nexport function printNodes(nodes: Array<CodeNode> | undefined): string {\n if (!nodes || nodes.length === 0) return ''\n\n let result = ''\n let hasContent = false\n let pendingBreak = false\n\n for (const node of nodes) {\n if (node.kind === 'Break') {\n if (hasContent) pendingBreak = true\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (hasContent) result += pendingBreak ? '\\n\\n' : '\\n'\n result += text\n hasContent = true\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by one indent unit. Pass a number to repeat\n * {@link INDENT_CHAR} that many times, or a string to use as the indent verbatim.\n */\nexport function indentLines(text: string, indent: number | string = INDENT): string {\n if (!text) return ''\n const pad = typeof indent === 'string' ? indent : INDENT_CHAR.repeat(indent)\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Removes the common leading whitespace shared by every non-blank line and trims\n * surrounding blank lines, normalizing multi-line content authored inside an\n * indented template literal back to a column-zero baseline. Leading whitespace is\n * counted by character, so N tabs and N spaces are treated as the same depth.\n *\n * @example\n * ```ts\n * dedent('\\n foo\\n bar\\n ')\n * // 'foo\\n bar'\n * ```\n */\nexport function dedent(text: string): string {\n if (!text) return ''\n\n const lines = text.split('\\n')\n const isBlank = (line: string) => line.trim() === ''\n\n const start = lines.findIndex((line) => !isBlank(line))\n if (start === -1) return ''\n const end = lines.findLastIndex((line) => !isBlank(line))\n\n const trimmed = lines.slice(start, end + 1)\n const indents = trimmed.filter((line) => !isBlank(line)).map((line) => line.match(/^\\s*/)?.[0].length ?? 0)\n const min = indents.length ? Math.min(...indents) : 0\n\n return trimmed.map((line) => (isBlank(line) ? '' : line.slice(min))).join('\\n')\n}\n\n/**\n * Renders the generic clause (`<T, U>`) shared by function and arrow-function nodes.\n * Accepts either a raw string (rendered verbatim) or an array of type-parameter names.\n */\nexport function formatGenerics(generics: FunctionNode['generics'] | ArrowFunctionNode['generics']): string {\n if (!generics) return ''\n return `<${Array.isArray(generics) ? generics.join(', ') : generics}>`\n}\n\n/**\n * Renders the return-type suffix (`: T` or `: Promise<T>` when `isAsync` is true).\n * Returns an empty string when no return type is provided.\n */\nexport function formatReturnType(returnType: string | null | undefined, isAsync: boolean | null | undefined): string {\n if (!returnType) return ''\n return isAsync ? `: Promise<${returnType}>` : `: ${returnType}`\n}\n\n/**\n * Module-scoped TypeScript printer instance. `ts.createPrinter()` is stateless across calls\n * (it does not mutate the source file) so a single instance can be safely reused for every\n * `print()` call. Hoisting it out of `print()` avoids re-running the printer initialization\n * for each file's import/export section.\n */\nconst TS_PRINTER = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n})\n\n/**\n * Module-scoped source file used as the print target. `printList` only reads the source\n * file's compiler options / language version. It never mutates it.\n */\nconst PRINT_SOURCE_FILE = ts.createSourceFile('print.tsx', '', ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX)\n\n// Pre-warm the printer at module load. The first `printList` call lazily initializes\n// the printer's internal string-builder and identifier tables. Doing it once at import\n// time keeps that cost off the critical path for short-lived CLI builds.\nTS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray([]), PRINT_SOURCE_FILE)\n\n/**\n * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.\n */\nexport function print(...elements: Array<ts.Node>): string {\n const filtered = elements.filter(Boolean)\n if (filtered.length === 0) return ''\n\n const output = TS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray(filtered), PRINT_SOURCE_FILE)\n\n return output.replace(CRLF_PATTERN, '\\n')\n}\n\n/**\n * Converts a {@link JSDocNode} to a JSDoc comment block string.\n *\n * @example\n * ```ts\n * printJSDoc({ comments: ['@description A pet', '@deprecated'] })\n * // /**\n * // * @description A pet\n * // * @deprecated\n * // *\\/\n * ```\n */\nexport function printJSDoc(jsDoc: JSDocNode): string {\n const comments = (jsDoc.comments ?? []).filter((c) => c != null)\n if (comments.length === 0) return ''\n\n const lines = comments\n .flatMap((c) => c.split(/\\r?\\n/))\n .map((l) => l.replace(JSDOC_TERMINATOR_PATTERN, '* /').replace(CARRIAGE_RETURN_PATTERN, ''))\n .filter((l) => l.trim().length > 0)\n\n if (lines.length === 0) return ''\n\n return ['/**', ...lines.map((l) => ` * ${l}`), ' */'].join('\\n')\n}\n\n/**\n * Converts a {@link ConstNode} to a TypeScript `const` declaration string.\n *\n * Mirrors the `Const` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printConst(createConst({ name: 'pet', export: true, nodes: ['{}'] }))\n * // 'export const pet = {}'\n * ```\n *\n * @example With type and `as const`\n * ```ts\n * printConst(createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true, nodes: ['[]'] }))\n * // 'export const pets: Pet[] = [] as const'\n * ```\n */\nexport function printConst(node: ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('const ')\n parts.push(name)\n if (type) {\n parts.push(`: ${type}`)\n }\n parts.push(' = ')\n parts.push(body)\n if (asConst) parts.push(' as const')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link TypeNode} to a TypeScript `type` alias declaration string.\n *\n * Mirrors the `Type` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printType(createType({ name: 'Pet', export: true, nodes: ['{ id: number }'] }))\n * // 'export type Pet = { id: number }'\n * ```\n */\nexport function printType(node: TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('type ')\n parts.push(name)\n parts.push(' = ')\n parts.push(body)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link FunctionNode} to a TypeScript `function` declaration string.\n *\n * Mirrors the `Function` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printFunction(createFunction({ name: 'getPet', export: true, params: 'id: string', returnType: 'Pet', nodes: ['return fetch(id)'] }))\n * // 'export function getPet(id: string): Pet {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Async with generics\n * ```ts\n * printFunction(createFunction({ name: 'fetchPet', export: true, async: true, generics: ['T'], params: 'id: string', returnType: 'T' }))\n * // 'export async function fetchPet<T>(id: string): Promise<T> {\\n}'\n * ```\n */\nexport function printFunction(node: FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const indented = body ? indentLines(body) : ''\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n if (isAsync) parts.push('async ')\n parts.push('function ')\n parts.push(name)\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(' {')\n if (indented) {\n parts.push(`\\n${indented}\\n`)\n }\n parts.push('}')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts an {@link ArrowFunctionNode} to a TypeScript arrow function declaration string.\n *\n * Mirrors the `Function.Arrow` component from `@kubb/renderer-jsx`.\n *\n * @example Multi-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'getPet', export: true, params: 'id: string', nodes: ['return fetch(id)'] }))\n * // 'export const getPet = (id: string) => {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Single-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'double', params: 'n: number', singleLine: true, nodes: ['n * 2'] }))\n * // 'const double = (n: number) => n * 2'\n * ```\n */\nexport function printArrowFunction(node: ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n parts.push('const ')\n parts.push(name)\n parts.push(' = ')\n if (isAsync) parts.push('async ')\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(arrowBody)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link CodeNode} to its TypeScript string representation.\n *\n * Dispatches to the appropriate printer based on the node's `kind`.\n *\n * @example\n * ```ts\n * printCodeNode(createConst({ name: 'x', nodes: ['1'] }))\n * // 'const x = 1'\n * ```\n */\nexport function printCodeNode(node: CodeNode): string {\n if (node.kind === 'Break') return ''\n if (node.kind === 'Text') return dedent((node as TextNode).value)\n if (node.kind === 'Jsx') return dedent((node as JsxNode).value)\n if (node.kind === 'Const') return printConst(node)\n if (node.kind === 'Type') return printType(node)\n if (node.kind === 'Function') return printFunction(node)\n if (node.kind === 'ArrowFunction') return printArrowFunction(node)\n return ''\n}\n\n/**\n * Converts a {@link SourceNode} to its TypeScript string representation.\n *\n * Iterates `nodes` in DOM order, rendering each {@link CodeNode} via\n * {@link printCodeNode}.\n *\n * Top-level declarations are separated by a blank line so the source reads\n * cleanly without an external formatter.\n *\n * @example From nodes\n * ```ts\n * printSource({ kind: 'Source', nodes: [createConst({ name: 'x', nodes: [createText('1')] }), createText('x.toString()')] })\n * // 'const x = 1\\n\\nx.toString()'\n * ```\n */\nexport function printSource(node: SourceNode): string {\n const nodes = node.nodes\n\n if (!nodes || nodes.length === 0) return ''\n\n return nodes\n .map((child) => printCodeNode(child as CodeNode))\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping any embedded backslash or quote so the emitted\n * statement stays valid even for unusual paths.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an import declaration string in the repo style (single quotes, no semicolons), covering\n * default, namespace (`* as`), and named imports with `{ a as b }` aliases, each optionally\n * `type`-only. `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printImport({ name: ['z'], path: './zod.ts' })\n * // \"import { z } from './zod.ts'\"\n * ```\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n isTypeOnly?: boolean | null\n isNameSpace?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (!Array.isArray(name)) {\n if (isNameSpace) return `import ${typePrefix}* as ${name} from ${from}`\n return `import ${typePrefix}${name} from ${from}`\n }\n\n const specifiers = name.map((item) => {\n if (typeof item === 'object') {\n return item.name ? `${item.propertyName} as ${item.name}` : item.propertyName\n }\n return item\n })\n\n return `import ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n}\n\n/**\n * Renders an export declaration string in the repo style (single quotes, no semicolons), covering\n * named re-exports, namespace alias (`* as name`), and wildcard, each optionally `type`-only.\n * `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printExport({ name: ['Pet', 'Order'], path: './models.ts' })\n * // \"export { Pet, Order } from './models.ts'\"\n * ```\n */\nexport function printExport({\n path,\n name,\n isTypeOnly = false,\n asAlias = false,\n}: {\n path: string\n name?: string | Array<ts.Identifier | string> | null\n isTypeOnly?: boolean | null\n asAlias?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n const specifiers = name.map((item) => (typeof item === 'string' ? item : item.text))\n return `export ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n const parsedName = LEADING_DIGIT_PATTERN.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n console.warn(`When using name as string, asAlias should be true: ${name}`)\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import type { FileNode, SourceNode } from '@kubb/ast'\nimport { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath } from './utils.ts'\n\n/**\n * Default Kubb parser for `.ts` and `.js` files. Takes the universal AST\n * produced by an adapter and prints it as TypeScript source using the official\n * TypeScript compiler. Imports and exports are rewritten based on each file's\n * metadata.\n *\n * Used automatically when no `parsers` option is set on `defineConfig`. Use\n * `parserTsx` instead for React projects that emit JSX.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTs } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.ts' }) {\n const sourceParts: Array<string> = []\n for (const item of file.sources) {\n const sourceStr = printSource(item as SourceNode)\n if (sourceStr) {\n sourceParts.push(sourceStr.trimEnd())\n }\n }\n const source = sourceParts.join('\\n\\n')\n\n const importLines: Array<string> = []\n for (const item of (file as FileNode).imports) {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n importLines.push(\n printImport({\n name: item.name as string | Array<string | { propertyName: string; name?: string }>,\n path: resolveOutputPath(importPath, options, Boolean(item.root)),\n isTypeOnly: item.isTypeOnly,\n isNameSpace: item.isNameSpace,\n }),\n )\n }\n\n const exportLines: Array<string> = []\n for (const item of (file as FileNode).exports) {\n exportLines.push(\n printExport({\n name: item.name as string | Array<ts.Identifier | string> | null | undefined,\n path: resolveOutputPath(item.path, options, true),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n }),\n )\n }\n\n const importExportBlock = [...importLines, ...exportLines].join('\\n')\n\n const parts = [file.banner, importExportBlock, source, file.footer].filter((segment): segment is string => Boolean(segment)).map((s) => s.trimEnd())\n return parts.join('\\n\\n')\n },\n})\n","import { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { parserTs } from './parserTs.ts'\nimport { print } from './utils.ts'\n\n/**\n * Kubb parser for `.tsx` and `.jsx` files. Delegates to `parserTs` because the\n * TypeScript compiler handles JSX natively via `ScriptKind.TSX`.\n *\n * Add to the `parsers` array on `defineConfig` when generating components for\n * React (or any framework that emits JSX).\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTsx } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineParser({\n name: 'tsx',\n extNames: ['.tsx', '.jsx'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.tsx' }) {\n return parserTs.parse(file, options)\n },\n})\n"],"mappings":"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"}
{"version":3,"file":"index.js","names":[],"sources":["../../../internals/utils/src/fs.ts","../src/constants.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["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","/**\n * Character used for a single indent step. Set to `'\\t'` to emit tab-indented output.\n */\nexport const INDENT_CHAR = ' '\n\n/**\n * Number of {@link INDENT_CHAR} repeats that make up one nesting level.\n */\nconst INDENT_SIZE = 2 as const\n\n/**\n * Indentation unit prepended once per nesting level when pretty-printing.\n */\nexport const INDENT = INDENT_CHAR.repeat(INDENT_SIZE)\n\n/**\n * Matches the trailing `.<ext>` segment of a path (keeps segments like `foo.bar.ts`\n * intact by only trimming the last run of non-`/`/`.` characters).\n */\nexport const FILE_EXTENSION_PATTERN = /\\.[^/.]+$/\n\n/**\n * Matches Windows-style backslash path separators.\n */\nexport const WINDOWS_PATH_SEPARATOR = /\\\\/g\n\n/**\n * Matches `*\\/` in free-form text so JSDoc bodies can neutralize premature\n * comment terminators (`*\\/` → `* /`).\n */\nexport const JSDOC_TERMINATOR_PATTERN = /\\*\\//g\n\n/**\n * Matches carriage returns for normalizing CRLF/CR line endings to LF.\n */\nexport const CARRIAGE_RETURN_PATTERN = /\\r/g\n\n/**\n * Matches CRLF sequences used when normalizing TypeScript printer output.\n */\nexport const CRLF_PATTERN = /\\r\\n/g\n\n/**\n * Matches an identifier that starts with a digit. JavaScript disallows this,\n * so the printer prefixes such names with `_`.\n */\nexport const LEADING_DIGIT_PATTERN = /^\\d/\n\n/**\n * Relative path prefix used to detect traversal segments (`../`).\n */\nexport const PARENT_DIRECTORY_PREFIX = '../' as const\n\n/**\n * Relative path prefix used when resolving imports within the output root.\n */\nexport const CURRENT_DIRECTORY_PREFIX = './' as const\n","import { normalize, relative } from 'node:path'\nimport { trimExtName } from '@internals/utils'\nimport type { ArrowFunctionNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, SourceNode, TextNode, TypeNode } from '@kubb/ast'\nimport ts from 'typescript'\nimport {\n CARRIAGE_RETURN_PATTERN,\n CRLF_PATTERN,\n CURRENT_DIRECTORY_PREFIX,\n FILE_EXTENSION_PATTERN,\n INDENT,\n INDENT_CHAR,\n JSDOC_TERMINATOR_PATTERN,\n LEADING_DIGIT_PATTERN,\n PARENT_DIRECTORY_PREFIX,\n WINDOWS_PATH_SEPARATOR,\n} from './constants.ts'\n\nconst { factory } = ts\n\n/**\n * Normalizes a file-system path to POSIX separators and strips any leading `../` segment.\n */\nexport function slash(path: string): string {\n return normalize(path).replaceAll(WINDOWS_PATH_SEPARATOR, '/').replace(PARENT_DIRECTORY_PREFIX, '')\n}\n\n/**\n * Resolves `filePath` relative to `rootDir` and returns a POSIX-style path\n * prefixed with `./` when the target sits inside the root, or `../` when it escapes it.\n */\nexport function getRelativePath(rootDir: string, filePath: string): string {\n const rel = relative(rootDir, filePath)\n const slashed = slash(rel)\n return slashed.startsWith(PARENT_DIRECTORY_PREFIX) ? slashed : `${CURRENT_DIRECTORY_PREFIX}${slashed}`\n}\n\n/**\n * Rewrites an import/export path so its extension matches the caller-supplied\n * `options.extname`. When the source path has no extension the original is kept,\n * so virtual/module-only paths flow through unchanged.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = FILE_EXTENSION_PATTERN.test(path)\n if (options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Serializes a `nodes` array into source text. Each entry is rendered via {@link printCodeNode}\n * and joined with a single newline; a `Break` node (`<br/>`) inserts one blank line between\n * statements. Consecutive breaks, and breaks at the very start or end, are folded into the\n * separator, so a double `<br/>` never emits more than one blank line.\n */\nexport function printNodes(nodes: Array<CodeNode> | undefined): string {\n if (!nodes || nodes.length === 0) return ''\n\n let result = ''\n let hasContent = false\n let pendingBreak = false\n\n for (const node of nodes) {\n if (node.kind === 'Break') {\n if (hasContent) pendingBreak = true\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (hasContent) result += pendingBreak ? '\\n\\n' : '\\n'\n result += text\n hasContent = true\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by one indent unit. Pass a number to repeat\n * {@link INDENT_CHAR} that many times, or a string to use as the indent verbatim.\n */\nexport function indentLines(text: string, indent: number | string = INDENT): string {\n if (!text) return ''\n const pad = typeof indent === 'string' ? indent : INDENT_CHAR.repeat(indent)\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Removes the common leading whitespace shared by every non-blank line and trims\n * surrounding blank lines, normalizing multi-line content authored inside an\n * indented template literal back to a column-zero baseline. Leading whitespace is\n * counted by character, so N tabs and N spaces are treated as the same depth.\n *\n * @example\n * ```ts\n * dedent('\\n foo\\n bar\\n ')\n * // 'foo\\n bar'\n * ```\n */\nexport function dedent(text: string): string {\n if (!text) return ''\n\n const lines = text.split('\\n')\n const isBlank = (line: string) => line.trim() === ''\n\n const start = lines.findIndex((line) => !isBlank(line))\n if (start === -1) return ''\n const end = lines.findLastIndex((line) => !isBlank(line))\n\n const trimmed = lines.slice(start, end + 1)\n const indents = trimmed.filter((line) => !isBlank(line)).map((line) => line.match(/^\\s*/)?.[0].length ?? 0)\n const min = indents.length ? Math.min(...indents) : 0\n\n return trimmed.map((line) => (isBlank(line) ? '' : line.slice(min))).join('\\n')\n}\n\n/**\n * Renders the generic clause (`<T, U>`) shared by function and arrow-function nodes.\n * Accepts either a raw string (rendered verbatim) or an array of type-parameter names.\n */\nexport function formatGenerics(generics: FunctionNode['generics'] | ArrowFunctionNode['generics']): string {\n if (!generics) return ''\n return `<${Array.isArray(generics) ? generics.join(', ') : generics}>`\n}\n\n/**\n * Renders the return-type suffix (`: T` or `: Promise<T>` when `isAsync` is true).\n * Returns an empty string when no return type is provided.\n */\nexport function formatReturnType(returnType: string | null | undefined, isAsync: boolean | null | undefined): string {\n if (!returnType) return ''\n return isAsync ? `: Promise<${returnType}>` : `: ${returnType}`\n}\n\n/**\n * Module-scoped TypeScript printer instance. `ts.createPrinter()` is stateless across calls\n * (it does not mutate the source file) so a single instance can be safely reused for every\n * `print()` call. Hoisting it out of `print()` avoids re-running the printer initialization\n * for each file's import/export section.\n */\nconst TS_PRINTER = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n})\n\n/**\n * Module-scoped source file used as the print target. `printList` only reads the source\n * file's compiler options / language version. It never mutates it.\n */\nconst PRINT_SOURCE_FILE = ts.createSourceFile('print.tsx', '', ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX)\n\n// Pre-warm the printer at module load. The first `printList` call lazily initializes\n// the printer's internal string-builder and identifier tables. Doing it once at import\n// time keeps that cost off the critical path for short-lived CLI builds.\nTS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray([]), PRINT_SOURCE_FILE)\n\n/**\n * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.\n */\nexport function print(...elements: Array<ts.Node>): string {\n const filtered = elements.filter(Boolean)\n if (filtered.length === 0) return ''\n\n const output = TS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray(filtered), PRINT_SOURCE_FILE)\n\n return output.replace(CRLF_PATTERN, '\\n')\n}\n\n/**\n * Converts a {@link JSDocNode} to a JSDoc comment block string.\n *\n * @example\n * ```ts\n * printJSDoc({ comments: ['@description A pet', '@deprecated'] })\n * // /**\n * // * @description A pet\n * // * @deprecated\n * // *\\/\n * ```\n */\nexport function printJSDoc(jsDoc: JSDocNode): string {\n const comments = (jsDoc.comments ?? []).filter((c) => c != null)\n if (comments.length === 0) return ''\n\n const lines = comments\n .flatMap((c) => c.split(/\\r?\\n/))\n .map((l) => l.replace(JSDOC_TERMINATOR_PATTERN, '* /').replace(CARRIAGE_RETURN_PATTERN, ''))\n .filter((l) => l.trim().length > 0)\n\n if (lines.length === 0) return ''\n\n return ['/**', ...lines.map((l) => ` * ${l}`), ' */'].join('\\n')\n}\n\n/**\n * Converts a {@link ConstNode} to a TypeScript `const` declaration string.\n *\n * Mirrors the `Const` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printConst(createConst({ name: 'pet', export: true, nodes: ['{}'] }))\n * // 'export const pet = {}'\n * ```\n *\n * @example With type and `as const`\n * ```ts\n * printConst(createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true, nodes: ['[]'] }))\n * // 'export const pets: Pet[] = [] as const'\n * ```\n */\nexport function printConst(node: ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('const ')\n parts.push(name)\n if (type) {\n parts.push(`: ${type}`)\n }\n parts.push(' = ')\n parts.push(body)\n if (asConst) parts.push(' as const')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link TypeNode} to a TypeScript `type` alias declaration string.\n *\n * Mirrors the `Type` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printType(createType({ name: 'Pet', export: true, nodes: ['{ id: number }'] }))\n * // 'export type Pet = { id: number }'\n * ```\n */\nexport function printType(node: TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n parts.push('type ')\n parts.push(name)\n parts.push(' = ')\n parts.push(body)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link FunctionNode} to a TypeScript `function` declaration string.\n *\n * Mirrors the `Function` component from `@kubb/renderer-jsx`.\n *\n * @example\n * ```ts\n * printFunction(createFunction({ name: 'getPet', export: true, params: 'id: string', returnType: 'Pet', nodes: ['return fetch(id)'] }))\n * // 'export function getPet(id: string): Pet {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Async with generics\n * ```ts\n * printFunction(createFunction({ name: 'fetchPet', export: true, async: true, generics: ['T'], params: 'id: string', returnType: 'T' }))\n * // 'export async function fetchPet<T>(id: string): Promise<T> {\\n}'\n * ```\n */\nexport function printFunction(node: FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const indented = body ? indentLines(body) : ''\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n if (isAsync) parts.push('async ')\n parts.push('function ')\n parts.push(name)\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(' {')\n if (indented) {\n parts.push(`\\n${indented}\\n`)\n }\n parts.push('}')\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts an {@link ArrowFunctionNode} to a TypeScript arrow function declaration string.\n *\n * Mirrors the `Function.Arrow` component from `@kubb/renderer-jsx`.\n *\n * @example Multi-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'getPet', export: true, params: 'id: string', nodes: ['return fetch(id)'] }))\n * // 'export const getPet = (id: string) => {\\n return fetch(id)\\n}'\n * ```\n *\n * @example Single-line arrow function\n * ```ts\n * printArrowFunction(createArrowFunction({ name: 'double', params: 'n: number', singleLine: true, nodes: ['n * 2'] }))\n * // 'const double = (n: number) => n * 2'\n * ```\n */\nexport function printArrowFunction(node: ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const jsDocStr = JSDoc ? printJSDoc(JSDoc) : ''\n const body = printNodes(nodes)\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n\n const parts: Array<string> = []\n if (canExport) parts.push('export ')\n if (isDefault) parts.push('default ')\n parts.push('const ')\n parts.push(name)\n parts.push(' = ')\n if (isAsync) parts.push('async ')\n parts.push(formatGenerics(generics))\n parts.push(`(${params ?? ''})`)\n parts.push(formatReturnType(returnType, isAsync))\n parts.push(arrowBody)\n\n const declaration = parts.join('')\n return [jsDocStr, declaration].filter(Boolean).join('\\n')\n}\n\n/**\n * Converts a {@link CodeNode} to its TypeScript string representation.\n *\n * Dispatches to the appropriate printer based on the node's `kind`.\n *\n * @example\n * ```ts\n * printCodeNode(createConst({ name: 'x', nodes: ['1'] }))\n * // 'const x = 1'\n * ```\n */\nexport function printCodeNode(node: CodeNode): string {\n if (node.kind === 'Break') return ''\n if (node.kind === 'Text') return dedent((node as TextNode).value)\n if (node.kind === 'Jsx') return dedent((node as JsxNode).value)\n if (node.kind === 'Const') return printConst(node)\n if (node.kind === 'Type') return printType(node)\n if (node.kind === 'Function') return printFunction(node)\n if (node.kind === 'ArrowFunction') return printArrowFunction(node)\n return ''\n}\n\n/**\n * Converts a {@link SourceNode} to its TypeScript string representation.\n *\n * Iterates `nodes` in DOM order, rendering each {@link CodeNode} via\n * {@link printCodeNode}.\n *\n * Top-level declarations are separated by a blank line so the source reads\n * cleanly without an external formatter.\n *\n * @example From nodes\n * ```ts\n * printSource({ kind: 'Source', nodes: [createConst({ name: 'x', nodes: [createText('1')] }), createText('x.toString()')] })\n * // 'const x = 1\\n\\nx.toString()'\n * ```\n */\nexport function printSource(node: SourceNode): string {\n const nodes = node.nodes\n\n if (!nodes || nodes.length === 0) return ''\n\n return nodes\n .map((child) => printCodeNode(child as CodeNode))\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping any embedded backslash or quote so the emitted\n * statement stays valid even for unusual paths.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an import declaration string in the repo style (single quotes, no semicolons), covering\n * default, namespace (`* as`), and named imports with `{ a as b }` aliases, each optionally\n * `type`-only. `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printImport({ name: ['z'], path: './zod.ts' })\n * // \"import { z } from './zod.ts'\"\n * ```\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n isTypeOnly?: boolean | null\n isNameSpace?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (!Array.isArray(name)) {\n if (isNameSpace) return `import ${typePrefix}* as ${name} from ${from}`\n return `import ${typePrefix}${name} from ${from}`\n }\n\n const specifiers = name.map((item) => {\n if (typeof item === 'object') {\n return item.name ? `${item.propertyName} as ${item.name}` : item.propertyName\n }\n return item\n })\n\n return `import ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n}\n\n/**\n * Renders an export declaration string in the repo style (single quotes, no semicolons), covering\n * named re-exports, namespace alias (`* as name`), and wildcard, each optionally `type`-only.\n * `path` is used verbatim, so resolve it first.\n *\n * @example\n * ```ts\n * printExport({ name: ['Pet', 'Order'], path: './models.ts' })\n * // \"export { Pet, Order } from './models.ts'\"\n * ```\n */\nexport function printExport({\n path,\n name,\n isTypeOnly = false,\n asAlias = false,\n}: {\n path: string\n name?: string | Array<ts.Identifier | string> | null\n isTypeOnly?: boolean | null\n asAlias?: boolean | null\n}): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n const specifiers = name.map((item) => (typeof item === 'string' ? item : item.text))\n return `export ${typePrefix}{ ${specifiers.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n const parsedName = LEADING_DIGIT_PATTERN.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n console.warn(`When using name as string, asAlias should be true: ${name}`)\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import type { FileNode, SourceNode } from '@kubb/ast'\nimport { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath } from './utils.ts'\n\n/**\n * Default Kubb parser for `.ts` and `.js` files. Takes the universal AST\n * produced by an adapter and prints it as TypeScript source using the official\n * TypeScript compiler. Imports and exports are rewritten based on each file's\n * metadata.\n *\n * Used automatically when no `parsers` option is set on `defineConfig`. Use\n * `parserTsx` instead for React projects that emit JSX.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTs } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.ts' }) {\n const sourceParts: Array<string> = []\n for (const item of file.sources) {\n const sourceStr = printSource(item as SourceNode)\n if (sourceStr) {\n sourceParts.push(sourceStr.trimEnd())\n }\n }\n const source = sourceParts.join('\\n\\n')\n\n const importLines: Array<string> = []\n for (const item of (file as FileNode).imports) {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n importLines.push(\n printImport({\n name: item.name as string | Array<string | { propertyName: string; name?: string }>,\n path: resolveOutputPath(importPath, options, Boolean(item.root)),\n isTypeOnly: item.isTypeOnly,\n isNameSpace: item.isNameSpace,\n }),\n )\n }\n\n const exportLines: Array<string> = []\n for (const item of (file as FileNode).exports) {\n exportLines.push(\n printExport({\n name: item.name as string | Array<ts.Identifier | string> | null | undefined,\n path: resolveOutputPath(item.path, options, true),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n }),\n )\n }\n\n const importExportBlock = [...importLines, ...exportLines].join('\\n')\n\n const parts = [file.banner, importExportBlock, source, file.footer].filter((segment): segment is string => Boolean(segment)).map((s) => s.trimEnd())\n\n return parts.join('\\n\\n')\n },\n})\n","import { defineParser } from '@kubb/core'\nimport type * as ts from 'typescript'\nimport { parserTs } from './parserTs.ts'\nimport { print } from './utils.ts'\n\n/**\n * Kubb parser for `.tsx` and `.jsx` files. Delegates to `parserTs` because the\n * TypeScript compiler handles JSX natively via `ScriptKind.TSX`.\n *\n * Add to the `parsers` array on `defineConfig` when generating components for\n * React (or any framework that emits JSX).\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { adapterOas } from '@kubb/adapter-oas'\n * import { parserTsx } from '@kubb/parser-ts'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineParser({\n name: 'tsx',\n extNames: ['.tsx', '.jsx'],\n print(...nodes: Array<ts.Node>) {\n return print(...nodes)\n },\n parse(file, options = { extname: '.tsx' }) {\n return parserTs.parse(file, options)\n },\n})\n"],"mappings":"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"}
{
"name": "@kubb/parser-ts",
"version": "5.0.0-beta.54",
"version": "5.0.0-beta.55",
"description": "TypeScript and TSX source file parser for Kubb. Converts AST nodes and raw TypeScript code into formatted source strings using the TypeScript compiler API.",

@@ -44,7 +44,7 @@ "keywords": [

"typescript": "^6.0.3",
"@kubb/core": "5.0.0-beta.54"
"@kubb/core": "5.0.0-beta.55"
},
"devDependencies": {
"@kubb/ast": "5.0.0-beta.54",
"@internals/utils": "0.0.0"
"@internals/utils": "0.0.0",
"@kubb/ast": "5.0.0-beta.55"
},

@@ -51,0 +51,0 @@ "engines": {

@@ -74,4 +74,5 @@ import type { FileNode, SourceNode } from '@kubb/ast'

const parts = [file.banner, importExportBlock, source, file.footer].filter((segment): segment is string => Boolean(segment)).map((s) => s.trimEnd())
return parts.join('\n\n')
},
})
import { normalize, relative } from 'node:path'
import { trimExtName } from '@internals/utils'
import type { ArrowFunctionNode, CodeNode, ConstNode, FunctionNode, JSDocNode, JsxNode, SourceNode, TextNode, TypeNode } from '@kubb/ast'

@@ -37,10 +38,2 @@ import ts from 'typescript'

/**
* Strips the trailing file extension (for example `.ts`) from a path.
* Preserves intermediate dots like `foo.bar.ts` → `foo.bar`.
*/
export function trimExtName(text: string): string {
return text.replace(FILE_EXTENSION_PATTERN, '')
}
/**
* Rewrites an import/export path so its extension matches the caller-supplied

@@ -47,0 +40,0 @@ * `options.extname`. When the source path has no extension the original is kept,