@kubb/parser-ts 5.0.0-beta.8 → 5.0.0-beta.81
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 +17 -10
- package/README.md +47 -48
- package/dist/index.cjs +221 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +60 -57
- package/dist/index.js +223 -105
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/extension.yaml +0 -100
- package/src/constants.ts +0 -47
- package/src/index.ts +0 -2
- package/src/parserTs.ts +0 -60
- package/src/parserTsx.ts +0 -20
- package/src/utils.ts +0 -459
- /package/dist/{chunk--u3MIqq1.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
import "./
|
|
1
|
+
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
2
|
import { defineParser } from "@kubb/core";
|
|
3
3
|
import { normalize, relative } from "node:path";
|
|
4
4
|
import ts from "typescript";
|
|
5
|
-
//#region src/
|
|
5
|
+
//#region ../../internals/utils/src/fs.ts
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Strips the file extension from a path or file name.
|
|
8
|
+
* Only removes the last `.ext` segment when the dot is not part of a directory name.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* trimExtName('petStore.ts') // 'petStore'
|
|
12
|
+
* trimExtName('/src/models/pet.ts') // '/src/models/pet'
|
|
13
|
+
* trimExtName('/project.v2/gen/pet.ts') // '/project.v2/gen/pet'
|
|
14
|
+
* trimExtName('noExtension') // 'noExtension'
|
|
15
|
+
*/
|
|
16
|
+
function trimExtName(text) {
|
|
17
|
+
const dotIndex = text.lastIndexOf(".");
|
|
18
|
+
if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
|
|
19
|
+
return text;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Indentation unit prepended once per nesting level when pretty-printing.
|
|
23
|
+
*/
|
|
24
|
+
const INDENT = " ".repeat(2);
|
|
25
|
+
/**
|
|
26
|
+
* Matches only the final `.<ext>` of a path, so a name like `foo.bar.ts` keeps
|
|
27
|
+
* `foo.bar` and loses just `.ts`.
|
|
9
28
|
*/
|
|
10
29
|
const FILE_EXTENSION_PATTERN = /\.[^/.]+$/;
|
|
11
30
|
/**
|
|
@@ -13,28 +32,28 @@ const FILE_EXTENSION_PATTERN = /\.[^/.]+$/;
|
|
|
13
32
|
*/
|
|
14
33
|
const WINDOWS_PATH_SEPARATOR = /\\/g;
|
|
15
34
|
/**
|
|
16
|
-
* Matches `*\/` in free-form text so JSDoc bodies can
|
|
35
|
+
* Matches `*\/` in free-form text so JSDoc bodies can neutralize premature
|
|
17
36
|
* comment terminators (`*\/` → `* /`).
|
|
18
37
|
*/
|
|
19
38
|
const JSDOC_TERMINATOR_PATTERN = /\*\//g;
|
|
20
39
|
/**
|
|
21
|
-
* Matches carriage returns for
|
|
40
|
+
* Matches carriage returns for normalizing CRLF/CR line endings to LF.
|
|
22
41
|
*/
|
|
23
42
|
const CARRIAGE_RETURN_PATTERN = /\r/g;
|
|
24
43
|
/**
|
|
25
|
-
* Matches CRLF sequences used when
|
|
44
|
+
* Matches CRLF sequences used when normalizing TypeScript printer output.
|
|
26
45
|
*/
|
|
27
46
|
const CRLF_PATTERN = /\r\n/g;
|
|
28
47
|
/**
|
|
29
|
-
* Matches an identifier that starts with a digit
|
|
30
|
-
* so the printer
|
|
48
|
+
* Matches an identifier that starts with a digit. JavaScript disallows this,
|
|
49
|
+
* so the printer replaces the leading digit with `_`.
|
|
31
50
|
*/
|
|
32
51
|
const LEADING_DIGIT_PATTERN = /^\d/;
|
|
33
52
|
//#endregion
|
|
34
53
|
//#region src/utils.ts
|
|
35
54
|
const { factory } = ts;
|
|
36
55
|
/**
|
|
37
|
-
*
|
|
56
|
+
* Normalizes a file-system path to POSIX separators and strips any leading `../` segment.
|
|
38
57
|
*/
|
|
39
58
|
function slash(path) {
|
|
40
59
|
return normalize(path).replaceAll(WINDOWS_PATH_SEPARATOR, "/").replace("../", "");
|
|
@@ -48,13 +67,6 @@ function getRelativePath(rootDir, filePath) {
|
|
|
48
67
|
return slashed.startsWith("../") ? slashed : `./${slashed}`;
|
|
49
68
|
}
|
|
50
69
|
/**
|
|
51
|
-
* Strips the trailing file extension (for example `.ts`) from a path.
|
|
52
|
-
* Preserves intermediate dots like `foo.bar.ts` → `foo.bar`.
|
|
53
|
-
*/
|
|
54
|
-
function trimExtName(text) {
|
|
55
|
-
return text.replace(FILE_EXTENSION_PATTERN, "");
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
70
|
* Rewrites an import/export path so its extension matches the caller-supplied
|
|
59
71
|
* `options.extname`. When the source path has no extension the original is kept,
|
|
60
72
|
* so virtual/module-only paths flow through unchanged.
|
|
@@ -65,25 +77,64 @@ function resolveOutputPath(path, options, rootAware) {
|
|
|
65
77
|
return rootAware ? trimExtName(path) : path;
|
|
66
78
|
}
|
|
67
79
|
/**
|
|
68
|
-
* Serializes
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* Elements are joined with `\n`.
|
|
80
|
+
* Serializes a `nodes` array into source text. Each entry is rendered via {@link printCodeNode}
|
|
81
|
+
* and joined with a single newline. A `Break` node (`<br/>`) inserts one blank line between
|
|
82
|
+
* statements. Consecutive breaks, and breaks at the very start or end, are folded into the
|
|
83
|
+
* separator, so a double `<br/>` never emits more than one blank line.
|
|
73
84
|
*/
|
|
74
85
|
function printNodes(nodes) {
|
|
75
86
|
if (!nodes || nodes.length === 0) return "";
|
|
76
|
-
|
|
87
|
+
let result = "";
|
|
88
|
+
let hasContent = false;
|
|
89
|
+
let pendingBreak = false;
|
|
90
|
+
for (const node of nodes) {
|
|
91
|
+
if (node.kind === "Break") {
|
|
92
|
+
if (hasContent) pendingBreak = true;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const text = printCodeNode(node);
|
|
96
|
+
if (!text) continue;
|
|
97
|
+
if (hasContent) result += pendingBreak ? "\n\n" : "\n";
|
|
98
|
+
result += text;
|
|
99
|
+
hasContent = true;
|
|
100
|
+
pendingBreak = false;
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
77
103
|
}
|
|
78
104
|
/**
|
|
79
|
-
* Indents every non-empty line of `text` by
|
|
105
|
+
* Indents every non-empty line of `text` by one indent unit. Pass a number to repeat
|
|
106
|
+
* {@link INDENT_CHAR} that many times, or a string to use as the indent verbatim.
|
|
80
107
|
*/
|
|
81
|
-
function indentLines(text,
|
|
108
|
+
function indentLines(text, indent = INDENT) {
|
|
82
109
|
if (!text) return "";
|
|
83
|
-
const pad = " ".repeat(
|
|
110
|
+
const pad = typeof indent === "string" ? indent : " ".repeat(indent);
|
|
84
111
|
return text.split("\n").map((line) => line.trim() ? `${pad}${line}` : "").join("\n");
|
|
85
112
|
}
|
|
86
113
|
/**
|
|
114
|
+
* Removes the common leading whitespace shared by every non-blank line and trims
|
|
115
|
+
* surrounding blank lines, so multi-line content authored inside an indented template
|
|
116
|
+
* literal lines up at a column-zero baseline. Leading whitespace is counted by
|
|
117
|
+
* character, so N tabs and N spaces are treated as the same depth.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* dedent('\n foo\n bar\n ')
|
|
122
|
+
* // 'foo\n bar'
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
function dedent(text) {
|
|
126
|
+
if (!text) return "";
|
|
127
|
+
const lines = text.split("\n");
|
|
128
|
+
const isBlank = (line) => line.trim() === "";
|
|
129
|
+
const start = lines.findIndex((line) => !isBlank(line));
|
|
130
|
+
if (start === -1) return "";
|
|
131
|
+
const end = lines.findLastIndex((line) => !isBlank(line));
|
|
132
|
+
const trimmed = lines.slice(start, end + 1);
|
|
133
|
+
const indents = trimmed.filter((line) => !isBlank(line)).map((line) => line.match(/^\s*/)?.[0].length ?? 0);
|
|
134
|
+
const min = indents.length ? Math.min(...indents) : 0;
|
|
135
|
+
return trimmed.map((line) => isBlank(line) ? "" : line.slice(min)).join("\n");
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
87
138
|
* Renders the generic clause (`<T, U>`) shared by function and arrow-function nodes.
|
|
88
139
|
* Accepts either a raw string (rendered verbatim) or an array of type-parameter names.
|
|
89
140
|
*/
|
|
@@ -100,34 +151,28 @@ function formatReturnType(returnType, isAsync) {
|
|
|
100
151
|
return isAsync ? `: Promise<${returnType}>` : `: ${returnType}`;
|
|
101
152
|
}
|
|
102
153
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* TypeScript printer to crash.
|
|
154
|
+
* Module-scoped TypeScript printer instance. A printer does not mutate the source file, so one
|
|
155
|
+
* instance is reused across every `print()` call instead of constructing a new printer each time.
|
|
106
156
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
157
|
+
const TS_PRINTER = ts.createPrinter({
|
|
158
|
+
omitTrailingSemicolon: true,
|
|
159
|
+
newLine: ts.NewLineKind.LineFeed,
|
|
160
|
+
removeComments: false,
|
|
161
|
+
noEmitHelpers: true
|
|
162
|
+
});
|
|
113
163
|
/**
|
|
114
|
-
*
|
|
164
|
+
* Module-scoped source file used as the print target. `printList` only reads the source
|
|
165
|
+
* file's compiler options / language version. It never mutates it.
|
|
115
166
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return ts.createPrinter({
|
|
119
|
-
omitTrailingSemicolon: true,
|
|
120
|
-
newLine: ts.NewLineKind.LineFeed,
|
|
121
|
-
removeComments: false,
|
|
122
|
-
noEmitHelpers: true
|
|
123
|
-
}).printList(ts.ListFormat.MultiLine, factory.createNodeArray(elements.filter(Boolean)), sourceFile).replace(CRLF_PATTERN, "\n");
|
|
124
|
-
}
|
|
167
|
+
const PRINT_SOURCE_FILE = ts.createSourceFile("print.tsx", "", ts.ScriptTarget.ES2022, true, ts.ScriptKind.TSX);
|
|
168
|
+
TS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray([]), PRINT_SOURCE_FILE);
|
|
125
169
|
/**
|
|
126
|
-
*
|
|
170
|
+
* Converts TypeScript/TSX AST nodes to a string using the TypeScript printer.
|
|
127
171
|
*/
|
|
128
|
-
function
|
|
129
|
-
|
|
130
|
-
|
|
172
|
+
function print(...elements) {
|
|
173
|
+
const filtered = elements.filter(Boolean);
|
|
174
|
+
if (filtered.length === 0) return "";
|
|
175
|
+
return TS_PRINTER.printList(ts.ListFormat.MultiLine, factory.createNodeArray(filtered), PRINT_SOURCE_FILE).replace(CRLF_PATTERN, "\n");
|
|
131
176
|
}
|
|
132
177
|
/**
|
|
133
178
|
* Converts a {@link JSDocNode} to a JSDoc comment block string.
|
|
@@ -159,13 +204,13 @@ function printJSDoc(jsDoc) {
|
|
|
159
204
|
*
|
|
160
205
|
* @example
|
|
161
206
|
* ```ts
|
|
162
|
-
* printConst(createConst({ name: 'pet', export: true, nodes: ['{}'] }))
|
|
207
|
+
* printConst(factory.createConst({ name: 'pet', export: true, nodes: ['{}'] }))
|
|
163
208
|
* // 'export const pet = {}'
|
|
164
209
|
* ```
|
|
165
210
|
*
|
|
166
211
|
* @example With type and `as const`
|
|
167
212
|
* ```ts
|
|
168
|
-
* printConst(createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true, nodes: ['[]'] }))
|
|
213
|
+
* printConst(factory.createConst({ name: 'pets', export: true, type: 'Pet[]', asConst: true, nodes: ['[]'] }))
|
|
169
214
|
* // 'export const pets: Pet[] = [] as const'
|
|
170
215
|
* ```
|
|
171
216
|
*/
|
|
@@ -190,7 +235,7 @@ function printConst(node) {
|
|
|
190
235
|
*
|
|
191
236
|
* @example
|
|
192
237
|
* ```ts
|
|
193
|
-
* printType(createType({ name: 'Pet', export: true, nodes: ['{ id: number }'] }))
|
|
238
|
+
* printType(factory.createType({ name: 'Pet', export: true, nodes: ['{ id: number }'] }))
|
|
194
239
|
* // 'export type Pet = { id: number }'
|
|
195
240
|
* ```
|
|
196
241
|
*/
|
|
@@ -213,13 +258,13 @@ function printType(node) {
|
|
|
213
258
|
*
|
|
214
259
|
* @example
|
|
215
260
|
* ```ts
|
|
216
|
-
* printFunction(createFunction({ name: 'getPet', export: true, params: 'id: string', returnType: 'Pet', nodes: ['return fetch(id)'] }))
|
|
261
|
+
* printFunction(factory.createFunction({ name: 'getPet', export: true, params: 'id: string', returnType: 'Pet', nodes: ['return fetch(id)'] }))
|
|
217
262
|
* // 'export function getPet(id: string): Pet {\n return fetch(id)\n}'
|
|
218
263
|
* ```
|
|
219
264
|
*
|
|
220
265
|
* @example Async with generics
|
|
221
266
|
* ```ts
|
|
222
|
-
* printFunction(createFunction({ name: 'fetchPet', export: true, async: true, generics: ['T'], params: 'id: string', returnType: 'T' }))
|
|
267
|
+
* printFunction(factory.createFunction({ name: 'fetchPet', export: true, async: true, generics: ['T'], params: 'id: string', returnType: 'T' }))
|
|
223
268
|
* // 'export async function fetchPet<T>(id: string): Promise<T> {\n}'
|
|
224
269
|
* ```
|
|
225
270
|
*/
|
|
@@ -249,13 +294,13 @@ function printFunction(node) {
|
|
|
249
294
|
*
|
|
250
295
|
* @example Multi-line arrow function
|
|
251
296
|
* ```ts
|
|
252
|
-
* printArrowFunction(createArrowFunction({ name: 'getPet', export: true, params: 'id: string', nodes: ['return fetch(id)'] }))
|
|
297
|
+
* printArrowFunction(factory.createArrowFunction({ name: 'getPet', export: true, params: 'id: string', nodes: ['return fetch(id)'] }))
|
|
253
298
|
* // 'export const getPet = (id: string) => {\n return fetch(id)\n}'
|
|
254
299
|
* ```
|
|
255
300
|
*
|
|
256
301
|
* @example Single-line arrow function
|
|
257
302
|
* ```ts
|
|
258
|
-
* printArrowFunction(createArrowFunction({ name: 'double', params: 'n: number', singleLine: true, nodes: ['n * 2'] }))
|
|
303
|
+
* printArrowFunction(factory.createArrowFunction({ name: 'double', params: 'n: number', singleLine: true, nodes: ['n * 2'] }))
|
|
259
304
|
* // 'const double = (n: number) => n * 2'
|
|
260
305
|
* ```
|
|
261
306
|
*/
|
|
@@ -284,20 +329,19 @@ function printArrowFunction(node) {
|
|
|
284
329
|
*
|
|
285
330
|
* @example
|
|
286
331
|
* ```ts
|
|
287
|
-
* printCodeNode(createConst({ name: 'x', nodes: ['1'] }))
|
|
332
|
+
* printCodeNode(factory.createConst({ name: 'x', nodes: ['1'] }))
|
|
288
333
|
* // 'const x = 1'
|
|
289
334
|
* ```
|
|
290
335
|
*/
|
|
291
336
|
function printCodeNode(node) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
337
|
+
if (node.kind === "Break") return "";
|
|
338
|
+
if (node.kind === "Text") return dedent(node.value);
|
|
339
|
+
if (node.kind === "Jsx") return dedent(node.value);
|
|
340
|
+
if (node.kind === "Const") return printConst(node);
|
|
341
|
+
if (node.kind === "Type") return printType(node);
|
|
342
|
+
if (node.kind === "Function") return printFunction(node);
|
|
343
|
+
if (node.kind === "ArrowFunction") return printArrowFunction(node);
|
|
344
|
+
return "";
|
|
301
345
|
}
|
|
302
346
|
/**
|
|
303
347
|
* Converts a {@link SourceNode} to its TypeScript string representation.
|
|
@@ -305,77 +349,135 @@ function printCodeNode(node) {
|
|
|
305
349
|
* Iterates `nodes` in DOM order, rendering each {@link CodeNode} via
|
|
306
350
|
* {@link printCodeNode}.
|
|
307
351
|
*
|
|
352
|
+
* Top-level declarations are separated by a blank line so the source reads
|
|
353
|
+
* cleanly without an external formatter.
|
|
354
|
+
*
|
|
308
355
|
* @example From nodes
|
|
309
356
|
* ```ts
|
|
310
|
-
* printSource({ kind: 'Source', nodes: [createConst({ name: 'x', nodes: [createText('1')] }), createText('x.toString()')] })
|
|
311
|
-
* // 'const x = 1\nx.toString()'
|
|
357
|
+
* printSource({ kind: 'Source', nodes: [factory.createConst({ name: 'x', nodes: [factory.createText('1')] }), factory.createText('x.toString()')] })
|
|
358
|
+
* // 'const x = 1\n\nx.toString()'
|
|
312
359
|
* ```
|
|
313
360
|
*/
|
|
314
361
|
function printSource(node) {
|
|
315
|
-
|
|
316
|
-
return "";
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, factory.createIdentifier(name), void 0), factory.createStringLiteral(resolvePath), void 0);
|
|
362
|
+
const nodes = node.nodes;
|
|
363
|
+
if (!nodes || nodes.length === 0) return "";
|
|
364
|
+
let result = "";
|
|
365
|
+
for (const child of nodes) {
|
|
366
|
+
const text = printCodeNode(child);
|
|
367
|
+
if (!text) continue;
|
|
368
|
+
result = result ? `${result}\n\n${text}` : text;
|
|
323
369
|
}
|
|
324
|
-
|
|
325
|
-
if (typeof item === "object") {
|
|
326
|
-
const { propertyName, name: alias } = item;
|
|
327
|
-
return factory.createImportSpecifier(false, alias ? factory.createIdentifier(propertyName) : void 0, factory.createIdentifier(alias ?? propertyName));
|
|
328
|
-
}
|
|
329
|
-
return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
|
|
330
|
-
});
|
|
331
|
-
return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(specifiers)), factory.createStringLiteral(resolvePath), void 0);
|
|
370
|
+
return result;
|
|
332
371
|
}
|
|
333
|
-
|
|
334
|
-
|
|
372
|
+
/**
|
|
373
|
+
* Wraps a module specifier in single quotes, escaping any embedded backslash or quote so the emitted
|
|
374
|
+
* statement stays valid even for unusual paths.
|
|
375
|
+
*/
|
|
376
|
+
function quoteModulePath(path) {
|
|
377
|
+
return `'${path.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Renders an import declaration string in the repo style (single quotes, no semicolons), covering
|
|
381
|
+
* default, namespace (`* as`), and named imports with `{ a as b }` aliases, each optionally
|
|
382
|
+
* `type`-only. `path` is used verbatim, so resolve it first.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```ts
|
|
386
|
+
* printImport({ name: ['z'], path: './zod.ts' })
|
|
387
|
+
* // "import { z } from './zod.ts'"
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
function printImport({ name, path, isTypeOnly = false, isNameSpace = false }) {
|
|
391
|
+
const typePrefix = isTypeOnly ? "type " : "";
|
|
392
|
+
const from = quoteModulePath(path);
|
|
335
393
|
if (!Array.isArray(name)) {
|
|
336
|
-
|
|
337
|
-
return
|
|
394
|
+
if (isNameSpace) return `import ${typePrefix}* as ${name} from ${from}`;
|
|
395
|
+
return `import ${typePrefix}${name} from ${from}`;
|
|
338
396
|
}
|
|
339
|
-
return
|
|
397
|
+
return `import ${typePrefix}{ ${name.map((item) => {
|
|
398
|
+
if (typeof item === "object") return item.name ? `${item.propertyName} as ${item.name}` : item.propertyName;
|
|
399
|
+
return item;
|
|
400
|
+
}).join(", ")} } from ${from}`;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Renders an export declaration string in the repo style (single quotes, no semicolons), covering
|
|
404
|
+
* named re-exports, namespace alias (`* as name`), and wildcard, each optionally `type`-only.
|
|
405
|
+
* `path` is used verbatim, so resolve it first.
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```ts
|
|
409
|
+
* printExport({ name: ['Pet', 'Order'], path: './models.ts' })
|
|
410
|
+
* // "export { Pet, Order } from './models.ts'"
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
function printExport({ path, name, isTypeOnly = false, asAlias = false }) {
|
|
414
|
+
const typePrefix = isTypeOnly ? "type " : "";
|
|
415
|
+
const from = quoteModulePath(path);
|
|
416
|
+
if (Array.isArray(name)) return `export ${typePrefix}{ ${name.map((item) => typeof item === "string" ? item : item.text).join(", ")} } from ${from}`;
|
|
417
|
+
if (asAlias && name) return `export ${typePrefix}* as ${LEADING_DIGIT_PATTERN.test(name) ? `_${name.slice(1)}` : name} from ${from}`;
|
|
418
|
+
if (name) console.warn(`When using name as string, asAlias should be true: ${name}`);
|
|
419
|
+
return `export ${typePrefix}* from ${from}`;
|
|
340
420
|
}
|
|
341
421
|
//#endregion
|
|
342
422
|
//#region src/parserTs.ts
|
|
343
423
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
424
|
+
* Default Kubb parser for `.ts` and `.js` files. Takes the universal AST
|
|
425
|
+
* produced by an adapter and prints it as TypeScript source using the official
|
|
426
|
+
* TypeScript compiler. Imports and exports are rewritten based on each file's
|
|
427
|
+
* metadata.
|
|
428
|
+
*
|
|
429
|
+
* Used automatically when no `parsers` option is set on `defineConfig`. Use
|
|
430
|
+
* `parserTsx` instead for React projects that emit JSX.
|
|
346
431
|
*
|
|
347
|
-
* @
|
|
432
|
+
* @example
|
|
433
|
+
* ```ts
|
|
434
|
+
* import { defineConfig } from 'kubb'
|
|
435
|
+
* import { adapterOas } from '@kubb/adapter-oas'
|
|
436
|
+
* import { parserTs } from '@kubb/parser-ts'
|
|
437
|
+
*
|
|
438
|
+
* export default defineConfig({
|
|
439
|
+
* input: { path: './petStore.yaml' },
|
|
440
|
+
* output: { path: './src/gen' },
|
|
441
|
+
* adapter: adapterOas(),
|
|
442
|
+
* parsers: [parserTs],
|
|
443
|
+
* plugins: [],
|
|
444
|
+
* })
|
|
445
|
+
* ```
|
|
348
446
|
*/
|
|
349
447
|
const parserTs = defineParser({
|
|
350
448
|
name: "typescript",
|
|
351
449
|
extNames: [".ts", ".js"],
|
|
352
|
-
|
|
450
|
+
print(...nodes) {
|
|
451
|
+
return print(...nodes);
|
|
452
|
+
},
|
|
453
|
+
parse(file, options = { extname: ".ts" }) {
|
|
353
454
|
const sourceParts = [];
|
|
354
455
|
for (const item of file.sources) {
|
|
355
456
|
const sourceStr = printSource(item);
|
|
356
457
|
if (sourceStr) sourceParts.push(sourceStr.trimEnd());
|
|
357
458
|
}
|
|
358
459
|
const source = sourceParts.join("\n\n");
|
|
359
|
-
const
|
|
460
|
+
const importLines = [];
|
|
360
461
|
for (const item of file.imports) {
|
|
361
462
|
const importPath = item.root ? getRelativePath(item.root, item.path) : item.path;
|
|
362
|
-
|
|
463
|
+
importLines.push(printImport({
|
|
363
464
|
name: item.name,
|
|
364
465
|
path: resolveOutputPath(importPath, options, Boolean(item.root)),
|
|
365
466
|
isTypeOnly: item.isTypeOnly,
|
|
366
467
|
isNameSpace: item.isNameSpace
|
|
367
468
|
}));
|
|
368
469
|
}
|
|
369
|
-
const
|
|
370
|
-
for (const item of file.exports)
|
|
470
|
+
const exportLines = [];
|
|
471
|
+
for (const item of file.exports) exportLines.push(printExport({
|
|
371
472
|
name: item.name,
|
|
372
473
|
path: resolveOutputPath(item.path, options, true),
|
|
373
474
|
isTypeOnly: item.isTypeOnly,
|
|
374
475
|
asAlias: item.asAlias
|
|
375
476
|
}));
|
|
477
|
+
const importExportBlock = [...importLines, ...exportLines].join("\n");
|
|
376
478
|
return [
|
|
377
479
|
file.banner,
|
|
378
|
-
|
|
480
|
+
importExportBlock,
|
|
379
481
|
source,
|
|
380
482
|
file.footer
|
|
381
483
|
].filter((segment) => Boolean(segment)).map((s) => s.trimEnd()).join("\n\n");
|
|
@@ -384,22 +486,38 @@ const parserTs = defineParser({
|
|
|
384
486
|
//#endregion
|
|
385
487
|
//#region src/parserTsx.ts
|
|
386
488
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* supports JSX/TSX syntax via `ScriptKind.TSX`.
|
|
489
|
+
* Kubb parser for `.tsx` and `.jsx` files. Delegates to `parserTs` because the
|
|
490
|
+
* TypeScript compiler handles JSX natively via `ScriptKind.TSX`.
|
|
390
491
|
*
|
|
391
|
-
* Add
|
|
492
|
+
* Add to the `parsers` array on `defineConfig` when generating components for
|
|
493
|
+
* React (or any framework that emits JSX).
|
|
392
494
|
*
|
|
393
|
-
* @
|
|
495
|
+
* @example
|
|
496
|
+
* ```ts
|
|
497
|
+
* import { defineConfig } from 'kubb'
|
|
498
|
+
* import { adapterOas } from '@kubb/adapter-oas'
|
|
499
|
+
* import { parserTsx } from '@kubb/parser-ts'
|
|
500
|
+
*
|
|
501
|
+
* export default defineConfig({
|
|
502
|
+
* input: { path: './petStore.yaml' },
|
|
503
|
+
* output: { path: './src/gen' },
|
|
504
|
+
* adapter: adapterOas(),
|
|
505
|
+
* parsers: [parserTsx],
|
|
506
|
+
* plugins: [],
|
|
507
|
+
* })
|
|
508
|
+
* ```
|
|
394
509
|
*/
|
|
395
510
|
const parserTsx = defineParser({
|
|
396
511
|
name: "tsx",
|
|
397
512
|
extNames: [".tsx", ".jsx"],
|
|
398
|
-
|
|
513
|
+
print(...nodes) {
|
|
514
|
+
return print(...nodes);
|
|
515
|
+
},
|
|
516
|
+
parse(file, options = { extname: ".tsx" }) {
|
|
399
517
|
return parserTs.parse(file, options);
|
|
400
518
|
}
|
|
401
519
|
});
|
|
402
520
|
//#endregion
|
|
403
|
-
export {
|
|
521
|
+
export { parserTs, parserTsx };
|
|
404
522
|
|
|
405
523
|
//# sourceMappingURL=index.js.map
|