@kubb/parser-ts 5.9.3 → 5.9.4

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
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#endregion
3
- let _kubb_kit = require("@kubb/kit");
3
+ let _kubb_ast = require("@kubb/ast");
4
+ let _kubb_core = require("@kubb/core");
4
5
  let node_module = require("node:module");
5
6
  let node_path = require("node:path");
6
7
  //#region kubb-extension.json
@@ -10,41 +11,7 @@ var compatibility = {
10
11
  };
11
12
  //#endregion
12
13
  //#region package.json
13
- var version = "5.9.3";
14
- //#endregion
15
- //#region ../../internals/utils/src/fs.ts
16
- /**
17
- * Converts a filesystem path to use POSIX (`/`) separators.
18
- *
19
- * Most of the codebase compares and composes paths as strings (prefix matching, joining for
20
- * import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated
21
- * paths, but on Windows it returns `\`-separated paths, which breaks every such comparison.
22
- *
23
- * Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the
24
- * code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is
25
- * exercisable from POSIX CI.
26
- *
27
- * @example
28
- * toPosixPath('C:\\repo\\src\\pet.ts') // 'C:/repo/src/pet.ts'
29
- */
30
- function toPosixPath(filePath) {
31
- return filePath.replaceAll("\\", "/");
32
- }
33
- /**
34
- * Strips the file extension from a path or file name.
35
- * Only removes the last `.ext` segment when the dot is not part of a directory name.
36
- *
37
- * @example
38
- * trimExtName('petStore.ts') // 'petStore'
39
- * trimExtName('/src/models/pet.ts') // '/src/models/pet'
40
- * trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
41
- * trimExtName('noExtension') // 'noExtension'
42
- */
43
- function trimExtName(text) {
44
- const dotIndex = text.lastIndexOf(".");
45
- if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
46
- return text;
47
- }
14
+ var version = "5.9.4";
48
15
  //#endregion
49
16
  //#region src/utils.ts
50
17
  let compiler;
