@kubb/parser-ts 4.1.4 → 5.0.0-alpha.31

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/LICENSE CHANGED
@@ -1,21 +1,14 @@
1
- MIT License
1
+ Copyright (c) 2026 Stijn Van Hulle
2
2
 
3
- Copyright (c) 2025 Stijn Van Hulle
3
+ This repository contains software under two licenses:
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ 1. Most of the code in this repository is licensed under the
6
+ MIT License see licenses/LICENSE-MIT for the full license text.
11
7
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
8
+ 2. The following components are licensed under the
9
+ GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)
10
+ — see licenses/LICENSE-AGPL-3.0 for the full license text:
14
11
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
12
+ - packages/agent (published as @kubb/agent)
13
+
14
+ Each package's own LICENSE file or package.json specifies its applicable license.
@@ -0,0 +1,8 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __name = (target, value) => __defProp(target, "name", {
4
+ value,
5
+ configurable: true
6
+ });
7
+ //#endregion
8
+ export { __name as t };
package/dist/index.cjs CHANGED
@@ -1,70 +1,163 @@
1
- const require_factory = require('./factory-BNDICAoK.cjs');
2
- let typescript = require("typescript");
3
- typescript = require_factory.__toESM(typescript);
4
- let prettier = require("prettier");
5
- prettier = require_factory.__toESM(prettier);
6
- let prettier_plugins_typescript = require("prettier/plugins/typescript");
7
- prettier_plugins_typescript = require_factory.__toESM(prettier_plugins_typescript);
8
-
9
- //#region src/format.ts
10
- const formatOptions = {
11
- tabWidth: 2,
12
- printWidth: 160,
13
- parser: "typescript",
14
- singleQuote: true,
15
- semi: false,
16
- bracketSameLine: false,
17
- endOfLine: "auto",
18
- plugins: [prettier_plugins_typescript.default]
19
- };
20
- function format(source) {
21
- if (!source) return Promise.resolve("");
22
- try {
23
- return (0, prettier.format)(source, formatOptions);
24
- } catch (_e) {
25
- return Promise.resolve(source);
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
26
16
  }
27
- }
28
-
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
29
23
  //#endregion
30
- //#region src/print.ts
24
+ let node_path = require("node:path");
25
+ let _kubb_core = require("@kubb/core");
26
+ let typescript = require("typescript");
27
+ typescript = __toESM(typescript);
28
+ //#region src/parserTs.ts
31
29
  const { factory } = typescript.default;
30
+ function slash(path) {
31
+ return (0, node_path.normalize)(path).replaceAll(/\\/g, "/").replace("../", "");
32
+ }
33
+ function getRelativePath(rootDir, filePath) {
34
+ const slashed = slash((0, node_path.relative)(rootDir, filePath));
35
+ return slashed.startsWith("../") ? slashed : `./${slashed}`;
36
+ }
37
+ function trimExtName(text) {
38
+ return text.replace(/\.[^/.]+$/, "");
39
+ }
32
40
  /**
33
- * Escaped new lines in code with block comments so they can be restored by {@link restoreNewLines}
34
- */
35
- const escapeNewLines = (code) => code.replace(/\n\n/g, "\n/* :newline: */");
36
- /**
37
- * Reverses {@link escapeNewLines} and restores new lines
41
+ * Validates TypeScript AST nodes before printing.
42
+ * Throws an error if any node has SyntaxKind.Unknown which would cause the
43
+ * TypeScript printer to crash.
38
44
  */
39
- const restoreNewLines = (code) => code.replace(/\/\* :newline: \*\//g, "\n");
45
+ function validateNodes(...nodes) {
46
+ for (const node of nodes) {
47
+ if (!node) throw new Error("Attempted to print undefined or null TypeScript node");
48
+ if (node.kind === typescript.default.SyntaxKind.Unknown) throw new Error(`Invalid TypeScript AST node detected with SyntaxKind.Unknown. This typically indicates a schema pattern that could not be properly converted to TypeScript. Node: ${JSON.stringify(node, null, 2)}`);
49
+ }
50
+ }
40
51
  /**
41
- * Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.
42
- * Ensures consistent output across environments.
43
- * Also works as a formatter when `source` is provided without `elements`.
52
+ * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.
44
53
  */
45
- function print(elements = [], { source = "", baseName = "print.tsx", scriptKind = typescript.default.ScriptKind.TSX } = {}) {
46
- const sourceFile = typescript.default.createSourceFile(baseName, escapeNewLines(source), typescript.default.ScriptTarget.ES2022, true, scriptKind);
47
- const printer = typescript.default.createPrinter({
54
+ function print(...elements) {
55
+ const sourceFile = typescript.default.createSourceFile("print.tsx", "", typescript.default.ScriptTarget.ES2022, true, typescript.default.ScriptKind.TSX);
56
+ return typescript.default.createPrinter({
48
57
  omitTrailingSemicolon: true,
49
58
  newLine: typescript.default.NewLineKind.LineFeed,
50
59
  removeComments: false,
51
60
  noEmitHelpers: true
61
+ }).printList(typescript.default.ListFormat.MultiLine, factory.createNodeArray(elements.filter(Boolean)), sourceFile).replace(/\r\n/g, "\n");
62
+ }
63
+ /**
64
+ * Like `print` but validates nodes first to surface issues early.
65
+ */
66
+ function safePrint(...elements) {
67
+ validateNodes(...elements);
68
+ return print(...elements);
69
+ }
70
+ function createImport({ name, path, root, isTypeOnly = false, isNameSpace = false }) {
71
+ const resolvePath = root ? getRelativePath(root, path) : path;
72
+ if (!Array.isArray(name)) {
73
+ if (isNameSpace) return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamespaceImport(factory.createIdentifier(name))), factory.createStringLiteral(resolvePath), void 0);
74
+ return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, factory.createIdentifier(name), void 0), factory.createStringLiteral(resolvePath), void 0);
75
+ }
76
+ const specifiers = name.map((item) => {
77
+ if (typeof item === "object") {
78
+ const { propertyName, name: alias } = item;
79
+ return factory.createImportSpecifier(false, alias ? factory.createIdentifier(propertyName) : void 0, factory.createIdentifier(alias ?? propertyName));
80
+ }
81
+ return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
52
82
  });
53
- let output;
54
- if (elements.length > 0) {
55
- const nodes = elements.filter(Boolean).sort((a, b) => (a.pos ?? 0) - (b.pos ?? 0));
56
- output = printer.printList(typescript.default.ListFormat.MultiLine, factory.createNodeArray(nodes), sourceFile);
57
- } else output = printer.printFile(sourceFile);
58
- return restoreNewLines(output).replace(/\r\n/g, "\n");
83
+ return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(specifiers)), factory.createStringLiteral(resolvePath), void 0);
59
84
  }
