@kubb/plugin-faker 5.0.0-beta.84 → 5.0.0-beta.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +495 -372
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +69 -110
- package/dist/index.js +494 -349
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -2,35 +2,382 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
//#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
//#endregion
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
let kubb_kit = require("kubb/kit");
|
|
8
|
+
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
9
|
+
let kubb_jsx = require("kubb/jsx");
|
|
10
|
+
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
11
|
+
//#region ../../internals/utils/src/casing.ts
|
|
12
|
+
/**
|
|
13
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
14
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
15
|
+
* and capitalizes each word according to `pascal`.
|
|
16
|
+
*
|
|
17
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
18
|
+
*/
|
|
19
|
+
function toCamelOrPascal(text, pascal) {
|
|
20
|
+
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
21
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
22
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
23
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Converts `text` to camelCase.
|
|
27
|
+
*
|
|
28
|
+
* @example Word boundaries
|
|
29
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
30
|
+
*
|
|
31
|
+
* @example With a prefix
|
|
32
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
33
|
+
*/
|
|
34
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
35
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ../../internals/utils/src/reserved.ts
|
|
39
|
+
/**
|
|
40
|
+
* JavaScript and Java reserved words.
|
|
41
|
+
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
42
|
+
*/
|
|
43
|
+
const reservedWords = /* @__PURE__ */ new Set([
|
|
44
|
+
"abstract",
|
|
45
|
+
"arguments",
|
|
46
|
+
"boolean",
|
|
47
|
+
"break",
|
|
48
|
+
"byte",
|
|
49
|
+
"case",
|
|
50
|
+
"catch",
|
|
51
|
+
"char",
|
|
52
|
+
"class",
|
|
53
|
+
"const",
|
|
54
|
+
"continue",
|
|
55
|
+
"debugger",
|
|
56
|
+
"default",
|
|
57
|
+
"delete",
|
|
58
|
+
"do",
|
|
59
|
+
"double",
|
|
60
|
+
"else",
|
|
61
|
+
"enum",
|
|
62
|
+
"eval",
|
|
63
|
+
"export",
|
|
64
|
+
"extends",
|
|
65
|
+
"false",
|
|
66
|
+
"final",
|
|
67
|
+
"finally",
|
|
68
|
+
"float",
|
|
69
|
+
"for",
|
|
70
|
+
"function",
|
|
71
|
+
"goto",
|
|
72
|
+
"if",
|
|
73
|
+
"implements",
|
|
74
|
+
"import",
|
|
75
|
+
"in",
|
|
76
|
+
"instanceof",
|
|
77
|
+
"int",
|
|
78
|
+
"interface",
|
|
79
|
+
"let",
|
|
80
|
+
"long",
|
|
81
|
+
"native",
|
|
82
|
+
"new",
|
|
83
|
+
"null",
|
|
84
|
+
"package",
|
|
85
|
+
"private",
|
|
86
|
+
"protected",
|
|
87
|
+
"public",
|
|
88
|
+
"return",
|
|
89
|
+
"short",
|
|
90
|
+
"static",
|
|
91
|
+
"super",
|
|
92
|
+
"switch",
|
|
93
|
+
"synchronized",
|
|
94
|
+
"this",
|
|
95
|
+
"throw",
|
|
96
|
+
"throws",
|
|
97
|
+
"transient",
|
|
98
|
+
"true",
|
|
99
|
+
"try",
|
|
100
|
+
"typeof",
|
|
101
|
+
"var",
|
|
102
|
+
"void",
|
|
103
|
+
"volatile",
|
|
104
|
+
"while",
|
|
105
|
+
"with",
|
|
106
|
+
"yield",
|
|
107
|
+
"Array",
|
|
108
|
+
"Date",
|
|
109
|
+
"hasOwnProperty",
|
|
110
|
+
"Infinity",
|
|
111
|
+
"isFinite",
|
|
112
|
+
"isNaN",
|
|
113
|
+
"isPrototypeOf",
|
|
114
|
+
"length",
|
|
115
|
+
"Math",
|
|
116
|
+
"name",
|
|
117
|
+
"NaN",
|
|
118
|
+
"Number",
|
|
119
|
+
"Object",
|
|
120
|
+
"prototype",
|
|
121
|
+
"String",
|
|
122
|
+
"toString",
|
|
123
|
+
"undefined",
|
|
124
|
+
"valueOf"
|
|
125
|
+
]);
|
|
126
|
+
/**
|
|
127
|
+
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* isValidVarName('status') // true
|
|
132
|
+
* isValidVarName('class') // false (reserved word)
|
|
133
|
+
* isValidVarName('42foo') // false (starts with digit)
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
function isValidVarName(name) {
|
|
137
|
+
if (!name || reservedWords.has(name)) return false;
|
|
138
|
+
return isIdentifier(name);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Returns `name` when it's a syntactically valid JavaScript variable name,
|
|
142
|
+
* otherwise prefixes it with `_` so the result is a valid identifier.
|
|
143
|
+
*
|
|
144
|
+
* Useful for sanitizing OpenAPI schema names or operation IDs that start with
|
|
145
|
+
* a digit (e.g. `409`, `504AccountCancel`) before using them as exported
|
|
146
|
+
* variable, type, or function names.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* ensureValidVarName('409') // '_409'
|
|
151
|
+
* ensureValidVarName('504AccountCancel') // '_504AccountCancel'
|
|
152
|
+
* ensureValidVarName('Pet') // 'Pet'
|
|
153
|
+
* ensureValidVarName('class') // '_class'
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
function ensureValidVarName(name) {
|
|
157
|
+
if (!name || isValidVarName(name)) return name;
|
|
158
|
+
return `_${name}`;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
|
|
162
|
+
*
|
|
163
|
+
* Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
|
|
164
|
+
* even though they are not valid variable names, so use this (not {@link isValidVarName}) when
|
|
165
|
+
* deciding whether an object key needs quoting.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* isIdentifier('name') // true
|
|
170
|
+
* isIdentifier('x-total')// false
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
function isIdentifier(name) {
|
|
174
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region ../../internals/utils/src/strings.ts
|
|
178
|
+
/**
|
|
179
|
+
* Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
|
|
180
|
+
* any backslash or single quote in the content.
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```ts
|
|
184
|
+
* singleQuote('foo') // "'foo'"
|
|
185
|
+
* singleQuote("o'clock") // "'o\\'clock'"
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
function singleQuote(value) {
|
|
189
|
+
if (value === void 0 || value === null) return "''";
|
|
190
|
+
return `'${String(value).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
|
|
194
|
+
* Returns the string unchanged when no balanced quote pair is found.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* trimQuotes('"hello"') // 'hello'
|
|
199
|
+
* trimQuotes('hello') // 'hello'
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
function trimQuotes(text) {
|
|
203
|
+
if (text.length >= 2) {
|
|
204
|
+
const first = text[0];
|
|
205
|
+
const last = text[text.length - 1];
|
|
206
|
+
if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
|
|
19
207
|
}
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
208
|
+
return text;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
|
|
212
|
+
*
|
|
213
|
+
* Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
|
|
214
|
+
* code matches the repo style without a formatter.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* stringify('hello') // "'hello'"
|
|
219
|
+
* stringify('"hello"') // "'hello'"
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
function stringify(value) {
|
|
223
|
+
if (value === void 0 || value === null) return "''";
|
|
224
|
+
return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
|
|
228
|
+
* and the Unicode line terminators U+2028 and U+2029.
|
|
229
|
+
*
|
|
230
|
+
* @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
function jsStringEscape(input) {
|
|
238
|
+
return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
|
|
239
|
+
switch (character) {
|
|
240
|
+
case "\"":
|
|
241
|
+
case "'":
|
|
242
|
+
case "\\": return `\\${character}`;
|
|
243
|
+
case "\n": return "\\n";
|
|
244
|
+
case "\r": return "\\r";
|
|
245
|
+
case "\u2028": return "\\u2028";
|
|
246
|
+
case "\u2029": return "\\u2029";
|
|
247
|
+
default: return "";
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
|
|
253
|
+
* Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
|
|
254
|
+
* Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```ts
|
|
258
|
+
* toRegExpString('^(?im)foo') // 'new RegExp("^foo", "im")'
|
|
259
|
+
* toRegExpString('^(?im)foo', null) // '/^foo/im'
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
function toRegExpString(text, func = "RegExp") {
|
|
263
|
+
const raw = trimQuotes(text);
|
|
264
|
+
const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
|
|
265
|
+
const replacementTarget = match?.[1] ?? "";
|
|
266
|
+
const matchedFlags = match?.[2];
|
|
267
|
+
const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
|
|
268
|
+
const { source, flags } = new RegExp(cleaned, matchedFlags);
|
|
269
|
+
if (func === null) return `/${source}/${flags}`;
|
|
270
|
+
return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
|
|
271
|
+
}
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region ../../internals/utils/src/codegen.ts
|
|
274
|
+
const INDENT = " ";
|
|
275
|
+
/**
|
|
276
|
+
* Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
|
|
277
|
+
*/
|
|
278
|
+
function indentLines(text) {
|
|
279
|
+
if (!text) return "";
|
|
280
|
+
return text.split("\n").map((line) => line.trim() ? `${INDENT}${line}` : "").join("\n");
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Renders an object key, quoting it with single quotes only when it is not a valid identifier.
|
|
284
|
+
* Reserved words and globals (`name`, `class`, …) are valid bare keys and stay unquoted.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* objectKey('name') // 'name'
|
|
289
|
+
* objectKey('x-total') // "'x-total'"
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
function objectKey(name) {
|
|
293
|
+
return isIdentifier(name) ? name : singleQuote(name);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Assembles a multi-line object literal from already-rendered `entries`, indenting each entry one
|
|
297
|
+
* level and closing the brace at column zero. Entries that are themselves multi-line objects indent
|
|
298
|
+
* cumulatively. Each entry ends with a trailing comma to match the formatter's multi-line style.
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* ```ts
|
|
302
|
+
* buildObject(['id: z.number()', 'name: z.string()'])
|
|
303
|
+
* // '{\n id: z.number(),\n name: z.string(),\n}'
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
306
|
+
function buildObject(entries) {
|
|
307
|
+
if (entries.length === 0) return "{}";
|
|
308
|
+
return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
|
|
309
|
+
}
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region ../../internals/utils/src/fs.ts
|
|
312
|
+
/**
|
|
313
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
314
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
315
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
316
|
+
*
|
|
317
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
318
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
319
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
320
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
321
|
+
*
|
|
322
|
+
* @example Nested path from a dotted name
|
|
323
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
324
|
+
*
|
|
325
|
+
* @example PascalCase the final segment
|
|
326
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
327
|
+
*
|
|
328
|
+
* @example Suffix applied to the final segment only
|
|
329
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
330
|
+
*/
|
|
331
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
332
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
333
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
334
|
+
}
|
|
335
|
+
//#endregion
|
|
336
|
+
//#region ../../internals/utils/src/imports.ts
|
|
337
|
+
function escapeRegExp(value) {
|
|
338
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
339
|
+
}
|
|
340
|
+
function getImportNames(entry) {
|
|
341
|
+
return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
|
|
342
|
+
if (typeof name === "string") return name;
|
|
343
|
+
return name.name ?? name.propertyName;
|
|
344
|
+
}).filter((name) => Boolean(name));
|
|
345
|
+
}
|
|
346
|
+
function filterUsedImports(imports, text, skipImportNames = []) {
|
|
347
|
+
const skip = new Set(skipImportNames);
|
|
348
|
+
return imports.filter((entry) => {
|
|
349
|
+
return getImportNames(entry).some((name) => {
|
|
350
|
+
if (skip.has(name)) return false;
|
|
351
|
+
return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*\\()`).test(text);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
function aliasConflictingImports(imports, reservedNames) {
|
|
356
|
+
const reservedNameSet = new Set(reservedNames);
|
|
357
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
358
|
+
return {
|
|
359
|
+
imports: imports.map((entry) => {
|
|
360
|
+
const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
|
|
361
|
+
if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
|
|
362
|
+
const alias = `${item}Schema`;
|
|
363
|
+
aliases.set(item, alias);
|
|
364
|
+
return {
|
|
365
|
+
propertyName: item,
|
|
366
|
+
name: alias
|
|
367
|
+
};
|
|
368
|
+
});
|
|
369
|
+
return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
|
|
370
|
+
...entry,
|
|
371
|
+
name: aliasedNames
|
|
372
|
+
} : entry;
|
|
373
|
+
}),
|
|
374
|
+
aliases
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function rewriteAliasedImports(text, aliases) {
|
|
378
|
+
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
379
|
+
}
|
|
26
380
|
//#endregion
|
|
27
|
-
let kubb_kit = require("kubb/kit");
|
|
28
|
-
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
29
|
-
let kubb_jsx = require("kubb/jsx");
|
|
30
|
-
let node_path = require("node:path");
|
|
31
|
-
node_path = __toESM(node_path, 1);
|
|
32
|
-
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
33
|
-
let node_crypto = require("node:crypto");
|
|
34
381
|
//#region src/utils.ts
|
|
35
382
|
/**
|
|
36
383
|
* Returns the `@faker-js/faker` named export for a locale code.
|
|
@@ -79,17 +426,6 @@ function canOverrideSchema(node) {
|
|
|
79
426
|
"blob"
|
|
80
427
|
])).has(node.type);
|
|
81
428
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Resolves a parameter name based on its location (path, query, header, etc.) using the provided resolver.
|
|
84
|
-
*/
|
|
85
|
-
function resolveParamNameByLocation(resolver, node, param) {
|
|
86
|
-
switch (param.in) {
|
|
87
|
-
case "path": return resolver.resolvePathParamsName(node, param);
|
|
88
|
-
case "query": return resolver.resolveQueryParamsName(node, param);
|
|
89
|
-
case "header": return resolver.resolveHeaderParamsName(node, param);
|
|
90
|
-
default: return resolver.resolveParamName(node, param);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
429
|
function shouldInlineSingleResponseSchema(schema) {
|
|
94
430
|
return (/* @__PURE__ */ new Set([
|
|
95
431
|
"any",
|
|
@@ -126,14 +462,14 @@ function buildResponseUnionSchema(node, resolver) {
|
|
|
126
462
|
if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
|
|
127
463
|
return kubb_kit.ast.factory.createSchema({
|
|
128
464
|
type: "ref",
|
|
129
|
-
name: resolver.
|
|
465
|
+
name: resolver.response.status(node, responses[0].statusCode)
|
|
130
466
|
});
|
|
131
467
|
}
|
|
132
468
|
return kubb_kit.ast.factory.createSchema({
|
|
133
469
|
type: "union",
|
|
134
470
|
members: responses.map((response) => kubb_kit.ast.factory.createSchema({
|
|
135
471
|
type: "ref",
|
|
136
|
-
name: resolver.
|
|
472
|
+
name: resolver.response.status(node, response.statusCode)
|
|
137
473
|
}))
|
|
138
474
|
});
|
|
139
475
|
}
|
|
@@ -152,7 +488,6 @@ const SCALAR_TYPES$1 = /* @__PURE__ */ new Set([
|
|
|
152
488
|
"blob",
|
|
153
489
|
"enum"
|
|
154
490
|
]);
|
|
155
|
-
const ARRAY_TYPES$1 = /* @__PURE__ */ new Set(["array"]);
|
|
156
491
|
function toRelativeImportPath(from, to) {
|
|
157
492
|
const relativePath = node_path.posix.relative(node_path.posix.dirname(from), to);
|
|
158
493
|
return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
|
|
@@ -197,7 +532,7 @@ function getScalarType(node, typeName) {
|
|
|
197
532
|
* Determines the data type, return type, and whether it uses the type name.
|
|
198
533
|
*/
|
|
199
534
|
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
200
|
-
const isArray =
|
|
535
|
+
const isArray = node.type === "array";
|
|
201
536
|
const isTuple = node.type === "tuple";
|
|
202
537
|
const isScalar = SCALAR_TYPES$1.has(node.type);
|
|
203
538
|
let dataType = `Partial<${typeName}>`;
|
|
@@ -214,7 +549,6 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
|
214
549
|
//#endregion
|
|
215
550
|
//#region src/components/Faker.tsx
|
|
216
551
|
const OBJECT_TYPES = /* @__PURE__ */ new Set(["object", "intersection"]);
|
|
217
|
-
const ARRAY_TYPES = /* @__PURE__ */ new Set(["array"]);
|
|
218
552
|
const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
219
553
|
"string",
|
|
220
554
|
"email",
|
|
@@ -233,7 +567,7 @@ const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
|
233
567
|
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
234
568
|
function Faker({ node, description, name, typeName, printer, seed, canOverride }) {
|
|
235
569
|
const fakerText = printer.print(node) ?? "undefined";
|
|
236
|
-
const isArray =
|
|
570
|
+
const isArray = node.type === "array";
|
|
237
571
|
const isObject = OBJECT_TYPES.has(node.type);
|
|
238
572
|
const isTuple = node.type === "tuple";
|
|
239
573
|
const isScalar = SCALAR_TYPES.has(node.type);
|
|
@@ -261,14 +595,14 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
|
|
|
261
595
|
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.Function, {
|
|
262
596
|
export: true,
|
|
263
597
|
name,
|
|
264
|
-
JSDoc: { comments: description ? [`@description ${
|
|
598
|
+
JSDoc: { comments: description ? [`@description ${jsStringEscape(description)}`] : [] },
|
|
265
599
|
params: canOverride ? paramsSignature : void 0,
|
|
266
600
|
returnType: returnType ?? void 0,
|
|
267
601
|
children: [seed ? /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [`faker.seed(${JSON.stringify(seed)})`, /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)("br", {})] }) : void 0, `return ${returnExpression}`]
|
|
268
602
|
})
|
|
269
603
|
});
|
|
270
604
|
}
|
|
271
|
-
const functionSignature = `${description ? `/**\n * @description ${
|
|
605
|
+
const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
|
|
272
606
|
const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
|
|
273
607
|
const { cyclicSchemas, schemaName } = printer.options;
|
|
274
608
|
const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => kubb_kit.ast.containsCircularRef(p.schema, {
|
|
@@ -297,226 +631,6 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
|
|
|
297
631
|
});
|
|
298
632
|
}
|
|
299
633
|
//#endregion
|
|
300
|
-
//#region ../../internals/utils/src/casing.ts
|
|
301
|
-
/**
|
|
302
|
-
* Shared implementation for camelCase and PascalCase conversion.
|
|
303
|
-
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
304
|
-
* and capitalizes each word according to `pascal`.
|
|
305
|
-
*
|
|
306
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
307
|
-
*/
|
|
308
|
-
function toCamelOrPascal(text, pascal) {
|
|
309
|
-
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
310
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
311
|
-
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
312
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Converts `text` to camelCase.
|
|
316
|
-
*
|
|
317
|
-
* @example Word boundaries
|
|
318
|
-
* `camelCase('hello-world') // 'helloWorld'`
|
|
319
|
-
*
|
|
320
|
-
* @example With a prefix
|
|
321
|
-
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
322
|
-
*/
|
|
323
|
-
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
324
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
325
|
-
}
|
|
326
|
-
//#endregion
|
|
327
|
-
//#region ../../internals/utils/src/fs.ts
|
|
328
|
-
/**
|
|
329
|
-
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
330
|
-
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
331
|
-
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
332
|
-
*
|
|
333
|
-
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
334
|
-
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
335
|
-
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
336
|
-
* absolute path, letting generated files escape the configured output directory.
|
|
337
|
-
*
|
|
338
|
-
* @example Nested path from a dotted name
|
|
339
|
-
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
340
|
-
*
|
|
341
|
-
* @example PascalCase the final segment
|
|
342
|
-
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
343
|
-
*
|
|
344
|
-
* @example Suffix applied to the final segment only
|
|
345
|
-
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
346
|
-
*/
|
|
347
|
-
function toFilePath(name, caseLast = camelCase) {
|
|
348
|
-
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
349
|
-
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
350
|
-
}
|
|
351
|
-
//#endregion
|
|
352
|
-
//#region ../../internals/utils/src/imports.ts
|
|
353
|
-
function escapeRegExp(value) {
|
|
354
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
355
|
-
}
|
|
356
|
-
function getImportNames(entry) {
|
|
357
|
-
return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
|
|
358
|
-
if (typeof name === "string") return name;
|
|
359
|
-
return name.name ?? name.propertyName;
|
|
360
|
-
}).filter((name) => Boolean(name));
|
|
361
|
-
}
|
|
362
|
-
function filterUsedImports(imports, text, skipImportNames = []) {
|
|
363
|
-
const skip = new Set(skipImportNames);
|
|
364
|
-
return imports.filter((entry) => {
|
|
365
|
-
return getImportNames(entry).some((name) => {
|
|
366
|
-
if (skip.has(name)) return false;
|
|
367
|
-
return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*\\()`).test(text);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
function aliasConflictingImports(imports, reservedNames) {
|
|
372
|
-
const reservedNameSet = new Set(reservedNames);
|
|
373
|
-
const aliases = /* @__PURE__ */ new Map();
|
|
374
|
-
return {
|
|
375
|
-
imports: imports.map((entry) => {
|
|
376
|
-
const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
|
|
377
|
-
if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
|
|
378
|
-
const alias = `${item}Schema`;
|
|
379
|
-
aliases.set(item, alias);
|
|
380
|
-
return {
|
|
381
|
-
propertyName: item,
|
|
382
|
-
name: alias
|
|
383
|
-
};
|
|
384
|
-
});
|
|
385
|
-
return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
|
|
386
|
-
...entry,
|
|
387
|
-
name: aliasedNames
|
|
388
|
-
} : entry;
|
|
389
|
-
}),
|
|
390
|
-
aliases
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
function rewriteAliasedImports(text, aliases) {
|
|
394
|
-
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
395
|
-
}
|
|
396
|
-
//#endregion
|
|
397
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
398
|
-
/**
|
|
399
|
-
* JavaScript and Java reserved words.
|
|
400
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
401
|
-
*/
|
|
402
|
-
const reservedWords = /* @__PURE__ */ new Set([
|
|
403
|
-
"abstract",
|
|
404
|
-
"arguments",
|
|
405
|
-
"boolean",
|
|
406
|
-
"break",
|
|
407
|
-
"byte",
|
|
408
|
-
"case",
|
|
409
|
-
"catch",
|
|
410
|
-
"char",
|
|
411
|
-
"class",
|
|
412
|
-
"const",
|
|
413
|
-
"continue",
|
|
414
|
-
"debugger",
|
|
415
|
-
"default",
|
|
416
|
-
"delete",
|
|
417
|
-
"do",
|
|
418
|
-
"double",
|
|
419
|
-
"else",
|
|
420
|
-
"enum",
|
|
421
|
-
"eval",
|
|
422
|
-
"export",
|
|
423
|
-
"extends",
|
|
424
|
-
"false",
|
|
425
|
-
"final",
|
|
426
|
-
"finally",
|
|
427
|
-
"float",
|
|
428
|
-
"for",
|
|
429
|
-
"function",
|
|
430
|
-
"goto",
|
|
431
|
-
"if",
|
|
432
|
-
"implements",
|
|
433
|
-
"import",
|
|
434
|
-
"in",
|
|
435
|
-
"instanceof",
|
|
436
|
-
"int",
|
|
437
|
-
"interface",
|
|
438
|
-
"let",
|
|
439
|
-
"long",
|
|
440
|
-
"native",
|
|
441
|
-
"new",
|
|
442
|
-
"null",
|
|
443
|
-
"package",
|
|
444
|
-
"private",
|
|
445
|
-
"protected",
|
|
446
|
-
"public",
|
|
447
|
-
"return",
|
|
448
|
-
"short",
|
|
449
|
-
"static",
|
|
450
|
-
"super",
|
|
451
|
-
"switch",
|
|
452
|
-
"synchronized",
|
|
453
|
-
"this",
|
|
454
|
-
"throw",
|
|
455
|
-
"throws",
|
|
456
|
-
"transient",
|
|
457
|
-
"true",
|
|
458
|
-
"try",
|
|
459
|
-
"typeof",
|
|
460
|
-
"var",
|
|
461
|
-
"void",
|
|
462
|
-
"volatile",
|
|
463
|
-
"while",
|
|
464
|
-
"with",
|
|
465
|
-
"yield",
|
|
466
|
-
"Array",
|
|
467
|
-
"Date",
|
|
468
|
-
"hasOwnProperty",
|
|
469
|
-
"Infinity",
|
|
470
|
-
"isFinite",
|
|
471
|
-
"isNaN",
|
|
472
|
-
"isPrototypeOf",
|
|
473
|
-
"length",
|
|
474
|
-
"Math",
|
|
475
|
-
"name",
|
|
476
|
-
"NaN",
|
|
477
|
-
"Number",
|
|
478
|
-
"Object",
|
|
479
|
-
"prototype",
|
|
480
|
-
"String",
|
|
481
|
-
"toString",
|
|
482
|
-
"undefined",
|
|
483
|
-
"valueOf"
|
|
484
|
-
]);
|
|
485
|
-
/**
|
|
486
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
487
|
-
*
|
|
488
|
-
* @example
|
|
489
|
-
* ```ts
|
|
490
|
-
* isValidVarName('status') // true
|
|
491
|
-
* isValidVarName('class') // false (reserved word)
|
|
492
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
493
|
-
* ```
|
|
494
|
-
*/
|
|
495
|
-
function isValidVarName(name) {
|
|
496
|
-
if (!name || reservedWords.has(name)) return false;
|
|
497
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
* Returns `name` when it's a syntactically valid JavaScript variable name,
|
|
501
|
-
* otherwise prefixes it with `_` so the result is a valid identifier.
|
|
502
|
-
*
|
|
503
|
-
* Useful for sanitizing OpenAPI schema names or operation IDs that start with
|
|
504
|
-
* a digit (e.g. `409`, `504AccountCancel`) before using them as exported
|
|
505
|
-
* variable, type, or function names.
|
|
506
|
-
*
|
|
507
|
-
* @example
|
|
508
|
-
* ```ts
|
|
509
|
-
* ensureValidVarName('409') // '_409'
|
|
510
|
-
* ensureValidVarName('504AccountCancel') // '_504AccountCancel'
|
|
511
|
-
* ensureValidVarName('Pet') // 'Pet'
|
|
512
|
-
* ensureValidVarName('class') // '_class'
|
|
513
|
-
* ```
|
|
514
|
-
*/
|
|
515
|
-
function ensureValidVarName(name) {
|
|
516
|
-
if (!name || isValidVarName(name)) return name;
|
|
517
|
-
return `_${name}`;
|
|
518
|
-
}
|
|
519
|
-
//#endregion
|
|
520
634
|
//#region ../../internals/shared/src/params.ts
|
|
521
635
|
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
522
636
|
/**
|
|
@@ -537,6 +651,23 @@ function caseParams(params, casing) {
|
|
|
537
651
|
caseParamsCache.set(params, result);
|
|
538
652
|
return result;
|
|
539
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* Drops parameters that collapse to the same property identity once camelCased, keeping the first.
|
|
656
|
+
*
|
|
657
|
+
* Some specs declare the same parameter twice under different casings (for example AWS S3 lists both
|
|
658
|
+
* `max-uploads` and `MaxUploads`). Both resolve to one output property, so emitting both would yield
|
|
659
|
+
* an object type with a duplicate member, which TypeScript rejects. De-duplicate by the camelCased
|
|
660
|
+
* identity so the resulting group is collision-free regardless of the names each caller carries.
|
|
661
|
+
*/
|
|
662
|
+
function dedupeByCasedName(params) {
|
|
663
|
+
const seen = /* @__PURE__ */ new Set();
|
|
664
|
+
return params.filter((param) => {
|
|
665
|
+
const key = camelCase(param.name);
|
|
666
|
+
if (seen.has(key)) return false;
|
|
667
|
+
seen.add(key);
|
|
668
|
+
return true;
|
|
669
|
+
});
|
|
670
|
+
}
|
|
540
671
|
//#endregion
|
|
541
672
|
//#region ../../internals/shared/src/operation.ts
|
|
542
673
|
/**
|
|
@@ -587,6 +718,15 @@ function resolveContentTypeVariants(entries, baseName) {
|
|
|
587
718
|
};
|
|
588
719
|
});
|
|
589
720
|
}
|
|
721
|
+
function getOperationParameters(node, options = {}) {
|
|
722
|
+
const params = caseParams(node.parameters, options.paramsCasing === "original" ? void 0 : "camelcase");
|
|
723
|
+
return {
|
|
724
|
+
path: dedupeByCasedName(params.filter((param) => param.in === "path")),
|
|
725
|
+
query: dedupeByCasedName(params.filter((param) => param.in === "query")),
|
|
726
|
+
header: dedupeByCasedName(params.filter((param) => param.in === "header")),
|
|
727
|
+
cookie: dedupeByCasedName(params.filter((param) => param.in === "cookie"))
|
|
728
|
+
};
|
|
729
|
+
}
|
|
590
730
|
//#endregion
|
|
591
731
|
//#region ../../internals/shared/src/group.ts
|
|
592
732
|
/**
|
|
@@ -681,7 +821,7 @@ const fakerKeywordMapper = {
|
|
|
681
821
|
return `{...${items.join(", ...")}}`;
|
|
682
822
|
},
|
|
683
823
|
matches: (value = "", regexGenerator = "faker") => {
|
|
684
|
-
if (regexGenerator === "randexp") return `${
|
|
824
|
+
if (regexGenerator === "randexp") return `${toRegExpString(value, "RandExp")}.gen()`;
|
|
685
825
|
return `faker.helpers.fromRegExp("${value}")`;
|
|
686
826
|
},
|
|
687
827
|
email: () => "faker.internet.email()",
|
|
@@ -692,7 +832,7 @@ function getEnumValues(node) {
|
|
|
692
832
|
return node.enumValues ?? [];
|
|
693
833
|
}
|
|
694
834
|
function parseEnumValue(value) {
|
|
695
|
-
if (typeof value === "string") return
|
|
835
|
+
if (typeof value === "string") return stringify(value);
|
|
696
836
|
return value;
|
|
697
837
|
}
|
|
698
838
|
/**
|
|
@@ -760,7 +900,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
760
900
|
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name ?? node.schema?.name : node.name ?? node.schema?.name;
|
|
761
901
|
if (!refName) throw new Error("Name not defined for ref node");
|
|
762
902
|
if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
|
|
763
|
-
const resolvedName = node.ref ? this.options.resolver.
|
|
903
|
+
const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
|
|
764
904
|
if (!this.options.nestedInObject) return `${resolvedName}(data)`;
|
|
765
905
|
return `${resolvedName}()`;
|
|
766
906
|
},
|
|
@@ -804,7 +944,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
804
944
|
},
|
|
805
945
|
object(node) {
|
|
806
946
|
const cyclicSchemas = this.options.cyclicSchemas;
|
|
807
|
-
|
|
947
|
+
return buildObject((node.properties ?? []).map((property) => {
|
|
808
948
|
const value = printNested(property.schema, {
|
|
809
949
|
typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
|
|
810
950
|
nestedInObject: true
|
|
@@ -812,10 +952,9 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
812
952
|
if (cyclicSchemas && kubb_kit.ast.containsCircularRef(property.schema, {
|
|
813
953
|
circularSchemas: cyclicSchemas,
|
|
814
954
|
excludeName: this.options.schemaName
|
|
815
|
-
})) return `get ${
|
|
816
|
-
return `${
|
|
817
|
-
});
|
|
818
|
-
return kubb_kit.ast.buildObject(entries);
|
|
955
|
+
})) return `get ${objectKey(property.name)}() { const _value = ${value}; Object.defineProperty(this, ${JSON.stringify(property.name)}, { value: _value, configurable: true, writable: true, enumerable: true }); return _value }`;
|
|
956
|
+
return `${objectKey(property.name)}: ${value}`;
|
|
957
|
+
}));
|
|
819
958
|
},
|
|
820
959
|
...options.nodes
|
|
821
960
|
},
|
|
@@ -845,22 +984,20 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
845
984
|
const isEnumSchema = !!kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
|
|
846
985
|
const tsEnumType = pluginTs.options?.enum?.type;
|
|
847
986
|
const tsEnumTypeSuffix = pluginTs.options?.enum?.typeSuffix ?? "Key";
|
|
848
|
-
const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.
|
|
987
|
+
const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.enum.keyName({ name: schemaName }, tsEnumTypeSuffix) : tsResolver.name(schemaName);
|
|
849
988
|
const meta = {
|
|
850
|
-
name: resolver.
|
|
851
|
-
file: resolver.
|
|
989
|
+
name: resolver.name(schemaName),
|
|
990
|
+
file: resolver.file({
|
|
852
991
|
name: schemaName,
|
|
853
|
-
extname: ".ts"
|
|
854
|
-
}, {
|
|
992
|
+
extname: ".ts",
|
|
855
993
|
root,
|
|
856
994
|
output,
|
|
857
995
|
group: group ?? void 0
|
|
858
996
|
}),
|
|
859
997
|
typeName: schemaTypeName,
|
|
860
|
-
typeFile: tsResolver.
|
|
998
|
+
typeFile: tsResolver.file({
|
|
861
999
|
name: schemaName,
|
|
862
|
-
extname: ".ts"
|
|
863
|
-
}, {
|
|
1000
|
+
extname: ".ts",
|
|
864
1001
|
root,
|
|
865
1002
|
output: pluginTs.options?.output ?? output,
|
|
866
1003
|
group: pluginTs.options?.group ?? void 0
|
|
@@ -888,11 +1025,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
888
1025
|
typeFilePath: meta.typeFile.path
|
|
889
1026
|
});
|
|
890
1027
|
const usedImports = filterUsedImports(adapter.getImports(node, (schemaName) => ({
|
|
891
|
-
name: resolver.
|
|
892
|
-
path: resolver.
|
|
1028
|
+
name: resolver.name(schemaName),
|
|
1029
|
+
path: resolver.file({
|
|
893
1030
|
name: schemaName,
|
|
894
|
-
extname: ".ts"
|
|
895
|
-
}, {
|
|
1031
|
+
extname: ".ts",
|
|
896
1032
|
root,
|
|
897
1033
|
output,
|
|
898
1034
|
group: group ?? void 0
|
|
@@ -902,7 +1038,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
902
1038
|
baseName: meta.file.baseName,
|
|
903
1039
|
path: meta.file.path,
|
|
904
1040
|
meta: meta.file.meta,
|
|
905
|
-
banner: resolver.
|
|
1041
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
906
1042
|
output,
|
|
907
1043
|
config,
|
|
908
1044
|
file: {
|
|
@@ -910,7 +1046,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
910
1046
|
baseName: meta.file.baseName
|
|
911
1047
|
}
|
|
912
1048
|
}),
|
|
913
|
-
footer: resolver.
|
|
1049
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
914
1050
|
output,
|
|
915
1051
|
config,
|
|
916
1052
|
file: {
|
|
@@ -967,10 +1103,31 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
967
1103
|
const pluginTs = ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
968
1104
|
if (!pluginTs) return;
|
|
969
1105
|
const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
970
|
-
const
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1106
|
+
const params = caseParams(node.parameters, "camelcase");
|
|
1107
|
+
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
|
|
1108
|
+
...node,
|
|
1109
|
+
parameters: params
|
|
1110
|
+
}, { paramsCasing: "original" });
|
|
1111
|
+
const paramGroups = [
|
|
1112
|
+
{
|
|
1113
|
+
params: pathParams,
|
|
1114
|
+
name: resolver.param.path,
|
|
1115
|
+
typeName: tsResolver.param.path
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
params: queryParams,
|
|
1119
|
+
name: resolver.param.query,
|
|
1120
|
+
typeName: tsResolver.param.query
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
params: headerParams,
|
|
1124
|
+
name: resolver.param.headers,
|
|
1125
|
+
typeName: tsResolver.param.headers
|
|
1126
|
+
}
|
|
1127
|
+
].filter((group) => group.params.length > 0).map((group) => ({
|
|
1128
|
+
schema: (0, _kubb_plugin_ts.buildParams)({ params: group.params }),
|
|
1129
|
+
name: group.name(node, group.params[0]),
|
|
1130
|
+
typeName: group.typeName(node, group.params[0])
|
|
974
1131
|
}));
|
|
975
1132
|
function expandContentUnits(entries, baseName, tsBaseName, description, decorate) {
|
|
976
1133
|
const withSchema = entries.filter((entry) => entry.schema);
|
|
@@ -1007,36 +1164,34 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1007
1164
|
skipImportNames: variants.map((variant) => variant.name)
|
|
1008
1165
|
}];
|
|
1009
1166
|
}
|
|
1010
|
-
const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.
|
|
1011
|
-
const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.
|
|
1167
|
+
const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.response.status(node, response.statusCode), tsResolver.response.status(node, response.statusCode), response.description));
|
|
1168
|
+
const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.response.body(node), tsResolver.response.body(node), node.requestBody?.description, (schema) => ({
|
|
1012
1169
|
...schema,
|
|
1013
1170
|
description: node.requestBody?.description ?? schema.description
|
|
1014
1171
|
}));
|
|
1015
|
-
const responseName = resolver.
|
|
1172
|
+
const responseName = resolver.response.response(node);
|
|
1016
1173
|
const localHelperNames = /* @__PURE__ */ new Set([
|
|
1017
|
-
...
|
|
1174
|
+
...paramGroups.map((group) => group.name),
|
|
1018
1175
|
...responseUnits.map((unit) => unit.name),
|
|
1019
1176
|
...dataUnits.map((unit) => unit.name),
|
|
1020
1177
|
responseName
|
|
1021
1178
|
]);
|
|
1022
1179
|
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1023
1180
|
const meta = {
|
|
1024
|
-
file: resolver.
|
|
1181
|
+
file: resolver.file({
|
|
1025
1182
|
name: node.operationId,
|
|
1026
1183
|
extname: ".ts",
|
|
1027
1184
|
tag: node.tags[0] ?? "default",
|
|
1028
|
-
path: node.path
|
|
1029
|
-
}, {
|
|
1185
|
+
path: node.path,
|
|
1030
1186
|
root,
|
|
1031
1187
|
output,
|
|
1032
1188
|
group: group ?? void 0
|
|
1033
1189
|
}),
|
|
1034
|
-
typeFile: tsResolver.
|
|
1190
|
+
typeFile: tsResolver.file({
|
|
1035
1191
|
name: node.operationId,
|
|
1036
1192
|
extname: ".ts",
|
|
1037
1193
|
tag: node.tags[0] ?? "default",
|
|
1038
|
-
path: node.path
|
|
1039
|
-
}, {
|
|
1194
|
+
path: node.path,
|
|
1040
1195
|
root,
|
|
1041
1196
|
output: pluginTs.options?.output ?? output,
|
|
1042
1197
|
group: pluginTs.options?.group ?? void 0
|
|
@@ -1044,11 +1199,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1044
1199
|
};
|
|
1045
1200
|
function resolveMockImports(schema) {
|
|
1046
1201
|
return adapter.getImports(schema, (schemaName) => ({
|
|
1047
|
-
name: resolver.
|
|
1048
|
-
path: resolver.
|
|
1202
|
+
name: resolver.name(schemaName),
|
|
1203
|
+
path: resolver.file({
|
|
1049
1204
|
name: schemaName,
|
|
1050
|
-
extname: ".ts"
|
|
1051
|
-
}, {
|
|
1205
|
+
extname: ".ts",
|
|
1052
1206
|
root,
|
|
1053
1207
|
output,
|
|
1054
1208
|
group: group ?? void 0
|
|
@@ -1113,7 +1267,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1113
1267
|
baseName: meta.file.baseName,
|
|
1114
1268
|
path: meta.file.path,
|
|
1115
1269
|
meta: meta.file.meta,
|
|
1116
|
-
banner: resolver.
|
|
1270
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1117
1271
|
output,
|
|
1118
1272
|
config,
|
|
1119
1273
|
file: {
|
|
@@ -1121,7 +1275,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1121
1275
|
baseName: meta.file.baseName
|
|
1122
1276
|
}
|
|
1123
1277
|
}),
|
|
1124
|
-
footer: resolver.
|
|
1278
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1125
1279
|
output,
|
|
1126
1280
|
config,
|
|
1127
1281
|
file: {
|
|
@@ -1145,11 +1299,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1145
1299
|
path: dateParser,
|
|
1146
1300
|
name: dateParser
|
|
1147
1301
|
}),
|
|
1148
|
-
|
|
1149
|
-
schema: param.schema,
|
|
1150
|
-
name,
|
|
1151
|
-
typeName
|
|
1152
|
-
})),
|
|
1302
|
+
paramGroups.map((group) => renderEntry(group)),
|
|
1153
1303
|
responseUnits.map((unit) => renderEntry({
|
|
1154
1304
|
schema: unit.schema,
|
|
1155
1305
|
name: unit.name,
|
|
@@ -1167,7 +1317,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1167
1317
|
renderEntry({
|
|
1168
1318
|
schema: buildResponseUnionSchema(node, resolver),
|
|
1169
1319
|
name: responseName,
|
|
1170
|
-
typeName: tsResolver.
|
|
1320
|
+
typeName: tsResolver.response.response(node),
|
|
1171
1321
|
skipImportNames: responseUnits.map((unit) => unit.name)
|
|
1172
1322
|
})
|
|
1173
1323
|
]
|
|
@@ -1185,69 +1335,45 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1185
1335
|
* ```ts
|
|
1186
1336
|
* import { resolverFaker } from '@kubb/plugin-faker'
|
|
1187
1337
|
*
|
|
1188
|
-
* resolverFaker.
|
|
1338
|
+
* resolverFaker.name('list pets') // 'createListPets'
|
|
1189
1339
|
* ```
|
|
1190
1340
|
*/
|
|
1191
|
-
const resolverFaker = (0, kubb_kit.
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
resolvePathName(name, type) {
|
|
1203
|
-
return this.default(name, type);
|
|
1204
|
-
},
|
|
1205
|
-
resolveFile({ name, extname, tag, path: groupPath }, context) {
|
|
1206
|
-
const inputBaseName = `${context.output.mode === "file" ? "" : this.resolveName(name, "file")}${extname}`;
|
|
1207
|
-
const filePath = this.resolvePath({
|
|
1208
|
-
baseName: inputBaseName,
|
|
1209
|
-
tag,
|
|
1210
|
-
path: groupPath
|
|
1211
|
-
}, context);
|
|
1212
|
-
const baseName = node_path.default.basename(filePath);
|
|
1213
|
-
return {
|
|
1214
|
-
kind: "File",
|
|
1215
|
-
id: (0, node_crypto.createHash)("sha256").update(filePath).digest("hex"),
|
|
1216
|
-
name: node_path.default.basename(filePath, extname),
|
|
1217
|
-
path: filePath,
|
|
1218
|
-
baseName,
|
|
1219
|
-
extname,
|
|
1220
|
-
meta: { pluginName: this.pluginName },
|
|
1221
|
-
sources: [],
|
|
1222
|
-
imports: [],
|
|
1223
|
-
exports: []
|
|
1224
|
-
};
|
|
1225
|
-
},
|
|
1226
|
-
resolveParamName(node, param) {
|
|
1227
|
-
return this.resolveName(`${node.operationId} ${param.in} ${param.name}`);
|
|
1228
|
-
},
|
|
1229
|
-
resolveDataName(node) {
|
|
1230
|
-
return this.resolveName(`${node.operationId} Data`);
|
|
1341
|
+
const resolverFaker = (0, kubb_kit.createResolver)({
|
|
1342
|
+
pluginName: "plugin-faker",
|
|
1343
|
+
name(name) {
|
|
1344
|
+
return ensureValidVarName(camelCase(name, { prefix: "create" }));
|
|
1345
|
+
},
|
|
1346
|
+
file: { baseName({ name, extname }) {
|
|
1347
|
+
return `${toFilePath(name, (part) => camelCase(part, { prefix: "create" }))}${extname}`;
|
|
1348
|
+
} },
|
|
1349
|
+
param: {
|
|
1350
|
+
name(node, param) {
|
|
1351
|
+
return this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
1231
1352
|
},
|
|
1232
|
-
|
|
1233
|
-
return this.
|
|
1353
|
+
path(node) {
|
|
1354
|
+
return this.name(`${node.operationId} Path`);
|
|
1234
1355
|
},
|
|
1235
|
-
|
|
1236
|
-
return this.
|
|
1356
|
+
query(node) {
|
|
1357
|
+
return this.name(`${node.operationId} Query`);
|
|
1237
1358
|
},
|
|
1238
|
-
|
|
1239
|
-
return this.
|
|
1359
|
+
headers(node) {
|
|
1360
|
+
return this.name(`${node.operationId} Headers`);
|
|
1361
|
+
}
|
|
1362
|
+
},
|
|
1363
|
+
response: {
|
|
1364
|
+
status(node, statusCode) {
|
|
1365
|
+
return this.name(`${node.operationId} Status ${statusCode}`);
|
|
1240
1366
|
},
|
|
1241
|
-
|
|
1242
|
-
return this.
|
|
1367
|
+
body(node) {
|
|
1368
|
+
return this.name(`${node.operationId} Body`);
|
|
1243
1369
|
},
|
|
1244
|
-
|
|
1245
|
-
return this.
|
|
1370
|
+
response(node) {
|
|
1371
|
+
return this.name(`${node.operationId} Response`);
|
|
1246
1372
|
},
|
|
1247
|
-
|
|
1248
|
-
return this.
|
|
1373
|
+
responses(node) {
|
|
1374
|
+
return this.name(`${node.operationId} Responses`);
|
|
1249
1375
|
}
|
|
1250
|
-
}
|
|
1376
|
+
}
|
|
1251
1377
|
});
|
|
1252
1378
|
//#endregion
|
|
1253
1379
|
//#region src/plugin.ts
|
|
@@ -1303,10 +1429,7 @@ const pluginFaker = (0, kubb_kit.definePlugin)((options) => {
|
|
|
1303
1429
|
regexGenerator,
|
|
1304
1430
|
printer
|
|
1305
1431
|
});
|
|
1306
|
-
ctx.setResolver(userResolver ?
|
|
1307
|
-
...resolverFaker,
|
|
1308
|
-
...userResolver
|
|
1309
|
-
} : resolverFaker);
|
|
1432
|
+
ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverFaker, userResolver) : resolverFaker);
|
|
1310
1433
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1311
1434
|
ctx.addGenerator(fakerGenerator);
|
|
1312
1435
|
} }
|