@kubb/plugin-faker 5.0.0-beta.84 → 5.0.0-beta.85
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 +493 -368
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +69 -110
- package/dist/index.js +492 -345
- 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 /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(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
|
}
|
|
@@ -261,14 +597,14 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
|
|
|
261
597
|
children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.Function, {
|
|
262
598
|
export: true,
|
|
263
599
|
name,
|
|
264
|
-
JSDoc: { comments: description ? [`@description ${
|
|
600
|
+
JSDoc: { comments: description ? [`@description ${jsStringEscape(description)}`] : [] },
|
|
265
601
|
params: canOverride ? paramsSignature : void 0,
|
|
266
602
|
returnType: returnType ?? void 0,
|
|
267
603
|
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
604
|
})
|
|
269
605
|
});
|
|
270
606
|
}
|
|
271
|
-
const functionSignature = `${description ? `/**\n * @description ${
|
|
607
|
+
const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
|
|
272
608
|
const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
|
|
273
609
|
const { cyclicSchemas, schemaName } = printer.options;
|
|
274
610
|
const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => kubb_kit.ast.containsCircularRef(p.schema, {
|
|
@@ -297,226 +633,6 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
|
|
|
297
633
|
});
|
|
298
634
|
}
|
|
299
635
|
//#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
636
|
//#region ../../internals/shared/src/params.ts
|
|
521
637
|
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
522
638
|
/**
|
|
@@ -537,6 +653,23 @@ function caseParams(params, casing) {
|
|
|
537
653
|
caseParamsCache.set(params, result);
|
|
538
654
|
return result;
|
|
539
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Drops parameters that collapse to the same property identity once camelCased, keeping the first.
|
|
658
|
+
*
|
|
659
|
+
* Some specs declare the same parameter twice under different casings (for example AWS S3 lists both
|
|
660
|
+
* `max-uploads` and `MaxUploads`). Both resolve to one output property, so emitting both would yield
|
|
661
|
+
* an object type with a duplicate member, which TypeScript rejects. De-duplicate by the camelCased
|
|
662
|
+
* identity so the resulting group is collision-free regardless of the names each caller carries.
|
|
663
|
+
*/
|
|
664
|
+
function dedupeByCasedName(params) {
|
|
665
|
+
const seen = /* @__PURE__ */ new Set();
|
|
666
|
+
return params.filter((param) => {
|
|
667
|
+
const key = camelCase(param.name);
|
|
668
|
+
if (seen.has(key)) return false;
|
|
669
|
+
seen.add(key);
|
|
670
|
+
return true;
|
|
671
|
+
});
|
|
672
|
+
}
|
|
540
673
|
//#endregion
|
|
541
674
|
//#region ../../internals/shared/src/operation.ts
|
|
542
675
|
/**
|
|
@@ -587,6 +720,15 @@ function resolveContentTypeVariants(entries, baseName) {
|
|
|
587
720
|
};
|
|
588
721
|
});
|
|
589
722
|
}
|
|
723
|
+
function getOperationParameters(node, options = {}) {
|
|
724
|
+
const params = caseParams(node.parameters, options.paramsCasing === "original" ? void 0 : "camelcase");
|
|
725
|
+
return {
|
|
726
|
+
path: dedupeByCasedName(params.filter((param) => param.in === "path")),
|
|
727
|
+
query: dedupeByCasedName(params.filter((param) => param.in === "query")),
|
|
728
|
+
header: dedupeByCasedName(params.filter((param) => param.in === "header")),
|
|
729
|
+
cookie: dedupeByCasedName(params.filter((param) => param.in === "cookie"))
|
|
730
|
+
};
|
|
731
|
+
}
|
|
590
732
|
//#endregion
|
|
591
733
|
//#region ../../internals/shared/src/group.ts
|
|
592
734
|
/**
|
|
@@ -681,7 +823,7 @@ const fakerKeywordMapper = {
|
|
|
681
823
|
return `{...${items.join(", ...")}}`;
|
|
682
824
|
},
|
|
683
825
|
matches: (value = "", regexGenerator = "faker") => {
|
|
684
|
-
if (regexGenerator === "randexp") return `${
|
|
826
|
+
if (regexGenerator === "randexp") return `${toRegExpString(value, "RandExp")}.gen()`;
|
|
685
827
|
return `faker.helpers.fromRegExp("${value}")`;
|
|
686
828
|
},
|
|
687
829
|
email: () => "faker.internet.email()",
|
|
@@ -692,7 +834,7 @@ function getEnumValues(node) {
|
|
|
692
834
|
return node.enumValues ?? [];
|
|
693
835
|
}
|
|
694
836
|
function parseEnumValue(value) {
|
|
695
|
-
if (typeof value === "string") return
|
|
837
|
+
if (typeof value === "string") return stringify(value);
|
|
696
838
|
return value;
|
|
697
839
|
}
|
|
698
840
|
/**
|
|
@@ -760,7 +902,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
760
902
|
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
903
|
if (!refName) throw new Error("Name not defined for ref node");
|
|
762
904
|
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.
|
|
905
|
+
const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
|
|
764
906
|
if (!this.options.nestedInObject) return `${resolvedName}(data)`;
|
|
765
907
|
return `${resolvedName}()`;
|
|
766
908
|
},
|
|
@@ -804,7 +946,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
804
946
|
},
|
|
805
947
|
object(node) {
|
|
806
948
|
const cyclicSchemas = this.options.cyclicSchemas;
|
|
807
|
-
|
|
949
|
+
return buildObject((node.properties ?? []).map((property) => {
|
|
808
950
|
const value = printNested(property.schema, {
|
|
809
951
|
typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
|
|
810
952
|
nestedInObject: true
|
|
@@ -812,10 +954,9 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
812
954
|
if (cyclicSchemas && kubb_kit.ast.containsCircularRef(property.schema, {
|
|
813
955
|
circularSchemas: cyclicSchemas,
|
|
814
956
|
excludeName: this.options.schemaName
|
|
815
|
-
})) return `get ${
|
|
816
|
-
return `${
|
|
817
|
-
});
|
|
818
|
-
return kubb_kit.ast.buildObject(entries);
|
|
957
|
+
})) 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 }`;
|
|
958
|
+
return `${objectKey(property.name)}: ${value}`;
|
|
959
|
+
}));
|
|
819
960
|
},
|
|
820
961
|
...options.nodes
|
|
821
962
|
},
|
|
@@ -845,22 +986,20 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
845
986
|
const isEnumSchema = !!kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
|
|
846
987
|
const tsEnumType = pluginTs.options?.enum?.type;
|
|
847
988
|
const tsEnumTypeSuffix = pluginTs.options?.enum?.typeSuffix ?? "Key";
|
|
848
|
-
const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.
|
|
989
|
+
const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.enum.keyName({ name: schemaName }, tsEnumTypeSuffix) : tsResolver.name(schemaName);
|
|
849
990
|
const meta = {
|
|
850
|
-
name: resolver.
|
|
851
|
-
file: resolver.
|
|
991
|
+
name: resolver.name(schemaName),
|
|
992
|
+
file: resolver.file({
|
|
852
993
|
name: schemaName,
|
|
853
|
-
extname: ".ts"
|
|
854
|
-
}, {
|
|
994
|
+
extname: ".ts",
|
|
855
995
|
root,
|
|
856
996
|
output,
|
|
857
997
|
group: group ?? void 0
|
|
858
998
|
}),
|
|
859
999
|
typeName: schemaTypeName,
|
|
860
|
-
typeFile: tsResolver.
|
|
1000
|
+
typeFile: tsResolver.file({
|
|
861
1001
|
name: schemaName,
|
|
862
|
-
extname: ".ts"
|
|
863
|
-
}, {
|
|
1002
|
+
extname: ".ts",
|
|
864
1003
|
root,
|
|
865
1004
|
output: pluginTs.options?.output ?? output,
|
|
866
1005
|
group: pluginTs.options?.group ?? void 0
|
|
@@ -888,11 +1027,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
888
1027
|
typeFilePath: meta.typeFile.path
|
|
889
1028
|
});
|
|
890
1029
|
const usedImports = filterUsedImports(adapter.getImports(node, (schemaName) => ({
|
|
891
|
-
name: resolver.
|
|
892
|
-
path: resolver.
|
|
1030
|
+
name: resolver.name(schemaName),
|
|
1031
|
+
path: resolver.file({
|
|
893
1032
|
name: schemaName,
|
|
894
|
-
extname: ".ts"
|
|
895
|
-
}, {
|
|
1033
|
+
extname: ".ts",
|
|
896
1034
|
root,
|
|
897
1035
|
output,
|
|
898
1036
|
group: group ?? void 0
|
|
@@ -902,7 +1040,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
902
1040
|
baseName: meta.file.baseName,
|
|
903
1041
|
path: meta.file.path,
|
|
904
1042
|
meta: meta.file.meta,
|
|
905
|
-
banner: resolver.
|
|
1043
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
906
1044
|
output,
|
|
907
1045
|
config,
|
|
908
1046
|
file: {
|
|
@@ -910,7 +1048,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
910
1048
|
baseName: meta.file.baseName
|
|
911
1049
|
}
|
|
912
1050
|
}),
|
|
913
|
-
footer: resolver.
|
|
1051
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
914
1052
|
output,
|
|
915
1053
|
config,
|
|
916
1054
|
file: {
|
|
@@ -967,10 +1105,31 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
967
1105
|
const pluginTs = ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
968
1106
|
if (!pluginTs) return;
|
|
969
1107
|
const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
970
|
-
const
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1108
|
+
const params = caseParams(node.parameters, "camelcase");
|
|
1109
|
+
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
|
|
1110
|
+
...node,
|
|
1111
|
+
parameters: params
|
|
1112
|
+
}, { paramsCasing: "original" });
|
|
1113
|
+
const paramGroups = [
|
|
1114
|
+
{
|
|
1115
|
+
params: pathParams,
|
|
1116
|
+
name: resolver.param.path,
|
|
1117
|
+
typeName: tsResolver.param.path
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
params: queryParams,
|
|
1121
|
+
name: resolver.param.query,
|
|
1122
|
+
typeName: tsResolver.param.query
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
params: headerParams,
|
|
1126
|
+
name: resolver.param.headers,
|
|
1127
|
+
typeName: tsResolver.param.headers
|
|
1128
|
+
}
|
|
1129
|
+
].filter((group) => group.params.length > 0).map((group) => ({
|
|
1130
|
+
schema: (0, _kubb_plugin_ts.buildParams)({ params: group.params }),
|
|
1131
|
+
name: group.name(node, group.params[0]),
|
|
1132
|
+
typeName: group.typeName(node, group.params[0])
|
|
974
1133
|
}));
|
|
975
1134
|
function expandContentUnits(entries, baseName, tsBaseName, description, decorate) {
|
|
976
1135
|
const withSchema = entries.filter((entry) => entry.schema);
|
|
@@ -1007,36 +1166,34 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1007
1166
|
skipImportNames: variants.map((variant) => variant.name)
|
|
1008
1167
|
}];
|
|
1009
1168
|
}
|
|
1010
|
-
const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.
|
|
1011
|
-
const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.
|
|
1169
|
+
const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.response.status(node, response.statusCode), tsResolver.response.status(node, response.statusCode), response.description));
|
|
1170
|
+
const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.response.body(node), tsResolver.response.body(node), node.requestBody?.description, (schema) => ({
|
|
1012
1171
|
...schema,
|
|
1013
1172
|
description: node.requestBody?.description ?? schema.description
|
|
1014
1173
|
}));
|
|
1015
|
-
const responseName = resolver.
|
|
1174
|
+
const responseName = resolver.response.response(node);
|
|
1016
1175
|
const localHelperNames = /* @__PURE__ */ new Set([
|
|
1017
|
-
...
|
|
1176
|
+
...paramGroups.map((group) => group.name),
|
|
1018
1177
|
...responseUnits.map((unit) => unit.name),
|
|
1019
1178
|
...dataUnits.map((unit) => unit.name),
|
|
1020
1179
|
responseName
|
|
1021
1180
|
]);
|
|
1022
1181
|
const cyclicSchemas = new Set(ctx.meta.circularNames);
|
|
1023
1182
|
const meta = {
|
|
1024
|
-
file: resolver.
|
|
1183
|
+
file: resolver.file({
|
|
1025
1184
|
name: node.operationId,
|
|
1026
1185
|
extname: ".ts",
|
|
1027
1186
|
tag: node.tags[0] ?? "default",
|
|
1028
|
-
path: node.path
|
|
1029
|
-
}, {
|
|
1187
|
+
path: node.path,
|
|
1030
1188
|
root,
|
|
1031
1189
|
output,
|
|
1032
1190
|
group: group ?? void 0
|
|
1033
1191
|
}),
|
|
1034
|
-
typeFile: tsResolver.
|
|
1192
|
+
typeFile: tsResolver.file({
|
|
1035
1193
|
name: node.operationId,
|
|
1036
1194
|
extname: ".ts",
|
|
1037
1195
|
tag: node.tags[0] ?? "default",
|
|
1038
|
-
path: node.path
|
|
1039
|
-
}, {
|
|
1196
|
+
path: node.path,
|
|
1040
1197
|
root,
|
|
1041
1198
|
output: pluginTs.options?.output ?? output,
|
|
1042
1199
|
group: pluginTs.options?.group ?? void 0
|
|
@@ -1044,11 +1201,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1044
1201
|
};
|
|
1045
1202
|
function resolveMockImports(schema) {
|
|
1046
1203
|
return adapter.getImports(schema, (schemaName) => ({
|
|
1047
|
-
name: resolver.
|
|
1048
|
-
path: resolver.
|
|
1204
|
+
name: resolver.name(schemaName),
|
|
1205
|
+
path: resolver.file({
|
|
1049
1206
|
name: schemaName,
|
|
1050
|
-
extname: ".ts"
|
|
1051
|
-
}, {
|
|
1207
|
+
extname: ".ts",
|
|
1052
1208
|
root,
|
|
1053
1209
|
output,
|
|
1054
1210
|
group: group ?? void 0
|
|
@@ -1113,7 +1269,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1113
1269
|
baseName: meta.file.baseName,
|
|
1114
1270
|
path: meta.file.path,
|
|
1115
1271
|
meta: meta.file.meta,
|
|
1116
|
-
banner: resolver.
|
|
1272
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1117
1273
|
output,
|
|
1118
1274
|
config,
|
|
1119
1275
|
file: {
|
|
@@ -1121,7 +1277,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1121
1277
|
baseName: meta.file.baseName
|
|
1122
1278
|
}
|
|
1123
1279
|
}),
|
|
1124
|
-
footer: resolver.
|
|
1280
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1125
1281
|
output,
|
|
1126
1282
|
config,
|
|
1127
1283
|
file: {
|
|
@@ -1145,11 +1301,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1145
1301
|
path: dateParser,
|
|
1146
1302
|
name: dateParser
|
|
1147
1303
|
}),
|
|
1148
|
-
|
|
1149
|
-
schema: param.schema,
|
|
1150
|
-
name,
|
|
1151
|
-
typeName
|
|
1152
|
-
})),
|
|
1304
|
+
paramGroups.map((group) => renderEntry(group)),
|
|
1153
1305
|
responseUnits.map((unit) => renderEntry({
|
|
1154
1306
|
schema: unit.schema,
|
|
1155
1307
|
name: unit.name,
|
|
@@ -1167,7 +1319,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1167
1319
|
renderEntry({
|
|
1168
1320
|
schema: buildResponseUnionSchema(node, resolver),
|
|
1169
1321
|
name: responseName,
|
|
1170
|
-
typeName: tsResolver.
|
|
1322
|
+
typeName: tsResolver.response.response(node),
|
|
1171
1323
|
skipImportNames: responseUnits.map((unit) => unit.name)
|
|
1172
1324
|
})
|
|
1173
1325
|
]
|
|
@@ -1185,69 +1337,45 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1185
1337
|
* ```ts
|
|
1186
1338
|
* import { resolverFaker } from '@kubb/plugin-faker'
|
|
1187
1339
|
*
|
|
1188
|
-
* resolverFaker.
|
|
1340
|
+
* resolverFaker.name('list pets') // 'createListPets'
|
|
1189
1341
|
* ```
|
|
1190
1342
|
*/
|
|
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`);
|
|
1343
|
+
const resolverFaker = (0, kubb_kit.createResolver)({
|
|
1344
|
+
pluginName: "plugin-faker",
|
|
1345
|
+
name(name) {
|
|
1346
|
+
return ensureValidVarName(camelCase(name, { prefix: "create" }));
|
|
1347
|
+
},
|
|
1348
|
+
file: { baseName({ name, extname }) {
|
|
1349
|
+
return `${toFilePath(name, (part) => camelCase(part, { prefix: "create" }))}${extname}`;
|
|
1350
|
+
} },
|
|
1351
|
+
param: {
|
|
1352
|
+
name(node, param) {
|
|
1353
|
+
return this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
1231
1354
|
},
|
|
1232
|
-
|
|
1233
|
-
return this.
|
|
1355
|
+
path(node) {
|
|
1356
|
+
return this.name(`${node.operationId} Path`);
|
|
1234
1357
|
},
|
|
1235
|
-
|
|
1236
|
-
return this.
|
|
1358
|
+
query(node) {
|
|
1359
|
+
return this.name(`${node.operationId} Query`);
|
|
1237
1360
|
},
|
|
1238
|
-
|
|
1239
|
-
return this.
|
|
1361
|
+
headers(node) {
|
|
1362
|
+
return this.name(`${node.operationId} Headers`);
|
|
1363
|
+
}
|
|
1364
|
+
},
|
|
1365
|
+
response: {
|
|
1366
|
+
status(node, statusCode) {
|
|
1367
|
+
return this.name(`${node.operationId} Status ${statusCode}`);
|
|
1240
1368
|
},
|
|
1241
|
-
|
|
1242
|
-
return this.
|
|
1369
|
+
body(node) {
|
|
1370
|
+
return this.name(`${node.operationId} Body`);
|
|
1243
1371
|
},
|
|
1244
|
-
|
|
1245
|
-
return this.
|
|
1372
|
+
response(node) {
|
|
1373
|
+
return this.name(`${node.operationId} Response`);
|
|
1246
1374
|
},
|
|
1247
|
-
|
|
1248
|
-
return this.
|
|
1375
|
+
responses(node) {
|
|
1376
|
+
return this.name(`${node.operationId} Responses`);
|
|
1249
1377
|
}
|
|
1250
|
-
}
|
|
1378
|
+
}
|
|
1251
1379
|
});
|
|
1252
1380
|
//#endregion
|
|
1253
1381
|
//#region src/plugin.ts
|
|
@@ -1303,10 +1431,7 @@ const pluginFaker = (0, kubb_kit.definePlugin)((options) => {
|
|
|
1303
1431
|
regexGenerator,
|
|
1304
1432
|
printer
|
|
1305
1433
|
});
|
|
1306
|
-
ctx.setResolver(userResolver ?
|
|
1307
|
-
...resolverFaker,
|
|
1308
|
-
...userResolver
|
|
1309
|
-
} : resolverFaker);
|
|
1434
|
+
ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverFaker, userResolver) : resolverFaker);
|
|
1310
1435
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1311
1436
|
ctx.addGenerator(fakerGenerator);
|
|
1312
1437
|
} }
|