60
-
85
+ function createExport({ path, asAlias, isTypeOnly = false, name }) {
86
+ if (name && !Array.isArray(name) && !asAlias) console.warn(`When using name as string, asAlias should be true: ${name}`);
87
+ if (!Array.isArray(name)) {
88
+ const parsedName = name?.match(/^\d/) ? `_${name?.slice(1)}` : name;
89
+ return factory.createExportDeclaration(void 0, isTypeOnly, asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : void 0, factory.createStringLiteral(path), void 0);
90
+ }
91
+ return factory.createExportDeclaration(void 0, isTypeOnly, factory.createNamedExports(name.map((propertyName) => factory.createExportSpecifier(false, void 0, typeof propertyName === "string" ? factory.createIdentifier(propertyName) : propertyName))), factory.createStringLiteral(path), void 0);
92
+ }
93
+ /**
94
+ * Parser that converts `.ts` and `.js` files to strings using the TypeScript
95
+ * compiler. Handles import/export statement generation from file metadata.
96
+ *
97
+ * @default Used automatically when no `parsers` option is set in `defineConfig`.
98
+ */
99
+ const parserTs = (0, _kubb_core.defineParser)({
100
+ name: "typescript",
101
+ extNames: [".ts", ".js"],
102
+ async parse(file, options = { extname: ".ts" }) {
103
+ const sourceParts = [];
104
+ for (const item of file.sources) if (item.value) sourceParts.push(item.value);
105
+ const source = sourceParts.join("\n\n");
106
+ const importNodes = [];
107
+ for (const item of file.imports) {
108
+ const importPath = item.root ? getRelativePath(item.root, item.path) : item.path;
109
+ const hasExtname = !!/\.[^/.]+$/.exec(importPath);
110
+ importNodes.push(createImport({
111
+ name: item.name,
112
+ path: options?.extname && hasExtname ? `${trimExtName(importPath)}${options.extname}` : item.root ? trimExtName(importPath) : importPath,
113
+ isTypeOnly: item.isTypeOnly,
114
+ isNameSpace: item.isNameSpace
115
+ }));
116
+ }
117
+ const exportNodes = [];
118
+ for (const item of file.exports) {
119
+ const exportPath = item.path;
120
+ const hasExtname = !!/\.[^/.]+$/.exec(exportPath);
121
+ exportNodes.push(createExport({
122
+ name: item.name,
123
+ path: options?.extname && hasExtname ? `${trimExtName(item.path)}${options.extname}` : trimExtName(item.path),
124
+ isTypeOnly: item.isTypeOnly,
125
+ asAlias: item.asAlias
126
+ }));
127
+ }
128
+ return [
129
+ file.banner,
130
+ print(...importNodes, ...exportNodes),
131
+ source,
132
+ file.footer
133
+ ].filter((segment) => segment != null).join("\n");
134
+ }
135
+ });
61
136
  //#endregion
