@kubb/plugin-faker 5.0.0-beta.81 → 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 CHANGED
@@ -2,36 +2,382 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- //#region \0rolldown/runtime.js
6
- var __create = Object.create;
7
- var __defProp = Object.defineProperty;
8
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
- var __getOwnPropNames = Object.getOwnPropertyNames;
10
- var __getProtoOf = Object.getPrototypeOf;
11
- var __hasOwnProp = Object.prototype.hasOwnProperty;
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
14
- key = keys[i];
15
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
- get: ((k) => from[k]).bind(null, key),
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
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 to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
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_ast_utils = require("@kubb/ast/utils");
28
- let _kubb_plugin_ts = require("@kubb/plugin-ts");
29
- let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
30
- let node_path = require("node:path");
31
- node_path = __toESM(node_path, 1);
32
- let _kubb_core = require("@kubb/core");
33
- let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
34
- let node_crypto = require("node:crypto");
35
381
  //#region src/utils.ts
36
382
  /**
37
383
  * Returns the `@faker-js/faker` named export for a locale code.
@@ -80,17 +426,6 @@ function canOverrideSchema(node) {
80
426
  "blob"
81
427
  ])).has(node.type);
82
428
  }
83
- /**
84
- * Resolves a parameter name based on its location (path, query, header, etc.) using the provided resolver.
85
- */
86
- function resolveParamNameByLocation(resolver, node, param) {
87
- switch (param.in) {
88
- case "path": return resolver.resolvePathParamsName(node, param);
89
- case "query": return resolver.resolveQueryParamsName(node, param);
90
- case "header": return resolver.resolveHeaderParamsName(node, param);
91
- default: return resolver.resolveParamName(node, param);
92
- }
93
- }
94
429
  function shouldInlineSingleResponseSchema(schema) {
95
430
  return (/* @__PURE__ */ new Set([
96
431
  "any",
@@ -125,16 +460,16 @@ function buildResponseUnionSchema(node, resolver) {
125
460
  if (responses.length === 1) {
126
461
  const schema = responses[0].content?.[0]?.schema;
127
462
  if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
128
- return _kubb_core.ast.factory.createSchema({
463
+ return kubb_kit.ast.factory.createSchema({
129
464
  type: "ref",
130
- name: resolver.resolveResponseStatusName(node, responses[0].statusCode)
465
+ name: resolver.response.status(node, responses[0].statusCode)
131
466
  });
132
467
  }
133
- return _kubb_core.ast.factory.createSchema({
468
+ return kubb_kit.ast.factory.createSchema({
134
469
  type: "union",
135
- members: responses.map((response) => _kubb_core.ast.factory.createSchema({
470
+ members: responses.map((response) => kubb_kit.ast.factory.createSchema({
136
471
  type: "ref",
137
- name: resolver.resolveResponseStatusName(node, response.statusCode)
472
+ name: resolver.response.status(node, response.statusCode)
138
473
  }))
139
474
  });
140
475
  }
@@ -255,24 +590,24 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
255
590
  const paramsSignature = declarationPrinter.print(params) ?? "";
256
591
  const returnType = resolvedReturnType;
257
592
  const returnExpression = node.type === "ref" && canOverride && returnType ? `${fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
258
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
593
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
259
594
  name,
260
595
  isExportable: true,
261
596
  isIndexable: true,
262
- children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.Function, {
597
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.Function, {
263
598
  export: true,
264
599
  name,
265
- JSDoc: { comments: description ? [`@description ${(0, _kubb_ast_utils.jsStringEscape)(description)}`] : [] },
600
+ JSDoc: { comments: description ? [`@description ${jsStringEscape(description)}`] : [] },
266
601
  params: canOverride ? paramsSignature : void 0,
267
602
  returnType: returnType ?? void 0,
268
- children: [seed ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [`faker.seed(${JSON.stringify(seed)})`, /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {})] }) : void 0, `return ${returnExpression}`]
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}`]
269
604
  })
270
605
  });
271
606
  }
272
- const functionSignature = `${description ? `/**\n * @description ${(0, _kubb_ast_utils.jsStringEscape)(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
607
+ const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
273
608
  const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
274
609
  const { cyclicSchemas, schemaName } = printer.options;
275
- const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, _kubb_ast_utils.containsCircularRef)(p.schema, {
610
+ const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => kubb_kit.ast.containsCircularRef(p.schema, {
276
611
  circularSchemas: cyclicSchemas,
277
612
  excludeName: schemaName
278
613
  })) ? `{
@@ -290,7 +625,7 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
290
625
  ...(data || {}),
291
626
  } as Omit<typeof defaultFakeData, keyof TData> & TData
292
627
  }`;
293
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File.Source, {
628
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File.Source, {
294
629
  name,
295
630
  isExportable: true,
296
631
  isIndexable: true,
@@ -298,226 +633,6 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
298
633
  });
299
634
  }
300
635
  //#endregion
301
- //#region ../../internals/utils/src/casing.ts
302
- /**
303
- * Shared implementation for camelCase and PascalCase conversion.
304
- * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
305
- * and capitalizes each word according to `pascal`.
306
- *
307
- * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
308
- */
309
- function toCamelOrPascal(text, pascal) {
310
- 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) => {
311
- if (word.length > 1 && word === word.toUpperCase()) return word;
312
- return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
313
- }).join("").replace(/[^a-zA-Z0-9]/g, "");
314
- }
315
- /**
316
- * Converts `text` to camelCase.
317
- *
318
- * @example Word boundaries
319
- * `camelCase('hello-world') // 'helloWorld'`
320
- *
321
- * @example With a prefix
322
- * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
323
- */
324
- function camelCase(text, { prefix = "", suffix = "" } = {}) {
325
- return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
326
- }
327
- //#endregion
328
- //#region ../../internals/utils/src/fs.ts
329
- /**
330
- * Builds a nested file path from a dotted name. Splits on dots that precede a letter
331
- * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
332
- * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
333
- *
334
- * Empty segments are dropped before joining. They arise when the name starts with a dot
335
- * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
336
- * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
337
- * absolute path, letting generated files escape the configured output directory.
338
- *
339
- * @example Nested path from a dotted name
340
- * `toFilePath('pet.petId') // 'pet/petId'`
341
- *
342
- * @example PascalCase the final segment
343
- * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
344
- *
345
- * @example Suffix applied to the final segment only
346
- * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
347
- */
348
- function toFilePath(name, caseLast = camelCase) {
349
- const parts = name.split(/\.(?=[a-zA-Z])/);
350
- return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
351
- }
352
- //#endregion
353
- //#region ../../internals/utils/src/imports.ts
354
- function escapeRegExp(value) {
355
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
356
- }
357
- function getImportNames(entry) {
358
- return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
359
- if (typeof name === "string") return name;
360
- return name.name ?? name.propertyName;
361
- }).filter((name) => Boolean(name));
362
- }
363
- function filterUsedImports(imports, text, skipImportNames = []) {
364
- const skip = new Set(skipImportNames);
365
- return imports.filter((entry) => {
366
- return getImportNames(entry).some((name) => {
367
- if (skip.has(name)) return false;
368
- return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*\\()`).test(text);
369
- });
370
- });
371
- }
372
- function aliasConflictingImports(imports, reservedNames) {
373
- const reservedNameSet = new Set(reservedNames);
374
- const aliases = /* @__PURE__ */ new Map();
375
- return {
376
- imports: imports.map((entry) => {
377
- const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
378
- if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
379
- const alias = `${item}Schema`;
380
- aliases.set(item, alias);
381
- return {
382
- propertyName: item,
383
- name: alias
384
- };
385
- });
386
- return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
387
- ...entry,
388
- name: aliasedNames
389
- } : entry;
390
- }),
391
- aliases
392
- };
393
- }
394
- function rewriteAliasedImports(text, aliases) {
395
- return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
396
- }
397
- //#endregion
398
- //#region ../../internals/utils/src/reserved.ts
399
- /**
400
- * JavaScript and Java reserved words.
401
- * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
402
- */
403
- const reservedWords = /* @__PURE__ */ new Set([
404
- "abstract",
405
- "arguments",
406
- "boolean",
407
- "break",
408
- "byte",
409
- "case",
410
- "catch",
411
- "char",
412
- "class",
413
- "const",
414
- "continue",
415
- "debugger",
416
- "default",
417
- "delete",
418
- "do",
419
- "double",
420
- "else",
421
- "enum",
422
- "eval",
423
- "export",
424
- "extends",
425
- "false",
426
- "final",
427
- "finally",
428
- "float",
429
- "for",
430
- "function",
431
- "goto",
432
- "if",
433
- "implements",
434
- "import",
435
- "in",
436
- "instanceof",
437
- "int",
438
- "interface",
439
- "let",
440
- "long",
441
- "native",
442
- "new",
443
- "null",
444
- "package",
445
- "private",
446
- "protected",
447
- "public",
448
- "return",
449
- "short",
450
- "static",
451
- "super",
452
- "switch",
453
- "synchronized",
454
- "this",
455
- "throw",
456
- "throws",
457
- "transient",
458
- "true",
459
- "try",
460
- "typeof",
461
- "var",
462
- "void",
463
- "volatile",
464
- "while",
465
- "with",
466
- "yield",
467
- "Array",
468
- "Date",
469
- "hasOwnProperty",
470
- "Infinity",
471
- "isFinite",
472
- "isNaN",
473
- "isPrototypeOf",
474
- "length",
475
- "Math",
476
- "name",
477
- "NaN",
478
- "Number",
479
- "Object",
480
- "prototype",
481
- "String",
482
- "toString",
483
- "undefined",
484
- "valueOf"
485
- ]);
486
- /**
487
- * Returns `true` when `name` is a syntactically valid JavaScript variable name.
488
- *
489
- * @example
490
- * ```ts
491
- * isValidVarName('status') // true
492
- * isValidVarName('class') // false (reserved word)
493
- * isValidVarName('42foo') // false (starts with digit)
494
- * ```
495
- */
496
- function isValidVarName(name) {
497
- if (!name || reservedWords.has(name)) return false;
498
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
499
- }
500
- /**
501
- * Returns `name` when it's a syntactically valid JavaScript variable name,
502
- * otherwise prefixes it with `_` so the result is a valid identifier.
503
- *
504
- * Useful for sanitizing OpenAPI schema names or operation IDs that start with
505
- * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
506
- * variable, type, or function names.
507
- *
508
- * @example
509
- * ```ts
510
- * ensureValidVarName('409') // '_409'
511
- * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
512
- * ensureValidVarName('Pet') // 'Pet'
513
- * ensureValidVarName('class') // '_class'
514
- * ```
515
- */
516
- function ensureValidVarName(name) {
517
- if (!name || isValidVarName(name)) return name;
518
- return `_${name}`;
519
- }
520
- //#endregion
521
636
  //#region ../../internals/shared/src/params.ts
522
637
  const caseParamsCache = /* @__PURE__ */ new WeakMap();
523
638
  /**
@@ -538,6 +653,23 @@ function caseParams(params, casing) {
538
653
  caseParamsCache.set(params, result);
539
654
  return result;
540
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
+ }
541
673
  //#endregion
542
674
  //#region ../../internals/shared/src/operation.ts
543
675
  /**
@@ -588,6 +720,15 @@ function resolveContentTypeVariants(entries, baseName) {
588
720
  };
589
721
  });
590
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
+ }
591
732
  //#endregion
592
733
  //#region ../../internals/shared/src/group.ts
593
734
  /**
@@ -682,7 +823,7 @@ const fakerKeywordMapper = {
682
823
  return `{...${items.join(", ...")}}`;
683
824
  },
684
825
  matches: (value = "", regexGenerator = "faker") => {
685
- if (regexGenerator === "randexp") return `${(0, _kubb_ast_utils.toRegExpString)(value, "RandExp")}.gen()`;
826
+ if (regexGenerator === "randexp") return `${toRegExpString(value, "RandExp")}.gen()`;
686
827
  return `faker.helpers.fromRegExp("${value}")`;
687
828
  },
688
829
  email: () => "faker.internet.email()",
@@ -693,15 +834,15 @@ function getEnumValues(node) {
693
834
  return node.enumValues ?? [];
694
835
  }
695
836
  function parseEnumValue(value) {
696
- if (typeof value === "string") return (0, _kubb_ast_utils.stringify)(value);
837
+ if (typeof value === "string") return stringify(value);
697
838
  return value;
698
839
  }
699
840
  /**
700
841
  * Reads the discriminator literal off a variant, or `undefined` when it can't be determined.
701
842
  */
702
843
  function getDiscriminatorValue(member, discriminatorPropertyName) {
703
- const prop = _kubb_core.ast.narrowSchema(member, "object")?.properties?.find((p) => p.name === discriminatorPropertyName);
704
- const enumNode = prop ? _kubb_core.ast.narrowSchema(prop.schema, "enum") : null;
844
+ const prop = kubb_kit.ast.narrowSchema(member, "object")?.properties?.find((p) => p.name === discriminatorPropertyName);
845
+ const enumNode = prop ? kubb_kit.ast.narrowSchema(prop.schema, "enum") : null;
705
846
  return enumNode ? getEnumValues(enumNode)[0] : void 0;
706
847
  }
707
848
  /**
@@ -718,7 +859,7 @@ function indexedTypeName(typeName, propertyName, nestedInUnion) {
718
859
  * Creates a Faker printer that generates mock data generation code from schema nodes.
719
860
  * Handles circular references gracefully by emitting memoizing getters for cyclic properties.
720
861
  */
721
- const printerFaker = _kubb_core.ast.createPrinter((options) => {
862
+ const printerFaker = kubb_kit.ast.createPrinter((options) => {
722
863
  const printNested = (node, overrideOptions = {}) => {
723
864
  return printerFaker({
724
865
  ...options,
@@ -758,10 +899,10 @@ const printerFaker = _kubb_core.ast.createPrinter((options) => {
758
899
  return fakerKeywordMapper.time(node.representation ?? "string", this.options.dateParser);
759
900
  },
760
901
  ref(node) {
761
- const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? (0, _kubb_ast_utils.extractRefName)(node.ref) ?? node.name ?? node.schema?.name : node.name ?? node.schema?.name;
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;
762
903
  if (!refName) throw new Error("Name not defined for ref node");
763
904
  if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
764
- const resolvedName = node.ref ? this.options.resolver.resolveName(refName) : refName;
905
+ const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
765
906
  if (!this.options.nestedInObject) return `${resolvedName}(data)`;
766
907
  return `${resolvedName}()`;
767
908
  },
@@ -771,7 +912,7 @@ const printerFaker = _kubb_core.ast.createPrinter((options) => {
771
912
  union(node) {
772
913
  const { discriminatorPropertyName } = node;
773
914
  const baseTypeName = this.options.typeName;
774
- const items = (0, _kubb_ast_utils.mapSchemaMembers)(node, (member) => {
915
+ const items = kubb_kit.ast.mapSchemaMembers(node, (member) => {
775
916
  const value = discriminatorPropertyName ? getDiscriminatorValue(member, discriminatorPropertyName) : void 0;
776
917
  if (baseTypeName && value !== void 0) return printNested(member, {
777
918
  typeName: `Extract<NonNullable<${baseTypeName}>, { ${JSON.stringify(discriminatorPropertyName)}: ${parseEnumValue(value)} }>`,
@@ -786,11 +927,11 @@ const printerFaker = _kubb_core.ast.createPrinter((options) => {
786
927
  return fakerKeywordMapper.union(items);
787
928
  },
788
929
  intersection(node) {
789
- const items = (0, _kubb_ast_utils.mapSchemaMembers)(node, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
930
+ const items = kubb_kit.ast.mapSchemaMembers(node, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
790
931
  return fakerKeywordMapper.and(items);
791
932
  },
792
933
  array(node) {
793
- const items = (0, _kubb_ast_utils.mapSchemaItems)(node, (member) => printNested(member, {
934
+ const items = kubb_kit.ast.mapSchemaItems(node, (member) => printNested(member, {
794
935
  typeName: this.options.typeName ? `NonNullable<${this.options.typeName}>[number]` : void 0,
795
936
  nestedInObject: true
796
937
  })).map(({ output }) => output).filter((item) => Boolean(item));
@@ -805,16 +946,16 @@ const printerFaker = _kubb_core.ast.createPrinter((options) => {
805
946
  },
806
947
  object(node) {
807
948
  const cyclicSchemas = this.options.cyclicSchemas;
808
- return (0, _kubb_ast_utils.buildObject)((node.properties ?? []).map((property) => {
949
+ return buildObject((node.properties ?? []).map((property) => {
809
950
  const value = printNested(property.schema, {
810
951
  typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
811
952
  nestedInObject: true
812
953
  }) ?? "undefined";
813
- if (cyclicSchemas && (0, _kubb_ast_utils.containsCircularRef)(property.schema, {
954
+ if (cyclicSchemas && kubb_kit.ast.containsCircularRef(property.schema, {
814
955
  circularSchemas: cyclicSchemas,
815
956
  excludeName: this.options.schemaName
816
- })) return `get ${(0, _kubb_ast_utils.objectKey)(property.name)}() { const _value = ${value}; Object.defineProperty(this, ${JSON.stringify(property.name)}, { value: _value, configurable: true, writable: true, enumerable: true }); return _value }`;
817
- return `${(0, _kubb_ast_utils.objectKey)(property.name)}: ${value}`;
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}`;
818
959
  }));
819
960
  },
820
961
  ...options.nodes
@@ -832,9 +973,9 @@ const printerFaker = _kubb_core.ast.createPrinter((options) => {
832
973
  * factory returns a value matching the corresponding TypeScript type from
833
974
  * `@kubb/plugin-ts`.
834
975
  */
835
- const fakerGenerator = (0, _kubb_core.defineGenerator)({
976
+ const fakerGenerator = (0, kubb_kit.defineGenerator)({
836
977
  name: "faker",
837
- renderer: _kubb_renderer_jsx.jsxRenderer,
978
+ renderer: kubb_jsx.jsxRenderer,
838
979
  schema(node, ctx) {
839
980
  const { adapter, config, resolver, root } = ctx;
840
981
  const { output, group, dateParser, regexGenerator, seed, locale, printer } = ctx.options;
@@ -842,25 +983,23 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
842
983
  if (!node.name || !pluginTs) return;
843
984
  const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
844
985
  const schemaName = node.name;
845
- const isEnumSchema = !!_kubb_core.ast.narrowSchema(node, _kubb_core.ast.schemaTypes.enum);
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.resolveEnumKeyName({ name: schemaName }, tsEnumTypeSuffix) : tsResolver.resolveTypeName(schemaName);
989
+ const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.enum.keyName({ name: schemaName }, tsEnumTypeSuffix) : tsResolver.name(schemaName);
849
990
  const meta = {
850
- name: resolver.resolveName(schemaName),
851
- file: resolver.resolveFile({
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.resolveFile({
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,21 +1027,20 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
888
1027
  typeFilePath: meta.typeFile.path
889
1028
  });
890
1029
  const usedImports = filterUsedImports(adapter.getImports(node, (schemaName) => ({
891
- name: resolver.resolveName(schemaName),
892
- path: resolver.resolveFile({
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
899
1037
  }).path
900
1038
  })), fakerText);
901
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
1039
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
902
1040
  baseName: meta.file.baseName,
903
1041
  path: meta.file.path,
904
1042
  meta: meta.file.meta,
905
- banner: resolver.resolveBanner(ctx.meta, {
1043
+ banner: resolver.default.banner(ctx.meta, {
906
1044
  output,
907
1045
  config,
908
1046
  file: {
@@ -910,7 +1048,7 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
910
1048
  baseName: meta.file.baseName
911
1049
  }
912
1050
  }),
913
- footer: resolver.resolveFooter(ctx.meta, {
1051
+ footer: resolver.default.footer(ctx.meta, {
914
1052
  output,
915
1053
  config,
916
1054
  file: {
@@ -919,28 +1057,28 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
919
1057
  }
920
1058
  }),
921
1059
  children: [
922
- /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1060
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
923
1061
  name: locale ? [{
924
1062
  propertyName: localeToFakerImport(locale),
925
1063
  name: "faker"
926
1064
  }] : ["faker"],
927
1065
  path: "@faker-js/faker"
928
1066
  }),
929
- regexGenerator === "randexp" && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1067
+ regexGenerator === "randexp" && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
930
1068
  name: "RandExp",
931
1069
  path: "randexp"
932
1070
  }),
933
- dateParser !== "faker" && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1071
+ dateParser !== "faker" && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
934
1072
  path: dateParser,
935
1073
  name: dateParser
936
1074
  }),
937
- typeReference.importPath && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1075
+ typeReference.importPath && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
938
1076
  isTypeOnly: true,
939
1077
  root: meta.file.path,
940
1078
  path: typeReference.importPath,
941
1079
  name: [meta.typeName]
942
1080
  }),
943
- usedImports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1081
+ usedImports.map((imp) => /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
944
1082
  root: meta.file.path,
945
1083
  path: imp.path,
946
1084
  name: imp.name
@@ -949,7 +1087,7 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
949
1087
  imp.path,
950
1088
  imp.name
951
1089
  ].join("-"))),
952
- /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Faker, {
1090
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Faker, {
953
1091
  name: meta.name,
954
1092
  typeName: typeReference.typeName,
955
1093
  description: node.description,
@@ -967,10 +1105,31 @@ const fakerGenerator = (0, _kubb_core.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 paramEntries = caseParams(node.parameters, "camelcase").map((param) => ({
971
- param,
972
- name: resolveParamNameByLocation(resolver, node, param),
973
- typeName: resolveParamNameByLocation(tsResolver, node, param)
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);
@@ -986,9 +1145,9 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
986
1145
  }];
987
1146
  }
988
1147
  const variants = resolveContentTypeVariants(entries, baseName);
989
- const unionSchema = _kubb_core.ast.factory.createSchema({
1148
+ const unionSchema = kubb_kit.ast.factory.createSchema({
990
1149
  type: "union",
991
- members: variants.map((variant) => _kubb_core.ast.factory.createSchema({
1150
+ members: variants.map((variant) => kubb_kit.ast.factory.createSchema({
992
1151
  type: "ref",
993
1152
  name: variant.name
994
1153
  }))
@@ -1007,36 +1166,34 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
1007
1166
  skipImportNames: variants.map((variant) => variant.name)
1008
1167
  }];
1009
1168
  }
1010
- const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.resolveResponseStatusName(node, response.statusCode), tsResolver.resolveResponseStatusName(node, response.statusCode), response.description));
1011
- const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.resolveDataName(node), tsResolver.resolveDataName(node), node.requestBody?.description, (schema) => ({
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.resolveResponseName(node);
1174
+ const responseName = resolver.response.response(node);
1016
1175
  const localHelperNames = /* @__PURE__ */ new Set([
1017
- ...paramEntries.map((entry) => entry.name),
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.resolveFile({
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.resolveFile({
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_core.defineGenerator)({
1044
1201
  };
1045
1202
  function resolveMockImports(schema) {
1046
1203
  return adapter.getImports(schema, (schemaName) => ({
1047
- name: resolver.resolveName(schemaName),
1048
- path: resolver.resolveFile({
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
@@ -1079,14 +1235,14 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
1079
1235
  filePath: meta.file.path,
1080
1236
  typeFilePath: meta.typeFile.path
1081
1237
  });
1082
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
1083
- typeReference.importPath && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1238
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
1239
+ typeReference.importPath && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1084
1240
  isTypeOnly: true,
1085
1241
  root: meta.file.path,
1086
1242
  path: typeReference.importPath,
1087
1243
  name: [typeName]
1088
1244
  }),
1089
- imports.map((imp) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1245
+ imports.map((imp) => /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1090
1246
  root: meta.file.path,
1091
1247
  path: imp.path,
1092
1248
  name: imp.name
@@ -1095,7 +1251,7 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
1095
1251
  imp.path,
1096
1252
  imp.name
1097
1253
  ].join("-"))),
1098
- /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Faker, {
1254
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Faker, {
1099
1255
  name,
1100
1256
  typeName: typeReference.typeName,
1101
1257
  description,
@@ -1109,11 +1265,11 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
1109
1265
  })
1110
1266
  ] });
1111
1267
  }
1112
- return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
1268
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
1113
1269
  baseName: meta.file.baseName,
1114
1270
  path: meta.file.path,
1115
1271
  meta: meta.file.meta,
1116
- banner: resolver.resolveBanner(ctx.meta, {
1272
+ banner: resolver.default.banner(ctx.meta, {
1117
1273
  output,
1118
1274
  config,
1119
1275
  file: {
@@ -1121,7 +1277,7 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
1121
1277
  baseName: meta.file.baseName
1122
1278
  }
1123
1279
  }),
1124
- footer: resolver.resolveFooter(ctx.meta, {
1280
+ footer: resolver.default.footer(ctx.meta, {
1125
1281
  output,
1126
1282
  config,
1127
1283
  file: {
@@ -1130,26 +1286,22 @@ const fakerGenerator = (0, _kubb_core.defineGenerator)({
1130
1286
  }
1131
1287
  }),
1132
1288
  children: [
1133
- /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1289
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1134
1290
  name: locale ? [{
1135
1291
  propertyName: localeToFakerImport(locale),
1136
1292
  name: "faker"
1137
1293
  }] : ["faker"],
1138
1294
  path: "@faker-js/faker"
1139
1295
  }),
1140
- regexGenerator === "randexp" && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1296
+ regexGenerator === "randexp" && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1141
1297
  name: "RandExp",
1142
1298
  path: "randexp"
1143
1299
  }),
1144
- dateParser !== "faker" && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1300
+ dateParser !== "faker" && /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
1145
1301
  path: dateParser,
1146
1302
  name: dateParser
1147
1303
  }),
1148
- paramEntries.map(({ param, name, typeName }) => renderEntry({
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_core.defineGenerator)({
1167
1319
  renderEntry({
1168
1320
  schema: buildResponseUnionSchema(node, resolver),
1169
1321
  name: responseName,
1170
- typeName: tsResolver.resolveResponseName(node),
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_core.defineGenerator)({
1185
1337
  * ```ts
1186
1338
  * import { resolverFaker } from '@kubb/plugin-faker'
1187
1339
  *
1188
- * resolverFaker.default('list pets', 'function') // 'createListPets'
1340
+ * resolverFaker.name('list pets') // 'createListPets'
1189
1341
  * ```
1190
1342
  */
1191
- const resolverFaker = (0, _kubb_core.defineResolver)(() => {
1192
- return {
1193
- name: "default",
1194
- pluginName: "plugin-faker",
1195
- default(name, type) {
1196
- if (type === "file") return toFilePath(name, (part) => camelCase(part, { prefix: "create" }));
1197
- return ensureValidVarName(camelCase(name, { prefix: "create" }));
1198
- },
1199
- resolveName(name, type) {
1200
- return this.default(name, type);
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
- resolveResponseStatusName(node, statusCode) {
1233
- return this.resolveName(`${node.operationId} Status ${statusCode}`);
1355
+ path(node) {
1356
+ return this.name(`${node.operationId} Path`);
1234
1357
  },
1235
- resolveResponseName(node) {
1236
- return this.resolveName(`${node.operationId} Response`);
1358
+ query(node) {
1359
+ return this.name(`${node.operationId} Query`);
1237
1360
  },
1238
- resolveResponsesName(node) {
1239
- return this.resolveName(`${node.operationId} Responses`);
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
- resolvePathParamsName(node, param) {
1242
- return this.resolveParamName(node, param);
1369
+ body(node) {
1370
+ return this.name(`${node.operationId} Body`);
1243
1371
  },
1244
- resolveQueryParamsName(node, param) {
1245
- return this.resolveParamName(node, param);
1372
+ response(node) {
1373
+ return this.name(`${node.operationId} Response`);
1246
1374
  },
1247
- resolveHeaderParamsName(node, param) {
1248
- return this.resolveParamName(node, param);
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
@@ -1263,7 +1391,7 @@ const pluginFakerName = "plugin-faker";
1263
1391
  *
1264
1392
  * @example
1265
1393
  * ```ts
1266
- * import { defineConfig } from 'kubb'
1394
+ * import { defineConfig } from 'kubb/config'
1267
1395
  * import { pluginTs } from '@kubb/plugin-ts'
1268
1396
  * import { pluginFaker } from '@kubb/plugin-faker'
1269
1397
  *
@@ -1280,7 +1408,7 @@ const pluginFakerName = "plugin-faker";
1280
1408
  * })
1281
1409
  * ```
1282
1410
  */
1283
- const pluginFaker = (0, _kubb_core.definePlugin)((options) => {
1411
+ const pluginFaker = (0, kubb_kit.definePlugin)((options) => {
1284
1412
  const { output = {
1285
1413
  path: "mocks",
1286
1414
  barrel: { type: "named" }
@@ -1303,10 +1431,7 @@ const pluginFaker = (0, _kubb_core.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
  } }