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