62
- Object.defineProperty(exports, 'factory', {
63
- enumerable: true,
64
- get: function () {
65
- return require_factory.factory_exports;
66
- }
137
+ //#region src/parserTsx.ts
138
+ /**
139
+ * Parser that converts `.tsx` and `.jsx` files to strings.
140
+ * Delegates to `typescriptParser` since the TypeScript compiler natively
141
+ * supports JSX/TSX syntax via `ScriptKind.TSX`.
142
+ *
143
+ * Add this parser to the `parsers` option in `defineConfig` when generating `.tsx`/`.jsx` files.
144
+ *
145
+ * @default extname '.tsx'
146
+ */
147
+ const parserTsx = (0, _kubb_core.defineParser)({
148
+ name: "tsx",
149
+ extNames: [".tsx", ".jsx"],
150
+ async parse(file, options = { extname: ".tsx" }) {
151
+ return parserTs.parse(file, options);
152
+ }
67
153
  });
68
- exports.format = format;
154
+ //#endregion
155
+ exports.createExport = createExport;
156
+ exports.createImport = createImport;
157
+ exports.parserTs = parserTs;
158
+ exports.parserTsx = parserTsx;
69
159
  exports.print = print;
160
+ exports.safePrint = safePrint;
161
+ exports.validateNodes = validateNodes;
162
+
70
163
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["formatOptions: Options","pluginTypescript","ts","output: string"],"sources":["../src/format.ts","../src/print.ts"],"sourcesContent":["import type { Options } from 'prettier'\nimport { format as prettierFormat } from 'prettier'\nimport pluginTypescript from 'prettier/plugins/typescript'\n\nconst formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n plugins: [pluginTypescript],\n}\nexport function format(source?: string): Promise<string> {\n if (!source) {\n return Promise.resolve('')\n }\n\n try {\n return prettierFormat(source, formatOptions)\n } catch (_e) {\n return Promise.resolve(source)\n }\n}\n","import ts from 'typescript'\n\nconst { factory } = ts\n\nexport type PrintOptions = {\n source?: string\n baseName?: string\n scriptKind?: ts.ScriptKind\n}\n\n/**\n * Escaped new lines in code with block comments so they can be restored by {@link restoreNewLines}\n */\nconst escapeNewLines = (code: string) => code.replace(/\\n\\n/g, '\\n/* :newline: */')\n\n/**\n * Reverses {@link escapeNewLines} and restores new lines\n */\nconst restoreNewLines = (code: string) => code.replace(/\\/\\* :newline: \\*\\//g, '\\n')\n\n/**\n * Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.\n * Ensures consistent output across environments.\n * Also works as a formatter when `source` is provided without `elements`.\n */\nexport function print(elements: Array<ts.Node> = [], { source = '', baseName = 'print.tsx', scriptKind = ts.ScriptKind.TSX }: PrintOptions = {}): string {\n const sourceFile = ts.createSourceFile(baseName, escapeNewLines(source), ts.ScriptTarget.ES2022, true, scriptKind)\n\n const printer = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n })\n\n let output: string\n\n if (elements.length > 0) {\n // Print only provided nodes\n const nodes = elements.filter(Boolean).sort((a, b) => (a.pos ?? 0) - (b.pos ?? 0))\n output = printer.printList(ts.ListFormat.MultiLine, factory.createNodeArray(nodes), sourceFile)\n } else {\n // Format the whole file\n output = printer.printFile(sourceFile)\n }\n\n return restoreNewLines(output).replace(/\\r\\n/g, '\\n')\n}\n"],"mappings":";;;;;;;;;AAIA,MAAMA,gBAAyB;CAC7B,UAAU;CACV,YAAY;CACZ,QAAQ;CACR,aAAa;CACb,MAAM;CACN,iBAAiB;CACjB,WAAW;CACX,SAAS,CAACC,oCAAiB;CAC5B;AACD,SAAgB,OAAO,QAAkC;AACvD,KAAI,CAAC,OACH,QAAO,QAAQ,QAAQ,GAAG;AAG5B,KAAI;AACF,8BAAsB,QAAQ,cAAc;UACrC,IAAI;AACX,SAAO,QAAQ,QAAQ,OAAO;;;;;;ACpBlC,MAAM,EAAE,YAAYC;;;;AAWpB,MAAM,kBAAkB,SAAiB,KAAK,QAAQ,SAAS,oBAAoB;;;;AAKnF,MAAM,mBAAmB,SAAiB,KAAK,QAAQ,wBAAwB,KAAK;;;;;;AAOpF,SAAgB,MAAM,WAA2B,EAAE,EAAE,EAAE,SAAS,IAAI,WAAW,aAAa,aAAaA,mBAAG,WAAW,QAAsB,EAAE,EAAU;CACvJ,MAAM,aAAaA,mBAAG,iBAAiB,UAAU,eAAe,OAAO,EAAEA,mBAAG,aAAa,QAAQ,MAAM,WAAW;CAElH,MAAM,UAAUA,mBAAG,cAAc;EAC/B,uBAAuB;EACvB,SAASA,mBAAG,YAAY;EACxB,gBAAgB;EAChB,eAAe;EAChB,CAAC;CAEF,IAAIC;AAEJ,KAAI,SAAS,SAAS,GAAG;EAEvB,MAAM,QAAQ,SAAS,OAAO,QAAQ,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,MAAM,EAAE,OAAO,GAAG;AAClF,WAAS,QAAQ,UAAUD,mBAAG,WAAW,WAAW,QAAQ,gBAAgB,MAAM,EAAE,WAAW;OAG/F,UAAS,QAAQ,UAAU,WAAW;AAGxC,QAAO,gBAAgB,OAAO,CAAC,QAAQ,SAAS,KAAK"}
1
+ {"version":3,"file":"index.cjs","names":["ts"],"sources":["../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["import { normalize, relative } from 'node:path'\nimport type { KubbFile, Parser } from '@kubb/core'\nimport { defineParser } from '@kubb/core'\nimport ts from 'typescript'\n\nconst { factory } = ts\n\nfunction slash(path: string): string {\n return normalize(path).replaceAll(/\\\\/g, '/').replace('../', '')\n}\n\nfunction getRelativePath(rootDir: string, filePath: string): string {\n const rel = relative(rootDir, filePath)\n const slashed = slash(rel)\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\nfunction trimExtName(text: string): string {\n return text.replace(/\\.[^/.]+$/, '')\n}\n\n/**\n * Validates TypeScript AST nodes before printing.\n * Throws an error if any node has SyntaxKind.Unknown which would cause the\n * TypeScript printer to crash.\n */\nexport function validateNodes(...nodes: ts.Node[]): void {\n for (const node of nodes) {\n if (!node) {\n throw new Error('Attempted to print undefined or null TypeScript node')\n }\n if (node.kind === ts.SyntaxKind.Unknown) {\n throw new Error(\n 'Invalid TypeScript AST node detected with SyntaxKind.Unknown. ' +\n 'This typically indicates a schema pattern that could not be properly converted to TypeScript. ' +\n `Node: ${JSON.stringify(node, null, 2)}`,\n )\n }\n }\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 sourceFile = ts.createSourceFile('print.tsx', '', ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX)\n\n const printer = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n })\n\n const output = printer.printList(ts.ListFormat.MultiLine, factory.createNodeArray(elements.filter(Boolean)), sourceFile)\n\n return output.replace(/\\r\\n/g, '\\n')\n}\n\n/**\n * Like `print` but validates nodes first to surface issues early.\n */\nexport function safePrint(...elements: Array<ts.Node>): string {\n validateNodes(...elements)\n return print(...elements)\n}\n\nexport function createImport({\n name,\n path,\n root,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n root?: string\n /** @default false */\n isTypeOnly?: boolean\n /** @default false */\n isNameSpace?: boolean\n}): ts.ImportDeclaration {\n const resolvePath = root ? getRelativePath(root, path) : path\n\n if (!Array.isArray(name)) {\n if (isNameSpace) {\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, undefined, factory.createNamespaceImport(factory.createIdentifier(name))),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n }\n\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, factory.createIdentifier(name), undefined),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n }\n\n const specifiers = name.map((item) => {\n if (typeof item === 'object') {\n const { propertyName, name: alias } = item\n return factory.createImportSpecifier(false, alias ? factory.createIdentifier(propertyName) : undefined, factory.createIdentifier(alias ?? propertyName))\n }\n return factory.createImportSpecifier(false, undefined, factory.createIdentifier(item))\n })\n\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, undefined, factory.createNamedImports(specifiers)),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n}\n\nexport function createExport({\n path,\n asAlias,\n isTypeOnly = false,\n name,\n}: {\n path: string\n /** @default false */\n asAlias?: boolean\n /** @default false */\n isTypeOnly?: boolean\n name?: string | Array<ts.Identifier | string>\n}): ts.ExportDeclaration {\n if (name && !Array.isArray(name) && !asAlias) {\n console.warn(`When using name as string, asAlias should be true: ${name}`)\n }\n\n if (!Array.isArray(name)) {\n const parsedName = name?.match(/^\\d/) ? `_${name?.slice(1)}` : name\n\n return factory.createExportDeclaration(\n undefined,\n isTypeOnly,\n asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : undefined,\n factory.createStringLiteral(path),\n undefined,\n )\n }\n\n return factory.createExportDeclaration(\n undefined,\n isTypeOnly,\n factory.createNamedExports(\n name.map((propertyName) =>\n factory.createExportSpecifier(false, undefined, typeof propertyName === 'string' ? factory.createIdentifier(propertyName) : propertyName),\n ),\n ),\n factory.createStringLiteral(path),\n undefined,\n )\n}\n\n/**\n * Parser that converts `.ts` and `.js` files to strings using the TypeScript\n * compiler. Handles import/export statement generation from file metadata.\n *\n * @default Used automatically when no `parsers` option is set in `defineConfig`.\n */\nexport const parserTs: Parser = defineParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n async parse(file, options = { extname: '.ts' }) {\n const sourceParts: Array<string> = []\n for (const item of file.sources) {\n if (item.value) {\n sourceParts.push(item.value)\n }\n }\n const source = sourceParts.join('\\n\\n')\n\n const importNodes: Array<ts.ImportDeclaration> = []\n for (const item of (file as KubbFile.ResolvedFile).imports) {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n const hasExtname = !!/\\.[^/.]+$/.exec(importPath)\n\n importNodes.push(\n createImport({\n name: item.name as string | Array<string | { propertyName: string; name?: string }>,\n path: options?.extname && hasExtname ? `${trimExtName(importPath)}${options.extname}` : item.root ? trimExtName(importPath) : importPath,\n isTypeOnly: item.isTypeOnly,\n isNameSpace: item.isNameSpace,\n }),\n )\n }\n\n const exportNodes: Array<ts.ExportDeclaration> = []\n for (const item of (file as KubbFile.ResolvedFile).exports) {\n const exportPath = item.path\n const hasExtname = !!/\\.[^/.]+$/.exec(exportPath)\n\n exportNodes.push(\n createExport({\n name: item.name as string | Array<ts.Identifier | string> | undefined,\n path: options?.extname && hasExtname ? `${trimExtName(item.path)}${options.extname}` : trimExtName(item.path),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n }),\n )\n }\n\n const parts = [file.banner, print(...importNodes, ...exportNodes), source, file.footer].filter((segment): segment is string => segment != null)\n return parts.join('\\n')\n },\n})\n","import type { Parser } from '@kubb/core'\nimport { defineParser } from '@kubb/core'\nimport { parserTs } from './parserTs.ts'\n\n/**\n * Parser that converts `.tsx` and `.jsx` files to strings.\n * Delegates to `typescriptParser` since the TypeScript compiler natively\n * supports JSX/TSX syntax via `ScriptKind.TSX`.\n *\n * Add this parser to the `parsers` option in `defineConfig` when generating `.tsx`/`.jsx` files.\n *\n * @default extname '.tsx'\n */\nexport const parserTsx: Parser = defineParser({\n name: 'tsx',\n extNames: ['.tsx', '.jsx'],\n async parse(file, options = { extname: '.tsx' }) {\n return parserTs.parse(file, options)\n },\n})\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,25 +1,68 @@
1
- import { factory_d_exports } from "./factory-BJCGLhSr.js";
1
+ import { t as __name } from "./chunk--u3MIqq1.js";
2
+ import { Parser } from "@kubb/core";
2
3
  import ts from "typescript";
