@kubb/parser-ts 5.9.0 → 5.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -10,7 +10,7 @@ var compatibility = {
10
10
  };
11
11
  //#endregion
12
12
  //#region package.json
13
- var version = "5.9.0";
13
+ var version = "5.9.1";
14
14
  //#endregion
15
15
  //#region ../../internals/utils/src/fs.ts
16
16
  /**
@@ -428,7 +428,8 @@ const parserTs = (0, _kubb_kit.defineExtension)({
428
428
  meta: {
429
429
  name: "typescript",
430
430
  version,
431
- compatibility
431
+ compatibility,
432
+ issues: "https://github.com/kubb-labs/kubb/issues"
432
433
  },
433
434
  build({ extension = DEFAULT_EXTENSION }) {
434
435
  return {
@@ -493,7 +494,10 @@ const parserTs = (0, _kubb_kit.defineExtension)({
493
494
  */
494
495
  const parserTsx = (0, _kubb_kit.defineExtension)({
495
496
  kind: "parser",
496
- meta: { name: "tsx" },
497
+ meta: {
498
+ name: "tsx",
499
+ issues: "https://github.com/kubb-labs/kubb/issues"
500
+ },
497
501
  build: (options) => ({
498
502
  ...parserTs(options),
499
503
  extNames: [".tsx", ".jsx"]
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createRequire","relative","dirname","resolve","ast","defineExtension","ast","defineExtension"],"sources":["../kubb-extension.json","../package.json","../../../internals/utils/src/fs.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["","","import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, relative, resolve } from 'node:path'\nimport { runtime } from './runtime.ts'\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 * Previously read content, or `null` when the file does not exist.\n * Omitting this value reads the file before writing.\n */\n stored?: string | null\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 * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact\n * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a\n * reason to rewrite the file.\n *\n * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one\n * that normalizes what it stores. Trimming only `stored` would leave a source with leading\n * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison\n * has already dropped.\n */\nexport function matchesStored({ stored, source }: { stored: string; source: string }): boolean {\n return stored.trim() === source.trim()\n}\n\n/**\n * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline\n * the way prettier, biome, and oxfmt all do.\n * Skips the write when the trimmed content is empty, or when the file already holds that content.\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 the trimmed content plus a newline\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 content = `${trimmed}\\n`\n const resolved = resolve(path)\n let stored = options.stored\n\n if (stored === undefined) {\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n stored = (await file.exists()) ? await file.text() : null\n } else {\n try {\n stored = await readFile(resolved, { encoding: 'utf-8' })\n } catch {\n /* file doesn't exist yet */\n stored = null\n }\n }\n }\n if (matchesStored({ stored: stored ?? '', source: trimmed })) return null\n\n if (runtime.isBun) {\n await Bun.write(resolved, content)\n return content\n }\n\n // Creating the directory up front costs a syscall per file, and every file after the first in a\n // directory pays it for nothing. Write first and only fall back when the directory is missing,\n // which also stays correct when something removed it mid-run.\n try {\n await writeFile(resolved, content, { encoding: 'utf-8' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, content, { encoding: 'utf-8' })\n }\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n if (savedData !== content) {\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 content\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 * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved\n * to absolute paths first, so relative and `..`-containing inputs compare correctly.\n *\n * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that\n * it does not contain the project root, and before loading a path a caller supplied, check that it\n * did not escape the directory it is allowed to read from.\n *\n * @example\n * isPathInside('./src/gen', '.') // true — nested inside the root\n * isPathInside('.', '.') // true — the same directory counts as inside\n * isPathInside('.', './src/gen') // false — the root is not inside its own output\n * isPathInside('../other', '.') // false — escapes the root\n */\nexport function isPathInside(path: string, parent: string): boolean {\n const resolvedPath = resolve(path)\n const resolvedParent = resolve(parent)\n if (resolvedPath === resolvedParent) {\n return true\n }\n\n const rel = relative(resolvedParent, resolvedPath)\n\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n","import { createRequire } from 'node:module'\nimport { dirname, relative, resolve } from 'node:path'\nimport { toPosixPath, trimExtName } from '@internals/utils'\nimport { ast } from '@kubb/kit'\nimport type * as ts from 'typescript'\n\ntype Compiler = {\n typescript: typeof ts\n printer: ts.Printer\n sourceFile: ts.SourceFile\n}\n\nlet compiler: Compiler | undefined\n\n/**\n * Loads TypeScript on the first `print` or `copy`; `parse` is string templating and never needs it.\n *\n * Loaded with `require`, not `import`: when ESM imports a CommonJS package, Node keeps a second copy of its source\n * to detect named exports, and for TypeScript that copy is about 9 MB.\n */\nfunction loadCompiler(): Compiler {\n if (compiler) return compiler\n\n const typescript: typeof ts = createRequire(import.meta.url)('typescript')\n\n compiler = {\n typescript,\n // One printer serves every call; printing does not mutate the source file, which only lends its compiler options\n printer: typescript.createPrinter({\n omitTrailingSemicolon: true,\n newLine: typescript.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n }),\n sourceFile: typescript.createSourceFile('print.tsx', '', typescript.ScriptTarget.ES2022, true, typescript.ScriptKind.TSX),\n }\n\n return compiler\n}\n\n/**\n * Module specifier that imports `filePath` from the file at `root`: POSIX, relative to that file's directory, `./`-prefixed unless it climbs with `../`.\n */\nexport function getRelativePath(root: string, filePath: string): string {\n const slashed = toPosixPath(relative(dirname(root), filePath))\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\n/**\n * Swaps the extension of a relative import/export path for `options.extname`; package specifiers and extension-less paths stay as-is.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = /\\.[^/.]+$/.test(path)\n if (rootAware && options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Converts an import specifier into an `ImportNode` name, keeping the quotes of a string-literal name (`{ 'a-b' as ab }`).\n */\nfunction toImportName(element: ts.ImportSpecifier): string | { propertyName: string; name: string } {\n if (!element.propertyName) return element.name.text\n\n const { typescript } = loadCompiler()\n const { propertyName } = element\n return { propertyName: typescript.isStringLiteral(propertyName) ? quoteModulePath(propertyName.text) : propertyName.text, name: element.name.text }\n}\n\n/**\n * Converts an `import` declaration into `ImportNode`s. Side-effect imports and imports with attributes stay as written.\n */\nfunction toImportNodes(statement: ts.Statement, filePath: string): Array<ast.ImportNode> {\n const { typescript } = loadCompiler()\n if (!typescript.isImportDeclaration(statement) || !statement.importClause || !typescript.isStringLiteral(statement.moduleSpecifier) || statement.attributes)\n return []\n\n const { name, namedBindings, phaseModifier } = statement.importClause\n const specifier = statement.moduleSpecifier.text\n const target = specifier.startsWith('.') ? { path: resolve(dirname(filePath), specifier), root: filePath } : { path: specifier }\n const isTypeOnly = phaseModifier === typescript.SyntaxKind.TypeKeyword\n const nodes: Array<ast.ImportNode> = []\n\n if (name) nodes.push(ast.factory.createImport({ name: name.text, ...target, isTypeOnly }))\n if (namedBindings && typescript.isNamespaceImport(namedBindings)) {\n nodes.push(ast.factory.createImport({ name: namedBindings.name.text, ...target, isTypeOnly, isNameSpace: true }))\n }\n if (namedBindings && typescript.isNamedImports(namedBindings)) {\n const values = namedBindings.elements.filter((element) => !element.isTypeOnly)\n const types = namedBindings.elements.filter((element) => element.isTypeOnly)\n if (values.length) nodes.push(ast.factory.createImport({ name: values.map(toImportName), ...target, isTypeOnly }))\n if (types.length) nodes.push(ast.factory.createImport({ name: types.map(toImportName), ...target, isTypeOnly: true }))\n }\n\n return nodes\n}\n\n/**\n * Converts an `export … from` declaration into `ExportNode`s. Forms `printExport` cannot print stay as written.\n */\nfunction toExportNodes(statement: ts.Statement): Array<ast.ExportNode> {\n const { typescript } = loadCompiler()\n if (\n !typescript.isExportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n statement.attributes\n )\n return []\n\n const { exportClause, isTypeOnly } = statement\n const path = statement.moduleSpecifier.text\n\n if (!exportClause) return [ast.factory.createExport({ path, isTypeOnly })]\n if (typescript.isNamespaceExport(exportClause)) return [ast.factory.createExport({ name: exportClause.name.text, path, isTypeOnly, asAlias: true })]\n if (exportClause.elements.some((element) => element.propertyName || element.isTypeOnly || typescript.isStringLiteral(element.name))) return []\n\n return [ast.factory.createExport({ name: exportClause.elements.map((element) => element.name.text), path, isTypeOnly })]\n}\n\ntype ModuleDeclarations = {\n header: string\n imports: Array<ast.ImportNode>\n exports: Array<ast.ExportNode>\n body: string\n}\n\n/**\n * Splits `source` into its lifted `import`/`export … from` nodes, the `header` above the first one (shebang, directives, comments) and the rest as `body`.\n */\nexport function splitModuleDeclarations(source: string, filePath: string): ModuleDeclarations {\n const { typescript } = loadCompiler()\n const sourceFile = typescript.createSourceFile(filePath, source, typescript.ScriptTarget.Latest)\n const imports: Array<ast.ImportNode> = []\n const exports: Array<ast.ExportNode> = []\n let header = ''\n let body = ''\n let cursor = 0\n\n for (const statement of sourceFile.statements) {\n const importNodes = toImportNodes(statement, filePath)\n const exportNodes = toExportNodes(statement)\n if (!importNodes.length && !exportNodes.length) {\n // Lifted declarations print above the body, so stop at the first one that stays in place to keep the evaluation order.\n if (typescript.isImportDeclaration(statement) || (typescript.isExportDeclaration(statement) && statement.moduleSpecifier)) break\n continue\n }\n\n const text = source.slice(cursor, statement.getStart(sourceFile))\n if (imports.length || exports.length) body += text\n else header = text\n imports.push(...importNodes)\n exports.push(...exportNodes)\n cursor = statement.getEnd()\n }\n\n return { header: header.trim(), imports, exports, body: `${body}${source.slice(cursor)}`.trim() }\n}\n\n/**\n * Joins the printed `nodes` with `separator`; a `Break` widens the next separator to a blank line, and leading, trailing and repeated breaks fold into one.\n *\n * Imperative on purpose: this runs once per source fragment and `map().filter().join()` showed up in deopt traces.\n */\nfunction printNodes({ nodes, separator }: { nodes: Array<ast.CodeNode> | undefined; separator: '\\n' | '\\n\\n' }): string {\n let result = ''\n let pendingBreak = false\n\n for (const node of nodes ?? []) {\n if (node.kind === 'Break') {\n pendingBreak = result !== ''\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (result) result += pendingBreak ? '\\n\\n' : separator\n result += text\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by two spaces.\n */\nfunction indentLines(text: string): string {\n if (!text) return ''\n return text\n .split('\\n')\n .map((line) => (line.trim() ? ` ${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Strips the common leading whitespace and the surrounding blank lines, counting tabs and spaces alike, so indented template literals start at column zero.\n */\nfunction 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\ntype Signature = {\n async?: boolean | null\n generics?: ast.FunctionNode['generics'] | ast.ArrowFunctionNode['generics']\n params?: string | null\n returnType?: string | null\n}\n\n/**\n * Renders `<T>(params): ReturnType`; an async function wraps its return type in `Promise<>`.\n */\nfunction signature({ async: isAsync, generics, params, returnType }: Signature): string {\n const genericsStr = generics ? `<${Array.isArray(generics) ? generics.join(', ') : generics}>` : ''\n const wrapped = isAsync ? `Promise<${returnType}>` : returnType\n const returnTypeStr = returnType ? `: ${wrapped}` : ''\n\n return `${genericsStr}(${params ?? ''})${returnTypeStr}`\n}\n\n/**\n * Puts the JSDoc block, when it renders to something, above `declaration`.\n */\nfunction withJSDoc({ jsDoc, declaration }: { jsDoc?: ast.JSDocNode | null; declaration: string }): string {\n const jsDocStr = jsDoc ? printJSDoc(jsDoc) : ''\n\n return jsDocStr ? `${jsDocStr}\\n${declaration}` : declaration\n}\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 { typescript, printer, sourceFile } = loadCompiler()\n const output = printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile)\n\n return output.replace(/\\r\\n/g, '\\n')\n}\n\n/**\n * Converts a {@link ast.JSDocNode} to a `/** … *\\/` block, dropping blank comments.\n */\nfunction printJSDoc(jsDoc: ast.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(/\\*\\//g, '* /').replace(/\\r/g, ''))\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 ast.ConstNode} to a `const` declaration, mirroring the `Const` component from `@kubb/renderer-jsx`.\n */\nfunction printConst(node: ast.ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}const ${name}${type ? `: ${type}` : ''} = ${printNodes({ nodes, separator: '\\n' })}${asConst ? ' as const' : ''}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.TypeNode} to a `type` alias, mirroring the `Type` component from `@kubb/renderer-jsx`.\n */\nfunction printType(node: ast.TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}type ${name} = ${printNodes({ nodes, separator: '\\n' })}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.FunctionNode} to a `function` declaration, mirroring the `Function` component from `@kubb/renderer-jsx`.\n */\nfunction printFunction(node: ast.FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const body = indentLines(printNodes({ nodes, separator: '\\n' }))\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}${isAsync ? 'async ' : ''}`\n const declaration = `${prefix}function ${name}${signature({ async: isAsync, generics, params, returnType })} {${body ? `\\n${body}\\n` : ''}}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts an {@link ast.ArrowFunctionNode} to a `const` arrow function, mirroring the `Function.Arrow` component from `@kubb/renderer-jsx`.\n */\nfunction printArrowFunction(node: ast.ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const body = printNodes({ nodes, separator: '\\n' })\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}`\n const declaration = `${prefix}const ${name} = ${isAsync ? 'async ' : ''}${signature({ async: isAsync, generics, params, returnType })}${arrowBody}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Dispatches a {@link ast.CodeNode} to the printer for its `kind`.\n */\nfunction printCodeNode(node: ast.CodeNode): string {\n switch (node.kind) {\n case 'Break':\n return ''\n case 'Text':\n case 'Jsx':\n return dedent(node.value)\n case 'Const':\n return printConst(node)\n case 'Type':\n return printType(node)\n case 'Function':\n return printFunction(node)\n case 'ArrowFunction':\n return printArrowFunction(node)\n }\n}\n\n/**\n * Prints a {@link ast.SourceNode} with a blank line between its top-level nodes.\n */\nexport function printSource(node: ast.SourceNode): string {\n return printNodes({ nodes: node.nodes, separator: '\\n\\n' })\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping embedded backslashes and quotes.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an `import` declaration (default, `* as`, or named with `{ a as b }`, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: Pick<ast.ImportNode, 'name' | 'path' | 'isTypeOnly' | 'isNameSpace'>): 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 … from` declaration (named, `* as name`, or wildcard, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printExport({ path, name, isTypeOnly = false, asAlias = false }: Pick<ast.ExportNode, 'name' | 'path' | 'isTypeOnly' | 'asAlias'>): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n return `export ${typePrefix}{ ${name.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n // An identifier cannot start with a digit, so swap the digit for `_`\n const parsedName = /^\\d/.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n return `export ${typePrefix}{ ${name} } from ${from}`\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import { ast, defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { compatibility } from '../kubb-extension.json'\nimport { version } from '../package.json'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath, splitModuleDeclarations } from './utils.ts'\n\nconst DEFAULT_EXTENSION: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''> = { '.ts': '' }\n\n/**\n * Options accepted by `parserTs` and `parserTsx`.\n */\nexport type ParserTsOptions = {\n /**\n * Rewrite extensions on relative `import`/`export` statements. Each key is the extension of a\n * generated file, and its value is the extension written on the relative specifiers in that\n * file. `''` drops it, and so does a generated file whose extension has no key. Package\n * specifiers stay unchanged. Also applies to relative paths in `copy` templates.\n *\n * Use `{ '.ts': '.js' }` for ESM output compiled to JavaScript, or `{ '.ts': '.ts' }` to run the\n * `.ts` files directly in Node.js or compile them with `rewriteRelativeImportExtensions`.\n *\n * @default { '.ts': '' }\n * @example\n * ```ts\n * parserTs({ extension: { '.ts': '.js' } }) // import './api.js' instead of './api'\n * parserTs({ extension: { '.ts': '.ts' } }) // import './api.ts' instead of './api'\n * ```\n */\n extension?: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''>\n}\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. Imports and exports\n * are rewritten based on each file's metadata and the `extension` option. The\n * `print` helper renders TypeScript compiler nodes with the TypeScript printer.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'typescript', version, compatibility },\n build({ extension = DEFAULT_EXTENSION }) {\n return {\n extNames: ['.ts', '.js'],\n print,\n parse(file) {\n const extname = extension[file.extname] || undefined\n\n const source = file.sources\n .map((item) => printSource(item))\n .filter(Boolean)\n .map((text) => text.trimEnd())\n .join('\\n\\n')\n\n const importLines = file.imports.map((item) =>\n printImport({\n ...item,\n path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, { extname }, Boolean(item.root)),\n }),\n )\n\n const exportLines = file.exports.map((item) => printExport({ ...item, path: resolveOutputPath(item.path, { extname }, item.path.startsWith('.')) }))\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 copy(file, source) {\n const { header, imports, exports, body } = splitModuleDeclarations(source, file.path)\n\n return {\n ...file,\n banner: [header, file.banner].filter(Boolean).join('\\n') || undefined,\n imports: [...file.imports, ...imports],\n exports: [...file.exports, ...exports],\n sources: [ast.factory.createSource({ nodes: [ast.factory.createText(body)] })],\n }\n },\n }\n },\n})\n","import { defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { parserTs, type ParserTsOptions } from './parserTs.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`, so it shares the\n * same `extension` option.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'tsx' },\n build: (options) => ({ ...parserTs(options), extNames: ['.tsx', '.jsx'] }),\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["createRequire","relative","dirname","resolve","ast","defineExtension","ast","defineExtension"],"sources":["../kubb-extension.json","../package.json","../../../internals/utils/src/fs.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["","","import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, relative, resolve } from 'node:path'\nimport { runtime } from './runtime.ts'\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 * Previously read content, or `null` when the file does not exist.\n * Omitting this value reads the file before writing.\n */\n stored?: string | null\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 * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact\n * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a\n * reason to rewrite the file.\n *\n * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one\n * that normalizes what it stores. Trimming only `stored` would leave a source with leading\n * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison\n * has already dropped.\n */\nexport function matchesStored({ stored, source }: { stored: string; source: string }): boolean {\n return stored.trim() === source.trim()\n}\n\n/**\n * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline\n * the way prettier, biome, and oxfmt all do.\n * Skips the write when the trimmed content is empty, or when the file already holds that content.\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 the trimmed content plus a newline\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 content = `${trimmed}\\n`\n const resolved = resolve(path)\n let stored = options.stored\n\n if (stored === undefined) {\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n stored = (await file.exists()) ? await file.text() : null\n } else {\n try {\n stored = await readFile(resolved, { encoding: 'utf-8' })\n } catch {\n /* file doesn't exist yet */\n stored = null\n }\n }\n }\n if (matchesStored({ stored: stored ?? '', source: trimmed })) return null\n\n if (runtime.isBun) {\n await Bun.write(resolved, content)\n return content\n }\n\n // Creating the directory up front costs a syscall per file, and every file after the first in a\n // directory pays it for nothing. Write first and only fall back when the directory is missing,\n // which also stays correct when something removed it mid-run.\n try {\n await writeFile(resolved, content, { encoding: 'utf-8' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, content, { encoding: 'utf-8' })\n }\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n if (savedData !== content) {\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 content\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 * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved\n * to absolute paths first, so relative and `..`-containing inputs compare correctly.\n *\n * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that\n * it does not contain the project root, and before loading a path a caller supplied, check that it\n * did not escape the directory it is allowed to read from.\n *\n * @example\n * isPathInside('./src/gen', '.') // true — nested inside the root\n * isPathInside('.', '.') // true — the same directory counts as inside\n * isPathInside('.', './src/gen') // false — the root is not inside its own output\n * isPathInside('../other', '.') // false — escapes the root\n */\nexport function isPathInside(path: string, parent: string): boolean {\n const resolvedPath = resolve(path)\n const resolvedParent = resolve(parent)\n if (resolvedPath === resolvedParent) {\n return true\n }\n\n const rel = relative(resolvedParent, resolvedPath)\n\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n","import { createRequire } from 'node:module'\nimport { dirname, relative, resolve } from 'node:path'\nimport { toPosixPath, trimExtName } from '@internals/utils'\nimport { ast } from '@kubb/kit'\nimport type * as ts from 'typescript'\n\ntype Compiler = {\n typescript: typeof ts\n printer: ts.Printer\n sourceFile: ts.SourceFile\n}\n\nlet compiler: Compiler | undefined\n\n/**\n * Loads TypeScript on the first `print` or `copy`; `parse` is string templating and never needs it.\n *\n * Loaded with `require`, not `import`: when ESM imports a CommonJS package, Node keeps a second copy of its source\n * to detect named exports, and for TypeScript that copy is about 9 MB.\n */\nfunction loadCompiler(): Compiler {\n if (compiler) return compiler\n\n const typescript: typeof ts = createRequire(import.meta.url)('typescript')\n\n compiler = {\n typescript,\n // One printer serves every call; printing does not mutate the source file, which only lends its compiler options\n printer: typescript.createPrinter({\n omitTrailingSemicolon: true,\n newLine: typescript.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n }),\n sourceFile: typescript.createSourceFile('print.tsx', '', typescript.ScriptTarget.ES2022, true, typescript.ScriptKind.TSX),\n }\n\n return compiler\n}\n\n/**\n * Module specifier that imports `filePath` from the file at `root`: POSIX, relative to that file's directory, `./`-prefixed unless it climbs with `../`.\n */\nexport function getRelativePath(root: string, filePath: string): string {\n const slashed = toPosixPath(relative(dirname(root), filePath))\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\n/**\n * Swaps the extension of a relative import/export path for `options.extname`; package specifiers and extension-less paths stay as-is.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = /\\.[^/.]+$/.test(path)\n if (rootAware && options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Converts an import specifier into an `ImportNode` name, keeping the quotes of a string-literal name (`{ 'a-b' as ab }`).\n */\nfunction toImportName(element: ts.ImportSpecifier): string | { propertyName: string; name: string } {\n if (!element.propertyName) return element.name.text\n\n const { typescript } = loadCompiler()\n const { propertyName } = element\n return { propertyName: typescript.isStringLiteral(propertyName) ? quoteModulePath(propertyName.text) : propertyName.text, name: element.name.text }\n}\n\n/**\n * Converts an `import` declaration into `ImportNode`s. Side-effect imports and imports with attributes stay as written.\n */\nfunction toImportNodes(statement: ts.Statement, filePath: string): Array<ast.ImportNode> {\n const { typescript } = loadCompiler()\n if (!typescript.isImportDeclaration(statement) || !statement.importClause || !typescript.isStringLiteral(statement.moduleSpecifier) || statement.attributes)\n return []\n\n const { name, namedBindings, phaseModifier } = statement.importClause\n const specifier = statement.moduleSpecifier.text\n const target = specifier.startsWith('.') ? { path: resolve(dirname(filePath), specifier), root: filePath } : { path: specifier }\n const isTypeOnly = phaseModifier === typescript.SyntaxKind.TypeKeyword\n const nodes: Array<ast.ImportNode> = []\n\n if (name) nodes.push(ast.factory.createImport({ name: name.text, ...target, isTypeOnly }))\n if (namedBindings && typescript.isNamespaceImport(namedBindings)) {\n nodes.push(ast.factory.createImport({ name: namedBindings.name.text, ...target, isTypeOnly, isNameSpace: true }))\n }\n if (namedBindings && typescript.isNamedImports(namedBindings)) {\n const values = namedBindings.elements.filter((element) => !element.isTypeOnly)\n const types = namedBindings.elements.filter((element) => element.isTypeOnly)\n if (values.length) nodes.push(ast.factory.createImport({ name: values.map(toImportName), ...target, isTypeOnly }))\n if (types.length) nodes.push(ast.factory.createImport({ name: types.map(toImportName), ...target, isTypeOnly: true }))\n }\n\n return nodes\n}\n\n/**\n * Converts an `export … from` declaration into `ExportNode`s. Forms `printExport` cannot print stay as written.\n */\nfunction toExportNodes(statement: ts.Statement): Array<ast.ExportNode> {\n const { typescript } = loadCompiler()\n if (\n !typescript.isExportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n statement.attributes\n )\n return []\n\n const { exportClause, isTypeOnly } = statement\n const path = statement.moduleSpecifier.text\n\n if (!exportClause) return [ast.factory.createExport({ path, isTypeOnly })]\n if (typescript.isNamespaceExport(exportClause)) return [ast.factory.createExport({ name: exportClause.name.text, path, isTypeOnly, asAlias: true })]\n if (exportClause.elements.some((element) => element.propertyName || element.isTypeOnly || typescript.isStringLiteral(element.name))) return []\n\n return [ast.factory.createExport({ name: exportClause.elements.map((element) => element.name.text), path, isTypeOnly })]\n}\n\ntype ModuleDeclarations = {\n header: string\n imports: Array<ast.ImportNode>\n exports: Array<ast.ExportNode>\n body: string\n}\n\n/**\n * Splits `source` into its lifted `import`/`export … from` nodes, the `header` above the first one (shebang, directives, comments) and the rest as `body`.\n */\nexport function splitModuleDeclarations(source: string, filePath: string): ModuleDeclarations {\n const { typescript } = loadCompiler()\n const sourceFile = typescript.createSourceFile(filePath, source, typescript.ScriptTarget.Latest)\n const imports: Array<ast.ImportNode> = []\n const exports: Array<ast.ExportNode> = []\n let header = ''\n let body = ''\n let cursor = 0\n\n for (const statement of sourceFile.statements) {\n const importNodes = toImportNodes(statement, filePath)\n const exportNodes = toExportNodes(statement)\n if (!importNodes.length && !exportNodes.length) {\n // Lifted declarations print above the body, so stop at the first one that stays in place to keep the evaluation order.\n if (typescript.isImportDeclaration(statement) || (typescript.isExportDeclaration(statement) && statement.moduleSpecifier)) break\n continue\n }\n\n const text = source.slice(cursor, statement.getStart(sourceFile))\n if (imports.length || exports.length) body += text\n else header = text\n imports.push(...importNodes)\n exports.push(...exportNodes)\n cursor = statement.getEnd()\n }\n\n return { header: header.trim(), imports, exports, body: `${body}${source.slice(cursor)}`.trim() }\n}\n\n/**\n * Joins the printed `nodes` with `separator`; a `Break` widens the next separator to a blank line, and leading, trailing and repeated breaks fold into one.\n *\n * Imperative on purpose: this runs once per source fragment and `map().filter().join()` showed up in deopt traces.\n */\nfunction printNodes({ nodes, separator }: { nodes: Array<ast.CodeNode> | undefined; separator: '\\n' | '\\n\\n' }): string {\n let result = ''\n let pendingBreak = false\n\n for (const node of nodes ?? []) {\n if (node.kind === 'Break') {\n pendingBreak = result !== ''\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (result) result += pendingBreak ? '\\n\\n' : separator\n result += text\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by two spaces.\n */\nfunction indentLines(text: string): string {\n if (!text) return ''\n return text\n .split('\\n')\n .map((line) => (line.trim() ? ` ${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Strips the common leading whitespace and the surrounding blank lines, counting tabs and spaces alike, so indented template literals start at column zero.\n */\nfunction 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\ntype Signature = {\n async?: boolean | null\n generics?: ast.FunctionNode['generics'] | ast.ArrowFunctionNode['generics']\n params?: string | null\n returnType?: string | null\n}\n\n/**\n * Renders `<T>(params): ReturnType`; an async function wraps its return type in `Promise<>`.\n */\nfunction signature({ async: isAsync, generics, params, returnType }: Signature): string {\n const genericsStr = generics ? `<${Array.isArray(generics) ? generics.join(', ') : generics}>` : ''\n const wrapped = isAsync ? `Promise<${returnType}>` : returnType\n const returnTypeStr = returnType ? `: ${wrapped}` : ''\n\n return `${genericsStr}(${params ?? ''})${returnTypeStr}`\n}\n\n/**\n * Puts the JSDoc block, when it renders to something, above `declaration`.\n */\nfunction withJSDoc({ jsDoc, declaration }: { jsDoc?: ast.JSDocNode | null; declaration: string }): string {\n const jsDocStr = jsDoc ? printJSDoc(jsDoc) : ''\n\n return jsDocStr ? `${jsDocStr}\\n${declaration}` : declaration\n}\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 { typescript, printer, sourceFile } = loadCompiler()\n const output = printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile)\n\n return output.replace(/\\r\\n/g, '\\n')\n}\n\n/**\n * Converts a {@link ast.JSDocNode} to a `/** … *\\/` block, dropping blank comments.\n */\nfunction printJSDoc(jsDoc: ast.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(/\\*\\//g, '* /').replace(/\\r/g, ''))\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 ast.ConstNode} to a `const` declaration, mirroring the `Const` component from `@kubb/renderer-jsx`.\n */\nfunction printConst(node: ast.ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}const ${name}${type ? `: ${type}` : ''} = ${printNodes({ nodes, separator: '\\n' })}${asConst ? ' as const' : ''}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.TypeNode} to a `type` alias, mirroring the `Type` component from `@kubb/renderer-jsx`.\n */\nfunction printType(node: ast.TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}type ${name} = ${printNodes({ nodes, separator: '\\n' })}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.FunctionNode} to a `function` declaration, mirroring the `Function` component from `@kubb/renderer-jsx`.\n */\nfunction printFunction(node: ast.FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const body = indentLines(printNodes({ nodes, separator: '\\n' }))\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}${isAsync ? 'async ' : ''}`\n const declaration = `${prefix}function ${name}${signature({ async: isAsync, generics, params, returnType })} {${body ? `\\n${body}\\n` : ''}}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts an {@link ast.ArrowFunctionNode} to a `const` arrow function, mirroring the `Function.Arrow` component from `@kubb/renderer-jsx`.\n */\nfunction printArrowFunction(node: ast.ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const body = printNodes({ nodes, separator: '\\n' })\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}`\n const declaration = `${prefix}const ${name} = ${isAsync ? 'async ' : ''}${signature({ async: isAsync, generics, params, returnType })}${arrowBody}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Dispatches a {@link ast.CodeNode} to the printer for its `kind`.\n */\nfunction printCodeNode(node: ast.CodeNode): string {\n switch (node.kind) {\n case 'Break':\n return ''\n case 'Text':\n case 'Jsx':\n return dedent(node.value)\n case 'Const':\n return printConst(node)\n case 'Type':\n return printType(node)\n case 'Function':\n return printFunction(node)\n case 'ArrowFunction':\n return printArrowFunction(node)\n }\n}\n\n/**\n * Prints a {@link ast.SourceNode} with a blank line between its top-level nodes.\n */\nexport function printSource(node: ast.SourceNode): string {\n return printNodes({ nodes: node.nodes, separator: '\\n\\n' })\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping embedded backslashes and quotes.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an `import` declaration (default, `* as`, or named with `{ a as b }`, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: Pick<ast.ImportNode, 'name' | 'path' | 'isTypeOnly' | 'isNameSpace'>): 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 … from` declaration (named, `* as name`, or wildcard, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printExport({ path, name, isTypeOnly = false, asAlias = false }: Pick<ast.ExportNode, 'name' | 'path' | 'isTypeOnly' | 'asAlias'>): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n return `export ${typePrefix}{ ${name.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n // An identifier cannot start with a digit, so swap the digit for `_`\n const parsedName = /^\\d/.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n return `export ${typePrefix}{ ${name} } from ${from}`\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import { ast, defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { compatibility } from '../kubb-extension.json'\nimport { version } from '../package.json'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath, splitModuleDeclarations } from './utils.ts'\n\nconst DEFAULT_EXTENSION: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''> = { '.ts': '' }\n\n/**\n * Options accepted by `parserTs` and `parserTsx`.\n */\nexport type ParserTsOptions = {\n /**\n * Rewrite extensions on relative `import`/`export` statements. Each key is the extension of a\n * generated file, and its value is the extension written on the relative specifiers in that\n * file. `''` drops it, and so does a generated file whose extension has no key. Package\n * specifiers stay unchanged. Also applies to relative paths in `copy` templates.\n *\n * Use `{ '.ts': '.js' }` for ESM output compiled to JavaScript, or `{ '.ts': '.ts' }` to run the\n * `.ts` files directly in Node.js or compile them with `rewriteRelativeImportExtensions`.\n *\n * @default { '.ts': '' }\n * @example\n * ```ts\n * parserTs({ extension: { '.ts': '.js' } }) // import './api.js' instead of './api'\n * parserTs({ extension: { '.ts': '.ts' } }) // import './api.ts' instead of './api'\n * ```\n */\n extension?: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''>\n}\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. Imports and exports\n * are rewritten based on each file's metadata and the `extension` option. The\n * `print` helper renders TypeScript compiler nodes with the TypeScript printer.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'typescript', version, compatibility, issues: 'https://github.com/kubb-labs/kubb/issues' },\n build({ extension = DEFAULT_EXTENSION }) {\n return {\n extNames: ['.ts', '.js'],\n print,\n parse(file) {\n const extname = extension[file.extname] || undefined\n\n const source = file.sources\n .map((item) => printSource(item))\n .filter(Boolean)\n .map((text) => text.trimEnd())\n .join('\\n\\n')\n\n const importLines = file.imports.map((item) =>\n printImport({\n ...item,\n path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, { extname }, Boolean(item.root)),\n }),\n )\n\n const exportLines = file.exports.map((item) => printExport({ ...item, path: resolveOutputPath(item.path, { extname }, item.path.startsWith('.')) }))\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 copy(file, source) {\n const { header, imports, exports, body } = splitModuleDeclarations(source, file.path)\n\n return {\n ...file,\n banner: [header, file.banner].filter(Boolean).join('\\n') || undefined,\n imports: [...file.imports, ...imports],\n exports: [...file.exports, ...exports],\n sources: [ast.factory.createSource({ nodes: [ast.factory.createText(body)] })],\n }\n },\n }\n },\n})\n","import { defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { parserTs, type ParserTsOptions } from './parserTs.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`, so it shares the\n * same `extension` option.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'tsx', issues: 'https://github.com/kubb-labs/kubb/issues' },\n build: (options) => ({ ...parserTs(options), extNames: ['.tsx', '.jsx'] }),\n})\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var compatibility = {
9
9
  };
10
10
  //#endregion
11
11
  //#region package.json
12
- var version = "5.9.0";
12
+ var version = "5.9.1";
13
13
  //#endregion
14
14
  //#region ../../internals/utils/src/fs.ts
15
15
  /**
@@ -427,7 +427,8 @@ const parserTs = defineExtension({
427
427
  meta: {
428
428
  name: "typescript",
429
429
  version,
430
- compatibility
430
+ compatibility,
431
+ issues: "https://github.com/kubb-labs/kubb/issues"
431
432
  },
432
433
  build({ extension = DEFAULT_EXTENSION }) {
433
434
  return {
@@ -492,7 +493,10 @@ const parserTs = defineExtension({
492
493
  */
493
494
  const parserTsx = defineExtension({
494
495
  kind: "parser",
495
- meta: { name: "tsx" },
496
+ meta: {
497
+ name: "tsx",
498
+ issues: "https://github.com/kubb-labs/kubb/issues"
499
+ },
496
500
  build: (options) => ({
497
501
  ...parserTs(options),
498
502
  extNames: [".tsx", ".jsx"]
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../kubb-extension.json","../package.json","../../../internals/utils/src/fs.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["","","import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, relative, resolve } from 'node:path'\nimport { runtime } from './runtime.ts'\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 * Previously read content, or `null` when the file does not exist.\n * Omitting this value reads the file before writing.\n */\n stored?: string | null\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 * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact\n * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a\n * reason to rewrite the file.\n *\n * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one\n * that normalizes what it stores. Trimming only `stored` would leave a source with leading\n * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison\n * has already dropped.\n */\nexport function matchesStored({ stored, source }: { stored: string; source: string }): boolean {\n return stored.trim() === source.trim()\n}\n\n/**\n * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline\n * the way prettier, biome, and oxfmt all do.\n * Skips the write when the trimmed content is empty, or when the file already holds that content.\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 the trimmed content plus a newline\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 content = `${trimmed}\\n`\n const resolved = resolve(path)\n let stored = options.stored\n\n if (stored === undefined) {\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n stored = (await file.exists()) ? await file.text() : null\n } else {\n try {\n stored = await readFile(resolved, { encoding: 'utf-8' })\n } catch {\n /* file doesn't exist yet */\n stored = null\n }\n }\n }\n if (matchesStored({ stored: stored ?? '', source: trimmed })) return null\n\n if (runtime.isBun) {\n await Bun.write(resolved, content)\n return content\n }\n\n // Creating the directory up front costs a syscall per file, and every file after the first in a\n // directory pays it for nothing. Write first and only fall back when the directory is missing,\n // which also stays correct when something removed it mid-run.\n try {\n await writeFile(resolved, content, { encoding: 'utf-8' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, content, { encoding: 'utf-8' })\n }\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n if (savedData !== content) {\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 content\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 * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved\n * to absolute paths first, so relative and `..`-containing inputs compare correctly.\n *\n * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that\n * it does not contain the project root, and before loading a path a caller supplied, check that it\n * did not escape the directory it is allowed to read from.\n *\n * @example\n * isPathInside('./src/gen', '.') // true — nested inside the root\n * isPathInside('.', '.') // true — the same directory counts as inside\n * isPathInside('.', './src/gen') // false — the root is not inside its own output\n * isPathInside('../other', '.') // false — escapes the root\n */\nexport function isPathInside(path: string, parent: string): boolean {\n const resolvedPath = resolve(path)\n const resolvedParent = resolve(parent)\n if (resolvedPath === resolvedParent) {\n return true\n }\n\n const rel = relative(resolvedParent, resolvedPath)\n\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n","import { createRequire } from 'node:module'\nimport { dirname, relative, resolve } from 'node:path'\nimport { toPosixPath, trimExtName } from '@internals/utils'\nimport { ast } from '@kubb/kit'\nimport type * as ts from 'typescript'\n\ntype Compiler = {\n typescript: typeof ts\n printer: ts.Printer\n sourceFile: ts.SourceFile\n}\n\nlet compiler: Compiler | undefined\n\n/**\n * Loads TypeScript on the first `print` or `copy`; `parse` is string templating and never needs it.\n *\n * Loaded with `require`, not `import`: when ESM imports a CommonJS package, Node keeps a second copy of its source\n * to detect named exports, and for TypeScript that copy is about 9 MB.\n */\nfunction loadCompiler(): Compiler {\n if (compiler) return compiler\n\n const typescript: typeof ts = createRequire(import.meta.url)('typescript')\n\n compiler = {\n typescript,\n // One printer serves every call; printing does not mutate the source file, which only lends its compiler options\n printer: typescript.createPrinter({\n omitTrailingSemicolon: true,\n newLine: typescript.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n }),\n sourceFile: typescript.createSourceFile('print.tsx', '', typescript.ScriptTarget.ES2022, true, typescript.ScriptKind.TSX),\n }\n\n return compiler\n}\n\n/**\n * Module specifier that imports `filePath` from the file at `root`: POSIX, relative to that file's directory, `./`-prefixed unless it climbs with `../`.\n */\nexport function getRelativePath(root: string, filePath: string): string {\n const slashed = toPosixPath(relative(dirname(root), filePath))\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\n/**\n * Swaps the extension of a relative import/export path for `options.extname`; package specifiers and extension-less paths stay as-is.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = /\\.[^/.]+$/.test(path)\n if (rootAware && options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Converts an import specifier into an `ImportNode` name, keeping the quotes of a string-literal name (`{ 'a-b' as ab }`).\n */\nfunction toImportName(element: ts.ImportSpecifier): string | { propertyName: string; name: string } {\n if (!element.propertyName) return element.name.text\n\n const { typescript } = loadCompiler()\n const { propertyName } = element\n return { propertyName: typescript.isStringLiteral(propertyName) ? quoteModulePath(propertyName.text) : propertyName.text, name: element.name.text }\n}\n\n/**\n * Converts an `import` declaration into `ImportNode`s. Side-effect imports and imports with attributes stay as written.\n */\nfunction toImportNodes(statement: ts.Statement, filePath: string): Array<ast.ImportNode> {\n const { typescript } = loadCompiler()\n if (!typescript.isImportDeclaration(statement) || !statement.importClause || !typescript.isStringLiteral(statement.moduleSpecifier) || statement.attributes)\n return []\n\n const { name, namedBindings, phaseModifier } = statement.importClause\n const specifier = statement.moduleSpecifier.text\n const target = specifier.startsWith('.') ? { path: resolve(dirname(filePath), specifier), root: filePath } : { path: specifier }\n const isTypeOnly = phaseModifier === typescript.SyntaxKind.TypeKeyword\n const nodes: Array<ast.ImportNode> = []\n\n if (name) nodes.push(ast.factory.createImport({ name: name.text, ...target, isTypeOnly }))\n if (namedBindings && typescript.isNamespaceImport(namedBindings)) {\n nodes.push(ast.factory.createImport({ name: namedBindings.name.text, ...target, isTypeOnly, isNameSpace: true }))\n }\n if (namedBindings && typescript.isNamedImports(namedBindings)) {\n const values = namedBindings.elements.filter((element) => !element.isTypeOnly)\n const types = namedBindings.elements.filter((element) => element.isTypeOnly)\n if (values.length) nodes.push(ast.factory.createImport({ name: values.map(toImportName), ...target, isTypeOnly }))\n if (types.length) nodes.push(ast.factory.createImport({ name: types.map(toImportName), ...target, isTypeOnly: true }))\n }\n\n return nodes\n}\n\n/**\n * Converts an `export … from` declaration into `ExportNode`s. Forms `printExport` cannot print stay as written.\n */\nfunction toExportNodes(statement: ts.Statement): Array<ast.ExportNode> {\n const { typescript } = loadCompiler()\n if (\n !typescript.isExportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n statement.attributes\n )\n return []\n\n const { exportClause, isTypeOnly } = statement\n const path = statement.moduleSpecifier.text\n\n if (!exportClause) return [ast.factory.createExport({ path, isTypeOnly })]\n if (typescript.isNamespaceExport(exportClause)) return [ast.factory.createExport({ name: exportClause.name.text, path, isTypeOnly, asAlias: true })]\n if (exportClause.elements.some((element) => element.propertyName || element.isTypeOnly || typescript.isStringLiteral(element.name))) return []\n\n return [ast.factory.createExport({ name: exportClause.elements.map((element) => element.name.text), path, isTypeOnly })]\n}\n\ntype ModuleDeclarations = {\n header: string\n imports: Array<ast.ImportNode>\n exports: Array<ast.ExportNode>\n body: string\n}\n\n/**\n * Splits `source` into its lifted `import`/`export … from` nodes, the `header` above the first one (shebang, directives, comments) and the rest as `body`.\n */\nexport function splitModuleDeclarations(source: string, filePath: string): ModuleDeclarations {\n const { typescript } = loadCompiler()\n const sourceFile = typescript.createSourceFile(filePath, source, typescript.ScriptTarget.Latest)\n const imports: Array<ast.ImportNode> = []\n const exports: Array<ast.ExportNode> = []\n let header = ''\n let body = ''\n let cursor = 0\n\n for (const statement of sourceFile.statements) {\n const importNodes = toImportNodes(statement, filePath)\n const exportNodes = toExportNodes(statement)\n if (!importNodes.length && !exportNodes.length) {\n // Lifted declarations print above the body, so stop at the first one that stays in place to keep the evaluation order.\n if (typescript.isImportDeclaration(statement) || (typescript.isExportDeclaration(statement) && statement.moduleSpecifier)) break\n continue\n }\n\n const text = source.slice(cursor, statement.getStart(sourceFile))\n if (imports.length || exports.length) body += text\n else header = text\n imports.push(...importNodes)\n exports.push(...exportNodes)\n cursor = statement.getEnd()\n }\n\n return { header: header.trim(), imports, exports, body: `${body}${source.slice(cursor)}`.trim() }\n}\n\n/**\n * Joins the printed `nodes` with `separator`; a `Break` widens the next separator to a blank line, and leading, trailing and repeated breaks fold into one.\n *\n * Imperative on purpose: this runs once per source fragment and `map().filter().join()` showed up in deopt traces.\n */\nfunction printNodes({ nodes, separator }: { nodes: Array<ast.CodeNode> | undefined; separator: '\\n' | '\\n\\n' }): string {\n let result = ''\n let pendingBreak = false\n\n for (const node of nodes ?? []) {\n if (node.kind === 'Break') {\n pendingBreak = result !== ''\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (result) result += pendingBreak ? '\\n\\n' : separator\n result += text\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by two spaces.\n */\nfunction indentLines(text: string): string {\n if (!text) return ''\n return text\n .split('\\n')\n .map((line) => (line.trim() ? ` ${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Strips the common leading whitespace and the surrounding blank lines, counting tabs and spaces alike, so indented template literals start at column zero.\n */\nfunction 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\ntype Signature = {\n async?: boolean | null\n generics?: ast.FunctionNode['generics'] | ast.ArrowFunctionNode['generics']\n params?: string | null\n returnType?: string | null\n}\n\n/**\n * Renders `<T>(params): ReturnType`; an async function wraps its return type in `Promise<>`.\n */\nfunction signature({ async: isAsync, generics, params, returnType }: Signature): string {\n const genericsStr = generics ? `<${Array.isArray(generics) ? generics.join(', ') : generics}>` : ''\n const wrapped = isAsync ? `Promise<${returnType}>` : returnType\n const returnTypeStr = returnType ? `: ${wrapped}` : ''\n\n return `${genericsStr}(${params ?? ''})${returnTypeStr}`\n}\n\n/**\n * Puts the JSDoc block, when it renders to something, above `declaration`.\n */\nfunction withJSDoc({ jsDoc, declaration }: { jsDoc?: ast.JSDocNode | null; declaration: string }): string {\n const jsDocStr = jsDoc ? printJSDoc(jsDoc) : ''\n\n return jsDocStr ? `${jsDocStr}\\n${declaration}` : declaration\n}\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 { typescript, printer, sourceFile } = loadCompiler()\n const output = printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile)\n\n return output.replace(/\\r\\n/g, '\\n')\n}\n\n/**\n * Converts a {@link ast.JSDocNode} to a `/** … *\\/` block, dropping blank comments.\n */\nfunction printJSDoc(jsDoc: ast.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(/\\*\\//g, '* /').replace(/\\r/g, ''))\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 ast.ConstNode} to a `const` declaration, mirroring the `Const` component from `@kubb/renderer-jsx`.\n */\nfunction printConst(node: ast.ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}const ${name}${type ? `: ${type}` : ''} = ${printNodes({ nodes, separator: '\\n' })}${asConst ? ' as const' : ''}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.TypeNode} to a `type` alias, mirroring the `Type` component from `@kubb/renderer-jsx`.\n */\nfunction printType(node: ast.TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}type ${name} = ${printNodes({ nodes, separator: '\\n' })}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.FunctionNode} to a `function` declaration, mirroring the `Function` component from `@kubb/renderer-jsx`.\n */\nfunction printFunction(node: ast.FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const body = indentLines(printNodes({ nodes, separator: '\\n' }))\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}${isAsync ? 'async ' : ''}`\n const declaration = `${prefix}function ${name}${signature({ async: isAsync, generics, params, returnType })} {${body ? `\\n${body}\\n` : ''}}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts an {@link ast.ArrowFunctionNode} to a `const` arrow function, mirroring the `Function.Arrow` component from `@kubb/renderer-jsx`.\n */\nfunction printArrowFunction(node: ast.ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const body = printNodes({ nodes, separator: '\\n' })\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}`\n const declaration = `${prefix}const ${name} = ${isAsync ? 'async ' : ''}${signature({ async: isAsync, generics, params, returnType })}${arrowBody}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Dispatches a {@link ast.CodeNode} to the printer for its `kind`.\n */\nfunction printCodeNode(node: ast.CodeNode): string {\n switch (node.kind) {\n case 'Break':\n return ''\n case 'Text':\n case 'Jsx':\n return dedent(node.value)\n case 'Const':\n return printConst(node)\n case 'Type':\n return printType(node)\n case 'Function':\n return printFunction(node)\n case 'ArrowFunction':\n return printArrowFunction(node)\n }\n}\n\n/**\n * Prints a {@link ast.SourceNode} with a blank line between its top-level nodes.\n */\nexport function printSource(node: ast.SourceNode): string {\n return printNodes({ nodes: node.nodes, separator: '\\n\\n' })\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping embedded backslashes and quotes.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an `import` declaration (default, `* as`, or named with `{ a as b }`, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: Pick<ast.ImportNode, 'name' | 'path' | 'isTypeOnly' | 'isNameSpace'>): 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 … from` declaration (named, `* as name`, or wildcard, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printExport({ path, name, isTypeOnly = false, asAlias = false }: Pick<ast.ExportNode, 'name' | 'path' | 'isTypeOnly' | 'asAlias'>): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n return `export ${typePrefix}{ ${name.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n // An identifier cannot start with a digit, so swap the digit for `_`\n const parsedName = /^\\d/.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n return `export ${typePrefix}{ ${name} } from ${from}`\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import { ast, defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { compatibility } from '../kubb-extension.json'\nimport { version } from '../package.json'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath, splitModuleDeclarations } from './utils.ts'\n\nconst DEFAULT_EXTENSION: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''> = { '.ts': '' }\n\n/**\n * Options accepted by `parserTs` and `parserTsx`.\n */\nexport type ParserTsOptions = {\n /**\n * Rewrite extensions on relative `import`/`export` statements. Each key is the extension of a\n * generated file, and its value is the extension written on the relative specifiers in that\n * file. `''` drops it, and so does a generated file whose extension has no key. Package\n * specifiers stay unchanged. Also applies to relative paths in `copy` templates.\n *\n * Use `{ '.ts': '.js' }` for ESM output compiled to JavaScript, or `{ '.ts': '.ts' }` to run the\n * `.ts` files directly in Node.js or compile them with `rewriteRelativeImportExtensions`.\n *\n * @default { '.ts': '' }\n * @example\n * ```ts\n * parserTs({ extension: { '.ts': '.js' } }) // import './api.js' instead of './api'\n * parserTs({ extension: { '.ts': '.ts' } }) // import './api.ts' instead of './api'\n * ```\n */\n extension?: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''>\n}\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. Imports and exports\n * are rewritten based on each file's metadata and the `extension` option. The\n * `print` helper renders TypeScript compiler nodes with the TypeScript printer.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'typescript', version, compatibility },\n build({ extension = DEFAULT_EXTENSION }) {\n return {\n extNames: ['.ts', '.js'],\n print,\n parse(file) {\n const extname = extension[file.extname] || undefined\n\n const source = file.sources\n .map((item) => printSource(item))\n .filter(Boolean)\n .map((text) => text.trimEnd())\n .join('\\n\\n')\n\n const importLines = file.imports.map((item) =>\n printImport({\n ...item,\n path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, { extname }, Boolean(item.root)),\n }),\n )\n\n const exportLines = file.exports.map((item) => printExport({ ...item, path: resolveOutputPath(item.path, { extname }, item.path.startsWith('.')) }))\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 copy(file, source) {\n const { header, imports, exports, body } = splitModuleDeclarations(source, file.path)\n\n return {\n ...file,\n banner: [header, file.banner].filter(Boolean).join('\\n') || undefined,\n imports: [...file.imports, ...imports],\n exports: [...file.exports, ...exports],\n sources: [ast.factory.createSource({ nodes: [ast.factory.createText(body)] })],\n }\n },\n }\n },\n})\n","import { defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { parserTs, type ParserTsOptions } from './parserTs.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`, so it shares the\n * same `extension` option.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'tsx' },\n build: (options) => ({ ...parserTs(options), extNames: ['.tsx', '.jsx'] }),\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../kubb-extension.json","../package.json","../../../internals/utils/src/fs.ts","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["","","import { access, mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, relative, resolve } from 'node:path'\nimport { runtime } from './runtime.ts'\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 * Previously read content, or `null` when the file does not exist.\n * Omitting this value reads the file before writing.\n */\n stored?: string | null\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 * Whether `stored` already holds `source`, comparing on the trimmed text rather than the exact\n * bytes. Surrounding whitespace is what a formatter adds and what editors strip, and neither is a\n * reason to rewrite the file.\n *\n * Both sides are trimmed, so a storage that keeps bytes verbatim settles on the same answer as one\n * that normalizes what it stores. Trimming only `stored` would leave a source with leading\n * whitespace rewritten on every build, since the stored copy keeps the whitespace the comparison\n * has already dropped.\n */\nexport function matchesStored({ stored, source }: { stored: string; source: string }): boolean {\n return stored.trim() === source.trim()\n}\n\n/**\n * Writes `data` to `path`, trimming surrounding whitespace and ending the file with a single newline\n * the way prettier, biome, and oxfmt all do.\n * Skips the write when the trimmed content is empty, or when the file already holds that content.\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 the trimmed content plus a newline\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 content = `${trimmed}\\n`\n const resolved = resolve(path)\n let stored = options.stored\n\n if (stored === undefined) {\n if (runtime.isBun) {\n const file = Bun.file(resolved)\n stored = (await file.exists()) ? await file.text() : null\n } else {\n try {\n stored = await readFile(resolved, { encoding: 'utf-8' })\n } catch {\n /* file doesn't exist yet */\n stored = null\n }\n }\n }\n if (matchesStored({ stored: stored ?? '', source: trimmed })) return null\n\n if (runtime.isBun) {\n await Bun.write(resolved, content)\n return content\n }\n\n // Creating the directory up front costs a syscall per file, and every file after the first in a\n // directory pays it for nothing. Write first and only fall back when the directory is missing,\n // which also stays correct when something removed it mid-run.\n try {\n await writeFile(resolved, content, { encoding: 'utf-8' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n\n await mkdir(dirname(resolved), { recursive: true })\n await writeFile(resolved, content, { encoding: 'utf-8' })\n }\n\n if (options.sanity) {\n const savedData = await readFile(resolved, { encoding: 'utf-8' })\n if (savedData !== content) {\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 content\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 * Resolves to `true` when `path` is `parent` itself or nested inside it. Both sides are resolved\n * to absolute paths first, so relative and `..`-containing inputs compare correctly.\n *\n * Guards a destructive or an out-of-tree operation: before wiping an output directory, check that\n * it does not contain the project root, and before loading a path a caller supplied, check that it\n * did not escape the directory it is allowed to read from.\n *\n * @example\n * isPathInside('./src/gen', '.') // true — nested inside the root\n * isPathInside('.', '.') // true — the same directory counts as inside\n * isPathInside('.', './src/gen') // false — the root is not inside its own output\n * isPathInside('../other', '.') // false — escapes the root\n */\nexport function isPathInside(path: string, parent: string): boolean {\n const resolvedPath = resolve(path)\n const resolvedParent = resolve(parent)\n if (resolvedPath === resolvedParent) {\n return true\n }\n\n const rel = relative(resolvedParent, resolvedPath)\n\n return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)\n}\n","import { createRequire } from 'node:module'\nimport { dirname, relative, resolve } from 'node:path'\nimport { toPosixPath, trimExtName } from '@internals/utils'\nimport { ast } from '@kubb/kit'\nimport type * as ts from 'typescript'\n\ntype Compiler = {\n typescript: typeof ts\n printer: ts.Printer\n sourceFile: ts.SourceFile\n}\n\nlet compiler: Compiler | undefined\n\n/**\n * Loads TypeScript on the first `print` or `copy`; `parse` is string templating and never needs it.\n *\n * Loaded with `require`, not `import`: when ESM imports a CommonJS package, Node keeps a second copy of its source\n * to detect named exports, and for TypeScript that copy is about 9 MB.\n */\nfunction loadCompiler(): Compiler {\n if (compiler) return compiler\n\n const typescript: typeof ts = createRequire(import.meta.url)('typescript')\n\n compiler = {\n typescript,\n // One printer serves every call; printing does not mutate the source file, which only lends its compiler options\n printer: typescript.createPrinter({\n omitTrailingSemicolon: true,\n newLine: typescript.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n }),\n sourceFile: typescript.createSourceFile('print.tsx', '', typescript.ScriptTarget.ES2022, true, typescript.ScriptKind.TSX),\n }\n\n return compiler\n}\n\n/**\n * Module specifier that imports `filePath` from the file at `root`: POSIX, relative to that file's directory, `./`-prefixed unless it climbs with `../`.\n */\nexport function getRelativePath(root: string, filePath: string): string {\n const slashed = toPosixPath(relative(dirname(root), filePath))\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\n/**\n * Swaps the extension of a relative import/export path for `options.extname`; package specifiers and extension-less paths stay as-is.\n */\nexport function resolveOutputPath(path: string, options: { extname?: string } | undefined, rootAware: boolean): string {\n const hasExtname = /\\.[^/.]+$/.test(path)\n if (rootAware && options?.extname && hasExtname) {\n return `${trimExtName(path)}${options.extname}`\n }\n return rootAware ? trimExtName(path) : path\n}\n\n/**\n * Converts an import specifier into an `ImportNode` name, keeping the quotes of a string-literal name (`{ 'a-b' as ab }`).\n */\nfunction toImportName(element: ts.ImportSpecifier): string | { propertyName: string; name: string } {\n if (!element.propertyName) return element.name.text\n\n const { typescript } = loadCompiler()\n const { propertyName } = element\n return { propertyName: typescript.isStringLiteral(propertyName) ? quoteModulePath(propertyName.text) : propertyName.text, name: element.name.text }\n}\n\n/**\n * Converts an `import` declaration into `ImportNode`s. Side-effect imports and imports with attributes stay as written.\n */\nfunction toImportNodes(statement: ts.Statement, filePath: string): Array<ast.ImportNode> {\n const { typescript } = loadCompiler()\n if (!typescript.isImportDeclaration(statement) || !statement.importClause || !typescript.isStringLiteral(statement.moduleSpecifier) || statement.attributes)\n return []\n\n const { name, namedBindings, phaseModifier } = statement.importClause\n const specifier = statement.moduleSpecifier.text\n const target = specifier.startsWith('.') ? { path: resolve(dirname(filePath), specifier), root: filePath } : { path: specifier }\n const isTypeOnly = phaseModifier === typescript.SyntaxKind.TypeKeyword\n const nodes: Array<ast.ImportNode> = []\n\n if (name) nodes.push(ast.factory.createImport({ name: name.text, ...target, isTypeOnly }))\n if (namedBindings && typescript.isNamespaceImport(namedBindings)) {\n nodes.push(ast.factory.createImport({ name: namedBindings.name.text, ...target, isTypeOnly, isNameSpace: true }))\n }\n if (namedBindings && typescript.isNamedImports(namedBindings)) {\n const values = namedBindings.elements.filter((element) => !element.isTypeOnly)\n const types = namedBindings.elements.filter((element) => element.isTypeOnly)\n if (values.length) nodes.push(ast.factory.createImport({ name: values.map(toImportName), ...target, isTypeOnly }))\n if (types.length) nodes.push(ast.factory.createImport({ name: types.map(toImportName), ...target, isTypeOnly: true }))\n }\n\n return nodes\n}\n\n/**\n * Converts an `export … from` declaration into `ExportNode`s. Forms `printExport` cannot print stay as written.\n */\nfunction toExportNodes(statement: ts.Statement): Array<ast.ExportNode> {\n const { typescript } = loadCompiler()\n if (\n !typescript.isExportDeclaration(statement) ||\n !statement.moduleSpecifier ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n statement.attributes\n )\n return []\n\n const { exportClause, isTypeOnly } = statement\n const path = statement.moduleSpecifier.text\n\n if (!exportClause) return [ast.factory.createExport({ path, isTypeOnly })]\n if (typescript.isNamespaceExport(exportClause)) return [ast.factory.createExport({ name: exportClause.name.text, path, isTypeOnly, asAlias: true })]\n if (exportClause.elements.some((element) => element.propertyName || element.isTypeOnly || typescript.isStringLiteral(element.name))) return []\n\n return [ast.factory.createExport({ name: exportClause.elements.map((element) => element.name.text), path, isTypeOnly })]\n}\n\ntype ModuleDeclarations = {\n header: string\n imports: Array<ast.ImportNode>\n exports: Array<ast.ExportNode>\n body: string\n}\n\n/**\n * Splits `source` into its lifted `import`/`export … from` nodes, the `header` above the first one (shebang, directives, comments) and the rest as `body`.\n */\nexport function splitModuleDeclarations(source: string, filePath: string): ModuleDeclarations {\n const { typescript } = loadCompiler()\n const sourceFile = typescript.createSourceFile(filePath, source, typescript.ScriptTarget.Latest)\n const imports: Array<ast.ImportNode> = []\n const exports: Array<ast.ExportNode> = []\n let header = ''\n let body = ''\n let cursor = 0\n\n for (const statement of sourceFile.statements) {\n const importNodes = toImportNodes(statement, filePath)\n const exportNodes = toExportNodes(statement)\n if (!importNodes.length && !exportNodes.length) {\n // Lifted declarations print above the body, so stop at the first one that stays in place to keep the evaluation order.\n if (typescript.isImportDeclaration(statement) || (typescript.isExportDeclaration(statement) && statement.moduleSpecifier)) break\n continue\n }\n\n const text = source.slice(cursor, statement.getStart(sourceFile))\n if (imports.length || exports.length) body += text\n else header = text\n imports.push(...importNodes)\n exports.push(...exportNodes)\n cursor = statement.getEnd()\n }\n\n return { header: header.trim(), imports, exports, body: `${body}${source.slice(cursor)}`.trim() }\n}\n\n/**\n * Joins the printed `nodes` with `separator`; a `Break` widens the next separator to a blank line, and leading, trailing and repeated breaks fold into one.\n *\n * Imperative on purpose: this runs once per source fragment and `map().filter().join()` showed up in deopt traces.\n */\nfunction printNodes({ nodes, separator }: { nodes: Array<ast.CodeNode> | undefined; separator: '\\n' | '\\n\\n' }): string {\n let result = ''\n let pendingBreak = false\n\n for (const node of nodes ?? []) {\n if (node.kind === 'Break') {\n pendingBreak = result !== ''\n continue\n }\n\n const text = printCodeNode(node)\n if (!text) continue\n\n if (result) result += pendingBreak ? '\\n\\n' : separator\n result += text\n pendingBreak = false\n }\n\n return result\n}\n\n/**\n * Indents every non-empty line of `text` by two spaces.\n */\nfunction indentLines(text: string): string {\n if (!text) return ''\n return text\n .split('\\n')\n .map((line) => (line.trim() ? ` ${line}` : ''))\n .join('\\n')\n}\n\n/**\n * Strips the common leading whitespace and the surrounding blank lines, counting tabs and spaces alike, so indented template literals start at column zero.\n */\nfunction 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\ntype Signature = {\n async?: boolean | null\n generics?: ast.FunctionNode['generics'] | ast.ArrowFunctionNode['generics']\n params?: string | null\n returnType?: string | null\n}\n\n/**\n * Renders `<T>(params): ReturnType`; an async function wraps its return type in `Promise<>`.\n */\nfunction signature({ async: isAsync, generics, params, returnType }: Signature): string {\n const genericsStr = generics ? `<${Array.isArray(generics) ? generics.join(', ') : generics}>` : ''\n const wrapped = isAsync ? `Promise<${returnType}>` : returnType\n const returnTypeStr = returnType ? `: ${wrapped}` : ''\n\n return `${genericsStr}(${params ?? ''})${returnTypeStr}`\n}\n\n/**\n * Puts the JSDoc block, when it renders to something, above `declaration`.\n */\nfunction withJSDoc({ jsDoc, declaration }: { jsDoc?: ast.JSDocNode | null; declaration: string }): string {\n const jsDocStr = jsDoc ? printJSDoc(jsDoc) : ''\n\n return jsDocStr ? `${jsDocStr}\\n${declaration}` : declaration\n}\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 { typescript, printer, sourceFile } = loadCompiler()\n const output = printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile)\n\n return output.replace(/\\r\\n/g, '\\n')\n}\n\n/**\n * Converts a {@link ast.JSDocNode} to a `/** … *\\/` block, dropping blank comments.\n */\nfunction printJSDoc(jsDoc: ast.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(/\\*\\//g, '* /').replace(/\\r/g, ''))\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 ast.ConstNode} to a `const` declaration, mirroring the `Const` component from `@kubb/renderer-jsx`.\n */\nfunction printConst(node: ast.ConstNode): string {\n const { name, export: canExport, type, JSDoc, asConst, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}const ${name}${type ? `: ${type}` : ''} = ${printNodes({ nodes, separator: '\\n' })}${asConst ? ' as const' : ''}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.TypeNode} to a `type` alias, mirroring the `Type` component from `@kubb/renderer-jsx`.\n */\nfunction printType(node: ast.TypeNode): string {\n const { name, export: canExport, JSDoc, nodes } = node\n\n const declaration = `${canExport ? 'export ' : ''}type ${name} = ${printNodes({ nodes, separator: '\\n' })}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts a {@link ast.FunctionNode} to a `function` declaration, mirroring the `Function` component from `@kubb/renderer-jsx`.\n */\nfunction printFunction(node: ast.FunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes } = node\n\n const body = indentLines(printNodes({ nodes, separator: '\\n' }))\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}${isAsync ? 'async ' : ''}`\n const declaration = `${prefix}function ${name}${signature({ async: isAsync, generics, params, returnType })} {${body ? `\\n${body}\\n` : ''}}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Converts an {@link ast.ArrowFunctionNode} to a `const` arrow function, mirroring the `Function.Arrow` component from `@kubb/renderer-jsx`.\n */\nfunction printArrowFunction(node: ast.ArrowFunctionNode): string {\n const { name, default: isDefault, export: canExport, async: isAsync, generics, params, returnType, JSDoc, nodes, singleLine } = node\n\n const body = printNodes({ nodes, separator: '\\n' })\n const arrowBody = singleLine ? ` => ${body}` : body ? ` => {\\n${indentLines(body)}\\n}` : ' => {}'\n const prefix = `${canExport ? 'export ' : ''}${isDefault ? 'default ' : ''}`\n const declaration = `${prefix}const ${name} = ${isAsync ? 'async ' : ''}${signature({ async: isAsync, generics, params, returnType })}${arrowBody}`\n\n return withJSDoc({ jsDoc: JSDoc, declaration })\n}\n\n/**\n * Dispatches a {@link ast.CodeNode} to the printer for its `kind`.\n */\nfunction printCodeNode(node: ast.CodeNode): string {\n switch (node.kind) {\n case 'Break':\n return ''\n case 'Text':\n case 'Jsx':\n return dedent(node.value)\n case 'Const':\n return printConst(node)\n case 'Type':\n return printType(node)\n case 'Function':\n return printFunction(node)\n case 'ArrowFunction':\n return printArrowFunction(node)\n }\n}\n\n/**\n * Prints a {@link ast.SourceNode} with a blank line between its top-level nodes.\n */\nexport function printSource(node: ast.SourceNode): string {\n return printNodes({ nodes: node.nodes, separator: '\\n\\n' })\n}\n\n/**\n * Wraps a module specifier in single quotes, escaping embedded backslashes and quotes.\n */\nfunction quoteModulePath(path: string): string {\n return `'${path.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n/**\n * Renders an `import` declaration (default, `* as`, or named with `{ a as b }`, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printImport({\n name,\n path,\n isTypeOnly = false,\n isNameSpace = false,\n}: Pick<ast.ImportNode, 'name' | 'path' | 'isTypeOnly' | 'isNameSpace'>): 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 … from` declaration (named, `* as name`, or wildcard, each optionally `type`-only). `path` is used verbatim, so resolve it first.\n */\nexport function printExport({ path, name, isTypeOnly = false, asAlias = false }: Pick<ast.ExportNode, 'name' | 'path' | 'isTypeOnly' | 'asAlias'>): string {\n const typePrefix = isTypeOnly ? 'type ' : ''\n const from = quoteModulePath(path)\n\n if (Array.isArray(name)) {\n return `export ${typePrefix}{ ${name.join(', ')} } from ${from}`\n }\n\n if (asAlias && name) {\n // An identifier cannot start with a digit, so swap the digit for `_`\n const parsedName = /^\\d/.test(name) ? `_${name.slice(1)}` : name\n return `export ${typePrefix}* as ${parsedName} from ${from}`\n }\n\n if (name) {\n return `export ${typePrefix}{ ${name} } from ${from}`\n }\n\n return `export ${typePrefix}* from ${from}`\n}\n","import { ast, defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { compatibility } from '../kubb-extension.json'\nimport { version } from '../package.json'\nimport { getRelativePath, print, printExport, printImport, printSource, resolveOutputPath, splitModuleDeclarations } from './utils.ts'\n\nconst DEFAULT_EXTENSION: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''> = { '.ts': '' }\n\n/**\n * Options accepted by `parserTs` and `parserTsx`.\n */\nexport type ParserTsOptions = {\n /**\n * Rewrite extensions on relative `import`/`export` statements. Each key is the extension of a\n * generated file, and its value is the extension written on the relative specifiers in that\n * file. `''` drops it, and so does a generated file whose extension has no key. Package\n * specifiers stay unchanged. Also applies to relative paths in `copy` templates.\n *\n * Use `{ '.ts': '.js' }` for ESM output compiled to JavaScript, or `{ '.ts': '.ts' }` to run the\n * `.ts` files directly in Node.js or compile them with `rewriteRelativeImportExtensions`.\n *\n * @default { '.ts': '' }\n * @example\n * ```ts\n * parserTs({ extension: { '.ts': '.js' } }) // import './api.js' instead of './api'\n * parserTs({ extension: { '.ts': '.ts' } }) // import './api.ts' instead of './api'\n * ```\n */\n extension?: Record<ast.FileNode['extname'], ast.FileNode['extname'] | ''>\n}\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. Imports and exports\n * are rewritten based on each file's metadata and the `extension` option. The\n * `print` helper renders TypeScript compiler nodes with the TypeScript printer.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTs()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTs = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'typescript', version, compatibility, issues: 'https://github.com/kubb-labs/kubb/issues' },\n build({ extension = DEFAULT_EXTENSION }) {\n return {\n extNames: ['.ts', '.js'],\n print,\n parse(file) {\n const extname = extension[file.extname] || undefined\n\n const source = file.sources\n .map((item) => printSource(item))\n .filter(Boolean)\n .map((text) => text.trimEnd())\n .join('\\n\\n')\n\n const importLines = file.imports.map((item) =>\n printImport({\n ...item,\n path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, { extname }, Boolean(item.root)),\n }),\n )\n\n const exportLines = file.exports.map((item) => printExport({ ...item, path: resolveOutputPath(item.path, { extname }, item.path.startsWith('.')) }))\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 copy(file, source) {\n const { header, imports, exports, body } = splitModuleDeclarations(source, file.path)\n\n return {\n ...file,\n banner: [header, file.banner].filter(Boolean).join('\\n') || undefined,\n imports: [...file.imports, ...imports],\n exports: [...file.exports, ...exports],\n sources: [ast.factory.createSource({ nodes: [ast.factory.createText(body)] })],\n }\n },\n }\n },\n})\n","import { defineExtension } from '@kubb/kit'\nimport type * as ts from 'typescript'\nimport { parserTs, type ParserTsOptions } from './parserTs.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`, so it shares the\n * same `extension` option.\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: './petStore.yaml',\n * output: { path: './src/gen' },\n * adapter: adapterOas(),\n * parsers: [parserTsx()],\n * plugins: [],\n * })\n * ```\n */\nexport const parserTsx = defineExtension<ParserTsOptions, object, ts.Node>({\n kind: 'parser',\n meta: { name: 'tsx', issues: 'https://github.com/kubb-labs/kubb/issues' },\n build: (options) => ({ ...parserTs(options), extNames: ['.tsx', '.jsx'] }),\n})\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/parser-ts",
3
- "version": "5.9.0",
3
+ "version": "5.9.1",
4
4
  "description": "TypeScript and TSX source file parser for Kubb. Converts AST nodes into formatted source strings using the TypeScript compiler API.",
5
5
  "keywords": [
6
6
  "codegen",
@@ -59,7 +59,7 @@
59
59
  "registry": "https://registry.npmjs.org/"
60
60
  },
61
61
  "dependencies": {
62
- "@kubb/kit": "5.9.0",
62
+ "@kubb/kit": "5.9.1",
63
63
  "typescript": "^6.0.3"
64
64
  },
65
65
  "devDependencies": {