@@ -73,16 +40,16 @@ function loadCompiler() {
73
40
  * Module specifier that imports `filePath` from the file at `root`: POSIX, relative to that file's directory, `./`-prefixed unless it climbs with `../`.
74
41
  */
75
42
  function getRelativePath(root, filePath) {
76
- const slashed = toPosixPath((0, node_path.relative)((0, node_path.dirname)(root), filePath));
43
+ const slashed = (0, node_path.relative)((0, node_path.dirname)(root), filePath).replaceAll("\\", "/");
77
44
  return slashed.startsWith("../") ? slashed : `./${slashed}`;
78
45
  }
79
46
  /**
80
- * Swaps the extension of a relative import/export path for `options.extname`; package specifiers and extension-less paths stay as-is.
47
+ * Swaps the extension of a relative import/export path for `extname`. Package specifiers and extension-less paths stay as-is.
81
48
  */
82
- function resolveOutputPath(path, options, rootAware) {
83
- const hasExtname = /\.[^/.]+$/.test(path);
84
- if (rootAware && options?.extname && hasExtname) return `${trimExtName(path)}${options.extname}`;
85
- return rootAware ? trimExtName(path) : path;
49
+ function resolveOutputPath(path, extname, rootAware) {
50
+ if (!rootAware) return path;
51
+ const current = (0, node_path.extname)(path);
52
+ return current ? `${path.slice(0, -current.length)}${extname ?? ""}` : path;
86
53
  }
87
54
  /**
88
55
  * Converts an import specifier into an `ImportNode` name, keeping the quotes of a string-literal name (`{ 'a-b' as ab }`).
@@ -110,12 +77,12 @@ function toImportNodes(statement, filePath) {
110
77
  } : { path: specifier };
111
78
  const isTypeOnly = phaseModifier === typescript.SyntaxKind.TypeKeyword;
112
79
  const nodes = [];
113
- if (name) nodes.push(_kubb_kit.ast.factory.createImport({
80
+ if (name) nodes.push(_kubb_ast.ast.factory.createImport({
114
81
  name: name.text,
115
82
  ...target,
116
83
  isTypeOnly
117
84
  }));
118
- if (namedBindings && typescript.isNamespaceImport(namedBindings)) nodes.push(_kubb_kit.ast.factory.createImport({
85
+ if (namedBindings && typescript.isNamespaceImport(namedBindings)) nodes.push(_kubb_ast.ast.factory.createImport({
119
86
  name: namedBindings.name.text,
120
87
  ...target,
121
88
  isTypeOnly,
@@ -124,12 +91,12 @@ function toImportNodes(statement, filePath) {
124
91
  if (namedBindings && typescript.isNamedImports(namedBindings)) {
125
92
  const values = namedBindings.elements.filter((element) => !element.isTypeOnly);
126
93
  const types = namedBindings.elements.filter((element) => element.isTypeOnly);
127
- if (values.length) nodes.push(_kubb_kit.ast.factory.createImport({
94
+ if (values.length) nodes.push(_kubb_ast.ast.factory.createImport({
128
95
  name: values.map(toImportName),
129
96
  ...target,
130
97
  isTypeOnly
131
98
  }));
132
- if (types.length) nodes.push(_kubb_kit.ast.factory.createImport({
99
+ if (types.length) nodes.push(_kubb_ast.ast.factory.createImport({
133
100
  name: types.map(toImportName),
134
101
  ...target,
135
102
  isTypeOnly: true
@@ -145,18 +112,18 @@ function toExportNodes(statement) {
145
112
  if (!typescript.isExportDeclaration(statement) || !statement.moduleSpecifier || !typescript.isStringLiteral(statement.moduleSpecifier) || statement.attributes) return [];
146
113
  const { exportClause, isTypeOnly } = statement;
147
114
  const path = statement.moduleSpecifier.text;
148
- if (!exportClause) return [_kubb_kit.ast.factory.createExport({
115
+ if (!exportClause) return [_kubb_ast.ast.factory.createExport({
149
116
  path,
150
117
  isTypeOnly
151
118
  })];
152
- if (typescript.isNamespaceExport(exportClause)) return [_kubb_kit.ast.factory.createExport({
119
+ if (typescript.isNamespaceExport(exportClause)) return [_kubb_ast.ast.factory.createExport({
153
120
  name: exportClause.name.text,
154
121
  path,
155
122
  isTypeOnly,
156
123
  asAlias: true
157
124
  })];
158
125
  if (exportClause.elements.some((element) => element.propertyName || element.isTypeOnly || typescript.isStringLiteral(element.name))) return [];
159
- return [_kubb_kit.ast.factory.createExport({
126
+ return [_kubb_ast.ast.factory.createExport({
160
127
  name: exportClause.elements.map((element) => element.name.text),
161
128
  path,
162
129
  isTypeOnly
@@ -260,7 +227,7 @@ function print(...elements) {
260
227
  const filtered = elements.filter(Boolean);
261
228
  if (filtered.length === 0) return "";
262
229
  const { typescript, printer, sourceFile } = loadCompiler();
263
- return printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile).replace(/\r\n/g, "\n");
230
+ return printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile);
264
231
  }
265
232
  /**
266
233
  * Converts a {@link ast.JSDocNode} to a `/** … *\/` block, dropping blank comments.
@@ -423,7 +390,7 @@ const DEFAULT_EXTENSION = { ".ts": "" };
423
390
  * })
424
391
  * ```
425
392
  */
426
- const parserTs = (0, _kubb_kit.defineExtension)({
393
+ const parserTs = (0, _kubb_core.defineExtension)({
427
394
  kind: "parser",
428
395
  meta: {
429
396
  name: "typescript",
@@ -440,11 +407,11 @@ const parserTs = (0, _kubb_kit.defineExtension)({
440
407
  const source = file.sources.map((item) => printSource(item)).filter(Boolean).map((text) => text.trimEnd()).join("\n\n");
441
408
  const importLines = file.imports.map((item) => printImport({
442
409
  ...item,
443
- path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, { extname }, Boolean(item.root))
410
+ path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, extname, Boolean(item.root))
444
411
  }));
445
412
  const exportLines = file.exports.map((item) => printExport({
446
413
  ...item,
447
- path: resolveOutputPath(item.path, { extname }, item.path.startsWith("."))
414
+ path: resolveOutputPath(item.path, extname, item.path.startsWith("."))
448
415
  }));
449
416
  const importExportBlock = [...importLines, ...exportLines].join("\n");
450
417
  return [
@@ -461,7 +428,7 @@ const parserTs = (0, _kubb_kit.defineExtension)({
461
428
  banner: [header, file.banner].filter(Boolean).join("\n") || void 0,
462
429
  imports: [...file.imports, ...imports],
463
430
  exports: [...file.exports, ...exports],
464
- sources: [_kubb_kit.ast.factory.createSource({ nodes: [_kubb_kit.ast.factory.createText(body)] })]
431
+ sources: [_kubb_ast.ast.factory.createSource({ nodes: [_kubb_ast.ast.factory.createText(body)] })]
465
432
  };
466
433
  }
467
434
  };
@@ -492,7 +459,7 @@ const parserTs = (0, _kubb_kit.defineExtension)({
492
459
  * })
493
460
  * ```
494
461
  */
495
- const parserTsx = (0, _kubb_kit.defineExtension)({
462
+ const parserTsx = (0, _kubb_core.defineExtension)({
496
463
  kind: "parser",
497
464
  meta: {
498
465
  name: "tsx",
@@ -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, 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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"}
1
+ {"version":3,"file":"index.cjs","names":["createRequire","relative","dirname","getExtname","resolve","ast","defineExtension","ast","defineExtension"],"sources":["../kubb-extension.json","../package.json","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["","","import { createRequire } from 'node:module'\nimport { dirname, extname as getExtname, relative, resolve } from 'node:path'\nimport { ast } from '@kubb/ast'\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 = relative(dirname(root), filePath).replaceAll('\\\\', '/')\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\n/**\n * Swaps the extension of a relative import/export path for `extname`. Package specifiers and extension-less paths stay as-is.\n */\nexport function resolveOutputPath(path: string, extname: string | undefined, rootAware: boolean): string {\n if (!rootAware) return path\n const current = getExtname(path)\n return current ? `${path.slice(0, -current.length)}${extname ?? ''}` : 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\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(\n source: string,\n filePath: string,\n): { header: string; imports: Array<ast.ImportNode>; exports: Array<ast.ExportNode>; body: string } {\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\n/**\n * Renders `<T>(params): ReturnType`; an async function wraps its return type in `Promise<>`.\n */\nfunction signature({ async: isAsync, generics, params, returnType }: Pick<ast.FunctionNode, 'async' | 'generics' | 'params' | 'returnType'>): 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 return printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile)\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 } from '@kubb/ast'\nimport { defineExtension } from '@kubb/core'\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/core'\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.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./rolldown-runtime-CRm0XQPb.js";
2
- import { ast } from "@kubb/kit";
2
+ import { ast } from "@kubb/ast";
3
3
  import * as ts from "typescript";
4
4
  //#region src/parserTs.d.ts
5
5
  /**
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import "./rolldown-runtime-CRm0XQPb.js";
2
2
  import { createRequire } from "node:module";
3
- import { ast, defineExtension } from "@kubb/kit";
4
- import { dirname, relative, resolve } from "node:path";
3
+ import { ast } from "@kubb/ast";
4
+ import { defineExtension } from "@kubb/core";
5
+ import { dirname, extname, relative, resolve } from "node:path";
5
6
  //#region kubb-extension.json
6
7
  var compatibility = {
7
8
  "kubb": ">=5.8.3",
@@ -9,41 +10,7 @@ var compatibility = {
9
10
  };
10
11
  //#endregion
11
12
  //#region package.json
12
- var version = "5.9.3";
13
- //#endregion
14
- //#region ../../internals/utils/src/fs.ts
15
- /**
16
- * Converts a filesystem path to use POSIX (`/`) separators.
17
- *
18
- * Most of the codebase compares and composes paths as strings (prefix matching, joining for
19
- * import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated
20
- * paths, but on Windows it returns `\`-separated paths, which breaks every such comparison.
21
- *
22
- * Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the
23
- * code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is
24
- * exercisable from POSIX CI.
25
- *
26
- * @example
27
- * toPosixPath('C:\\repo\\src\\pet.ts') // 'C:/repo/src/pet.ts'
28
- */
29
- function toPosixPath(filePath) {
30
- return filePath.replaceAll("\\", "/");
31
- }
32
- /**
33
- * Strips the file extension from a path or file name.
34
- * Only removes the last `.ext` segment when the dot is not part of a directory name.
35
- *
36
- * @example
37
- * trimExtName('petStore.ts') // 'petStore'
38
- * trimExtName('/src/models/pet.ts') // '/src/models/pet'
39
- * trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
40
- * trimExtName('noExtension') // 'noExtension'
41
- */
42
- function trimExtName(text) {
43
- const dotIndex = text.lastIndexOf(".");
44
- if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
45
- return text;
46
- }
13
+ var version = "5.9.4";
47
14
  //#endregion
48
15
  //#region src/utils.ts
49
16
  let compiler;
@@ -72,16 +39,16 @@ function loadCompiler() {
72
39
  * Module specifier that imports `filePath` from the file at `root`: POSIX, relative to that file's directory, `./`-prefixed unless it climbs with `../`.
73
40
  */
74
41
  function getRelativePath(root, filePath) {
75
- const slashed = toPosixPath(relative(dirname(root), filePath));
42
+ const slashed = relative(dirname(root), filePath).replaceAll("\\", "/");
76
43
  return slashed.startsWith("../") ? slashed : `./${slashed}`;
77
44
  }
78
45
  /**
79
- * Swaps the extension of a relative import/export path for `options.extname`; package specifiers and extension-less paths stay as-is.
46
+ * Swaps the extension of a relative import/export path for `extname`. Package specifiers and extension-less paths stay as-is.
80
47
  */
81
- function resolveOutputPath(path, options, rootAware) {
82
- const hasExtname = /\.[^/.]+$/.test(path);
83
- if (rootAware && options?.extname && hasExtname) return `${trimExtName(path)}${options.extname}`;
84
- return rootAware ? trimExtName(path) : path;
48
+ function resolveOutputPath(path, extname$1, rootAware) {
49
+ if (!rootAware) return path;
50
+ const current = extname(path);
51
+ return current ? `${path.slice(0, -current.length)}${extname$1 ?? ""}` : path;
85
52
  }
86
53
  /**
87
54
  * Converts an import specifier into an `ImportNode` name, keeping the quotes of a string-literal name (`{ 'a-b' as ab }`).
@@ -259,7 +226,7 @@ function print(...elements) {
259
226
  const filtered = elements.filter(Boolean);
260
227
  if (filtered.length === 0) return "";
261
228
  const { typescript, printer, sourceFile } = loadCompiler();
262
- return printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile).replace(/\r\n/g, "\n");
229
+ return printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile);
263
230
  }
264
231
  /**
265
232
  * Converts a {@link ast.JSDocNode} to a `/** … *\/` block, dropping blank comments.
@@ -439,11 +406,11 @@ const parserTs = defineExtension({
439
406
  const source = file.sources.map((item) => printSource(item)).filter(Boolean).map((text) => text.trimEnd()).join("\n\n");
440
407
  const importLines = file.imports.map((item) => printImport({
441
408
  ...item,
442
- path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, { extname }, Boolean(item.root))
409
+ path: resolveOutputPath(item.root ? getRelativePath(item.root, item.path) : item.path, extname, Boolean(item.root))
443
410
  }));
444
411
  const exportLines = file.exports.map((item) => printExport({
445
412
  ...item,
446
- path: resolveOutputPath(item.path, { extname }, item.path.startsWith("."))
413
+ path: resolveOutputPath(item.path, extname, item.path.startsWith("."))
447
414
  }));
448
415
  const importExportBlock = [...importLines, ...exportLines].join("\n");
449
416
  return [
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, 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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"}
1
+ {"version":3,"file":"index.js","names":["getExtname","extname"],"sources":["../kubb-extension.json","../package.json","../src/utils.ts","../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["","","import { createRequire } from 'node:module'\nimport { dirname, extname as getExtname, relative, resolve } from 'node:path'\nimport { ast } from '@kubb/ast'\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 = relative(dirname(root), filePath).replaceAll('\\\\', '/')\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\n/**\n * Swaps the extension of a relative import/export path for `extname`. Package specifiers and extension-less paths stay as-is.\n */\nexport function resolveOutputPath(path: string, extname: string | undefined, rootAware: boolean): string {\n if (!rootAware) return path\n const current = getExtname(path)\n return current ? `${path.slice(0, -current.length)}${extname ?? ''}` : 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\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(\n source: string,\n filePath: string,\n): { header: string; imports: Array<ast.ImportNode>; exports: Array<ast.ExportNode>; body: string } {\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\n/**\n * Renders `<T>(params): ReturnType`; an async function wraps its return type in `Promise<>`.\n */\nfunction signature({ async: isAsync, generics, params, returnType }: Pick<ast.FunctionNode, 'async' | 'generics' | 'params' | 'returnType'>): 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 return printer.printList(typescript.ListFormat.MultiLine, typescript.factory.createNodeArray(filtered), sourceFile)\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 } from '@kubb/ast'\nimport { defineExtension } from '@kubb/core'\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/core'\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.3",
3
+ "version": "5.9.4",
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,12 +59,10 @@
59
59
  "registry": "https://registry.npmjs.org/"
60
60
  },
61
61
  "dependencies": {
62
- "@kubb/kit": "5.9.3",
62
+ "@kubb/ast": "5.9.4",
63
+ "@kubb/core": "5.9.4",
63
64
  "typescript": "^6.0.3"
64
65
  },
65
- "devDependencies": {
66
- "@internals/utils": "0.0.1"
67
- },
68
66
  "engines": {
69
67
  "node": ">=22"
70
68
  },