3
4
 
4
- //#region src/format.d.ts
5
- declare function format(source?: string): Promise<string>;
5
+ //#region src/parserTs.d.ts
6
+ /**
7
+ * Validates TypeScript AST nodes before printing.
8
+ * Throws an error if any node has SyntaxKind.Unknown which would cause the
9
+ * TypeScript printer to crash.
10
+ */
11
+ declare function validateNodes(...nodes: ts.Node[]): void;
12
+ /**
13
+ * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.
14
+ */
15
+ declare function print(...elements: Array<ts.Node>): string;
16
+ /**
17
+ * Like `print` but validates nodes first to surface issues early.
18
+ */
19
+ declare function safePrint(...elements: Array<ts.Node>): string;
20
+ declare function createImport({
21
+ name,
22
+ path,
23
+ root,
24
+ isTypeOnly,
25
+ isNameSpace
26
+ }: {
27
+ name: string | Array<string | {
28
+ propertyName: string;
29
+ name?: string;
30
+ }>;
31
+ path: string;
32
+ root?: string; /** @default false */
33
+ isTypeOnly?: boolean; /** @default false */
34
+ isNameSpace?: boolean;
35
+ }): ts.ImportDeclaration;
36
+ declare function createExport({
37
+ path,
38
+ asAlias,
39
+ isTypeOnly,
40
+ name
41
+ }: {
42
+ path: string; /** @default false */
43
+ asAlias?: boolean; /** @default false */
44
+ isTypeOnly?: boolean;
45
+ name?: string | Array<ts.Identifier | string>;
46
+ }): ts.ExportDeclaration;
47
+ /**
48
+ * Parser that converts `.ts` and `.js` files to strings using the TypeScript
49
+ * compiler. Handles import/export statement generation from file metadata.
50
+ *
51
+ * @default Used automatically when no `parsers` option is set in `defineConfig`.
52
+ */
53
+ declare const parserTs: Parser;
6
54
  //#endregion
7
- //#region src/print.d.ts
8
- type PrintOptions = {
9
- source?: string;
10
- baseName?: string;
11
- scriptKind?: ts.ScriptKind;
12
- };
55
+ //#region src/parserTsx.d.ts
13
56
  /**
14
- * Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.
15
- * Ensures consistent output across environments.
16
- * Also works as a formatter when `source` is provided without `elements`.
57
+ * Parser that converts `.tsx` and `.jsx` files to strings.
58
+ * Delegates to `typescriptParser` since the TypeScript compiler natively
59
+ * supports JSX/TSX syntax via `ScriptKind.TSX`.
60
+ *
61
+ * Add this parser to the `parsers` option in `defineConfig` when generating `.tsx`/`.jsx` files.
62
+ *
63
+ * @default extname '.tsx'
17
64
  */
18
- declare function print(elements?: Array<ts.Node>, {
19
- source,
20
- baseName,
21
- scriptKind
22
- }?: PrintOptions): string;
65
+ declare const parserTsx: Parser;
23
66
  //#endregion
24
- export { factory_d_exports as factory, format, print };
67
+ export { createExport, createImport, parserTs, parserTsx, print, safePrint, validateNodes };
25
68
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,60 +1,134 @@
1
- import { factory_exports } from "./factory-CroRqsMR.js";
1
+ import "./chunk--u3MIqq1.js";
2
+ import { normalize, relative } from "node:path";
3
+ import { defineParser } from "@kubb/core";
2
4
  import ts from "typescript";
3
- import { format as format$1 } from "prettier";
4
- import pluginTypescript from "prettier/plugins/typescript";
5
-
6
- //#region src/format.ts
7
- const formatOptions = {
8
- tabWidth: 2,
9
- printWidth: 160,
10
- parser: "typescript",
11
- singleQuote: true,
12
- semi: false,
13
- bracketSameLine: false,
14
- endOfLine: "auto",
15
- plugins: [pluginTypescript]
16
- };
17
- function format(source) {
18
- if (!source) return Promise.resolve("");
19
- try {
20
- return format$1(source, formatOptions);
21
- } catch (_e) {
22
- return Promise.resolve(source);
23
- }
24
- }
25
-
26
- //#endregion
27
- //#region src/print.ts
5
+ //#region src/parserTs.ts
28
6
  const { factory } = ts;
7
+ function slash(path) {
8
+ return normalize(path).replaceAll(/\\/g, "/").replace("../", "");
9
+ }
10
+ function getRelativePath(rootDir, filePath) {
11
+ const slashed = slash(relative(rootDir, filePath));
12
+ return slashed.startsWith("../") ? slashed : `./${slashed}`;
13
+ }
14
+ function trimExtName(text) {
15
+ return text.replace(/\.[^/.]+$/, "");
16
+ }
29
17
  /**
30
- * Escaped new lines in code with block comments so they can be restored by {@link restoreNewLines}
31
- */
32
- const escapeNewLines = (code) => code.replace(/\n\n/g, "\n/* :newline: */");
33
- /**
34
- * Reverses {@link escapeNewLines} and restores new lines
18
+ * Validates TypeScript AST nodes before printing.
19
+ * Throws an error if any node has SyntaxKind.Unknown which would cause the
20
+ * TypeScript printer to crash.
35
21
  */
36
- const restoreNewLines = (code) => code.replace(/\/\* :newline: \*\//g, "\n");
22
+ function validateNodes(...nodes) {
23
+ for (const node of nodes) {
24
+ if (!node) throw new Error("Attempted to print undefined or null TypeScript node");
25
+ if (node.kind === ts.SyntaxKind.Unknown) throw new Error(`Invalid TypeScript AST node detected with SyntaxKind.Unknown. This typically indicates a schema pattern that could not be properly converted to TypeScript. Node: ${JSON.stringify(node, null, 2)}`);
26
+ }
27
+ }
37
28
  /**
38
- * Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.
39
- * Ensures consistent output across environments.
40
- * Also works as a formatter when `source` is provided without `elements`.
29
+ * Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.
41
30
  */
42
- function print(elements = [], { source = "", baseName = "print.tsx", scriptKind = ts.ScriptKind.TSX } = {}) {
43
- const sourceFile = ts.createSourceFile(baseName, escapeNewLines(source), ts.ScriptTarget.ES2022, true, scriptKind);
44
- const printer = ts.createPrinter({
31
+ function print(...elements) {
32
+ const sourceFile = ts.createSourceFile("print.tsx", "", ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX);
33
+ return ts.createPrinter({
45
34
  omitTrailingSemicolon: true,
46
35
  newLine: ts.NewLineKind.LineFeed,
47
36
  removeComments: false,
48
37
  noEmitHelpers: true
38
+ }).printList(ts.ListFormat.MultiLine, factory.createNodeArray(elements.filter(Boolean)), sourceFile).replace(/\r\n/g, "\n");
39
+ }
40
+ /**
41
+ * Like `print` but validates nodes first to surface issues early.
42
+ */
43
+ function safePrint(...elements) {
44
+ validateNodes(...elements);
45
+ return print(...elements);
46
+ }
47
+ function createImport({ name, path, root, isTypeOnly = false, isNameSpace = false }) {
48
+ const resolvePath = root ? getRelativePath(root, path) : path;
49
+ if (!Array.isArray(name)) {
50
+ if (isNameSpace) return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamespaceImport(factory.createIdentifier(name))), factory.createStringLiteral(resolvePath), void 0);
51
+ return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, factory.createIdentifier(name), void 0), factory.createStringLiteral(resolvePath), void 0);
52
+ }
53
+ const specifiers = name.map((item) => {
54
+ if (typeof item === "object") {
55
+ const { propertyName, name: alias } = item;
56
+ return factory.createImportSpecifier(false, alias ? factory.createIdentifier(propertyName) : void 0, factory.createIdentifier(alias ?? propertyName));
57
+ }
58
+ return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
49
59
  });
50
- let output;
51
- if (elements.length > 0) {
52
- const nodes = elements.filter(Boolean).sort((a, b) => (a.pos ?? 0) - (b.pos ?? 0));
53
- output = printer.printList(ts.ListFormat.MultiLine, factory.createNodeArray(nodes), sourceFile);
54
- } else output = printer.printFile(sourceFile);
55
- return restoreNewLines(output).replace(/\r\n/g, "\n");
60
+ return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(specifiers)), factory.createStringLiteral(resolvePath), void 0);
56
61
  }
57
-
62
+ function createExport({ path, asAlias, isTypeOnly = false, name }) {
63
+ if (name && !Array.isArray(name) && !asAlias) console.warn(`When using name as string, asAlias should be true: ${name}`);
64
+ if (!Array.isArray(name)) {
65
+ const parsedName = name?.match(/^\d/) ? `_${name?.slice(1)}` : name;
66
+ return factory.createExportDeclaration(void 0, isTypeOnly, asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : void 0, factory.createStringLiteral(path), void 0);
67
+ }
68
+ return factory.createExportDeclaration(void 0, isTypeOnly, factory.createNamedExports(name.map((propertyName) => factory.createExportSpecifier(false, void 0, typeof propertyName === "string" ? factory.createIdentifier(propertyName) : propertyName))), factory.createStringLiteral(path), void 0);
69
+ }
70
+ /**
71
+ * Parser that converts `.ts` and `.js` files to strings using the TypeScript
72
+ * compiler. Handles import/export statement generation from file metadata.
73
+ *
74
+ * @default Used automatically when no `parsers` option is set in `defineConfig`.
75
+ */
76
+ const parserTs = defineParser({
77
+ name: "typescript",
78
+ extNames: [".ts", ".js"],
79
+ async parse(file, options = { extname: ".ts" }) {
80
+ const sourceParts = [];
81
+ for (const item of file.sources) if (item.value) sourceParts.push(item.value);
82
+ const source = sourceParts.join("\n\n");
83
+ const importNodes = [];
84
+ for (const item of file.imports) {
85
+ const importPath = item.root ? getRelativePath(item.root, item.path) : item.path;
86
+ const hasExtname = !!/\.[^/.]+$/.exec(importPath);
87
+ importNodes.push(createImport({
88
+ name: item.name,
89
+ path: options?.extname && hasExtname ? `${trimExtName(importPath)}${options.extname}` : item.root ? trimExtName(importPath) : importPath,
90
+ isTypeOnly: item.isTypeOnly,
91
+ isNameSpace: item.isNameSpace
92
+ }));
93
+ }
94
+ const exportNodes = [];
95
+ for (const item of file.exports) {
96
+ const exportPath = item.path;
97
+ const hasExtname = !!/\.[^/.]+$/.exec(exportPath);
98
+ exportNodes.push(createExport({
99
+ name: item.name,
100
+ path: options?.extname && hasExtname ? `${trimExtName(item.path)}${options.extname}` : trimExtName(item.path),
101
+ isTypeOnly: item.isTypeOnly,
102
+ asAlias: item.asAlias
103
+ }));
104
+ }
105
+ return [
106
+ file.banner,
107
+ print(...importNodes, ...exportNodes),
108
+ source,
109
+ file.footer
110
+ ].filter((segment) => segment != null).join("\n");
111
+ }
112
+ });
58
113
  //#endregion
59
- export { factory_exports as factory, format, print };
114
+ //#region src/parserTsx.ts
115
+ /**
116
+ * Parser that converts `.tsx` and `.jsx` files to strings.
117
+ * Delegates to `typescriptParser` since the TypeScript compiler natively
118
+ * supports JSX/TSX syntax via `ScriptKind.TSX`.
119
+ *
120
+ * Add this parser to the `parsers` option in `defineConfig` when generating `.tsx`/`.jsx` files.
121
+ *
122
+ * @default extname '.tsx'
123
+ */
124
+ const parserTsx = defineParser({
125
+ name: "tsx",
126
+ extNames: [".tsx", ".jsx"],
127
+ async parse(file, options = { extname: ".tsx" }) {
128
+ return parserTs.parse(file, options);
129
+ }
130
+ });
131
+ //#endregion
132
+ export { createExport, createImport, parserTs, parserTsx, print, safePrint, validateNodes };
133
+
60
134
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["formatOptions: Options","prettierFormat","output: string"],"sources":["../src/format.ts","../src/print.ts"],"sourcesContent":["import type { Options } from 'prettier'\nimport { format as prettierFormat } from 'prettier'\nimport pluginTypescript from 'prettier/plugins/typescript'\n\nconst formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n plugins: [pluginTypescript],\n}\nexport function format(source?: string): Promise<string> {\n if (!source) {\n return Promise.resolve('')\n }\n\n try {\n return prettierFormat(source, formatOptions)\n } catch (_e) {\n return Promise.resolve(source)\n }\n}\n","import ts from 'typescript'\n\nconst { factory } = ts\n\nexport type PrintOptions = {\n source?: string\n baseName?: string\n scriptKind?: ts.ScriptKind\n}\n\n/**\n * Escaped new lines in code with block comments so they can be restored by {@link restoreNewLines}\n */\nconst escapeNewLines = (code: string) => code.replace(/\\n\\n/g, '\\n/* :newline: */')\n\n/**\n * Reverses {@link escapeNewLines} and restores new lines\n */\nconst restoreNewLines = (code: string) => code.replace(/\\/\\* :newline: \\*\\//g, '\\n')\n\n/**\n * Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.\n * Ensures consistent output across environments.\n * Also works as a formatter when `source` is provided without `elements`.\n */\nexport function print(elements: Array<ts.Node> = [], { source = '', baseName = 'print.tsx', scriptKind = ts.ScriptKind.TSX }: PrintOptions = {}): string {\n const sourceFile = ts.createSourceFile(baseName, escapeNewLines(source), ts.ScriptTarget.ES2022, true, scriptKind)\n\n const printer = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n })\n\n let output: string\n\n if (elements.length > 0) {\n // Print only provided nodes\n const nodes = elements.filter(Boolean).sort((a, b) => (a.pos ?? 0) - (b.pos ?? 0))\n output = printer.printList(ts.ListFormat.MultiLine, factory.createNodeArray(nodes), sourceFile)\n } else {\n // Format the whole file\n output = printer.printFile(sourceFile)\n }\n\n return restoreNewLines(output).replace(/\\r\\n/g, '\\n')\n}\n"],"mappings":";;;;;;AAIA,MAAMA,gBAAyB;CAC7B,UAAU;CACV,YAAY;CACZ,QAAQ;CACR,aAAa;CACb,MAAM;CACN,iBAAiB;CACjB,WAAW;CACX,SAAS,CAAC,iBAAiB;CAC5B;AACD,SAAgB,OAAO,QAAkC;AACvD,KAAI,CAAC,OACH,QAAO,QAAQ,QAAQ,GAAG;AAG5B,KAAI;AACF,SAAOC,SAAe,QAAQ,cAAc;UACrC,IAAI;AACX,SAAO,QAAQ,QAAQ,OAAO;;;;;;ACpBlC,MAAM,EAAE,YAAY;;;;AAWpB,MAAM,kBAAkB,SAAiB,KAAK,QAAQ,SAAS,oBAAoB;;;;AAKnF,MAAM,mBAAmB,SAAiB,KAAK,QAAQ,wBAAwB,KAAK;;;;;;AAOpF,SAAgB,MAAM,WAA2B,EAAE,EAAE,EAAE,SAAS,IAAI,WAAW,aAAa,aAAa,GAAG,WAAW,QAAsB,EAAE,EAAU;CACvJ,MAAM,aAAa,GAAG,iBAAiB,UAAU,eAAe,OAAO,EAAE,GAAG,aAAa,QAAQ,MAAM,WAAW;CAElH,MAAM,UAAU,GAAG,cAAc;EAC/B,uBAAuB;EACvB,SAAS,GAAG,YAAY;EACxB,gBAAgB;EAChB,eAAe;EAChB,CAAC;CAEF,IAAIC;AAEJ,KAAI,SAAS,SAAS,GAAG;EAEvB,MAAM,QAAQ,SAAS,OAAO,QAAQ,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,MAAM,EAAE,OAAO,GAAG;AAClF,WAAS,QAAQ,UAAU,GAAG,WAAW,WAAW,QAAQ,gBAAgB,MAAM,EAAE,WAAW;OAG/F,UAAS,QAAQ,UAAU,WAAW;AAGxC,QAAO,gBAAgB,OAAO,CAAC,QAAQ,SAAS,KAAK"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/parserTs.ts","../src/parserTsx.ts"],"sourcesContent":["import { normalize, relative } from 'node:path'\nimport type { KubbFile, Parser } from '@kubb/core'\nimport { defineParser } from '@kubb/core'\nimport ts from 'typescript'\n\nconst { factory } = ts\n\nfunction slash(path: string): string {\n return normalize(path).replaceAll(/\\\\/g, '/').replace('../', '')\n}\n\nfunction getRelativePath(rootDir: string, filePath: string): string {\n const rel = relative(rootDir, filePath)\n const slashed = slash(rel)\n return slashed.startsWith('../') ? slashed : `./${slashed}`\n}\n\nfunction trimExtName(text: string): string {\n return text.replace(/\\.[^/.]+$/, '')\n}\n\n/**\n * Validates TypeScript AST nodes before printing.\n * Throws an error if any node has SyntaxKind.Unknown which would cause the\n * TypeScript printer to crash.\n */\nexport function validateNodes(...nodes: ts.Node[]): void {\n for (const node of nodes) {\n if (!node) {\n throw new Error('Attempted to print undefined or null TypeScript node')\n }\n if (node.kind === ts.SyntaxKind.Unknown) {\n throw new Error(\n 'Invalid TypeScript AST node detected with SyntaxKind.Unknown. ' +\n 'This typically indicates a schema pattern that could not be properly converted to TypeScript. ' +\n `Node: ${JSON.stringify(node, null, 2)}`,\n )\n }\n }\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 sourceFile = ts.createSourceFile('print.tsx', '', ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX)\n\n const printer = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n })\n\n const output = printer.printList(ts.ListFormat.MultiLine, factory.createNodeArray(elements.filter(Boolean)), sourceFile)\n\n return output.replace(/\\r\\n/g, '\\n')\n}\n\n/**\n * Like `print` but validates nodes first to surface issues early.\n */\nexport function safePrint(...elements: Array<ts.Node>): string {\n validateNodes(...elements)\n return print(...elements)\n}\n\nexport function createImport({\n name,\n path,\n root,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n root?: string\n /** @default false */\n isTypeOnly?: boolean\n /** @default false */\n isNameSpace?: boolean\n}): ts.ImportDeclaration {\n const resolvePath = root ? getRelativePath(root, path) : path\n\n if (!Array.isArray(name)) {\n if (isNameSpace) {\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, undefined, factory.createNamespaceImport(factory.createIdentifier(name))),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n }\n\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, factory.createIdentifier(name), undefined),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n }\n\n const specifiers = name.map((item) => {\n if (typeof item === 'object') {\n const { propertyName, name: alias } = item\n return factory.createImportSpecifier(false, alias ? factory.createIdentifier(propertyName) : undefined, factory.createIdentifier(alias ?? propertyName))\n }\n return factory.createImportSpecifier(false, undefined, factory.createIdentifier(item))\n })\n\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, undefined, factory.createNamedImports(specifiers)),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n}\n\nexport function createExport({\n path,\n asAlias,\n isTypeOnly = false,\n name,\n}: {\n path: string\n /** @default false */\n asAlias?: boolean\n /** @default false */\n isTypeOnly?: boolean\n name?: string | Array<ts.Identifier | string>\n}): ts.ExportDeclaration {\n if (name && !Array.isArray(name) && !asAlias) {\n console.warn(`When using name as string, asAlias should be true: ${name}`)\n }\n\n if (!Array.isArray(name)) {\n const parsedName = name?.match(/^\\d/) ? `_${name?.slice(1)}` : name\n\n return factory.createExportDeclaration(\n undefined,\n isTypeOnly,\n asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : undefined,\n factory.createStringLiteral(path),\n undefined,\n )\n }\n\n return factory.createExportDeclaration(\n undefined,\n isTypeOnly,\n factory.createNamedExports(\n name.map((propertyName) =>\n factory.createExportSpecifier(false, undefined, typeof propertyName === 'string' ? factory.createIdentifier(propertyName) : propertyName),\n ),\n ),\n factory.createStringLiteral(path),\n undefined,\n )\n}\n\n/**\n * Parser that converts `.ts` and `.js` files to strings using the TypeScript\n * compiler. Handles import/export statement generation from file metadata.\n *\n * @default Used automatically when no `parsers` option is set in `defineConfig`.\n */\nexport const parserTs: Parser = defineParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n async parse(file, options = { extname: '.ts' }) {\n const sourceParts: Array<string> = []\n for (const item of file.sources) {\n if (item.value) {\n sourceParts.push(item.value)\n }\n }\n const source = sourceParts.join('\\n\\n')\n\n const importNodes: Array<ts.ImportDeclaration> = []\n for (const item of (file as KubbFile.ResolvedFile).imports) {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n const hasExtname = !!/\\.[^/.]+$/.exec(importPath)\n\n importNodes.push(\n createImport({\n name: item.name as string | Array<string | { propertyName: string; name?: string }>,\n path: options?.extname && hasExtname ? `${trimExtName(importPath)}${options.extname}` : item.root ? trimExtName(importPath) : importPath,\n isTypeOnly: item.isTypeOnly,\n isNameSpace: item.isNameSpace,\n }),\n )\n }\n\n const exportNodes: Array<ts.ExportDeclaration> = []\n for (const item of (file as KubbFile.ResolvedFile).exports) {\n const exportPath = item.path\n const hasExtname = !!/\\.[^/.]+$/.exec(exportPath)\n\n exportNodes.push(\n createExport({\n name: item.name as string | Array<ts.Identifier | string> | undefined,\n path: options?.extname && hasExtname ? `${trimExtName(item.path)}${options.extname}` : trimExtName(item.path),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n }),\n )\n }\n\n const parts = [file.banner, print(...importNodes, ...exportNodes), source, file.footer].filter((segment): segment is string => segment != null)\n return parts.join('\\n')\n },\n})\n","import type { Parser } from '@kubb/core'\nimport { defineParser } from '@kubb/core'\nimport { parserTs } from './parserTs.ts'\n\n/**\n * Parser that converts `.tsx` and `.jsx` files to strings.\n * Delegates to `typescriptParser` since the TypeScript compiler natively\n * supports JSX/TSX syntax via `ScriptKind.TSX`.\n *\n * Add this parser to the `parsers` option in `defineConfig` when generating `.tsx`/`.jsx` files.\n *\n * @default extname '.tsx'\n */\nexport const parserTsx: Parser = defineParser({\n name: 'tsx',\n extNames: ['.tsx', '.jsx'],\n async parse(file, options = { extname: '.tsx' }) {\n return parserTs.parse(file, options)\n },\n})\n"],"mappings":"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"}