@kubb/plugin-faker 5.0.0-beta.3 → 5.0.0-beta.31

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.
Files changed (37) hide show
  1. package/README.md +26 -5
  2. package/dist/{Faker-CdyPfOPg.d.ts → Faker-BaLJxPyl.d.ts} +2 -2
  3. package/dist/{Faker-fcQEB9i5.js → Faker-DwIc_lta.js} +38 -100
  4. package/dist/Faker-DwIc_lta.js.map +1 -0
  5. package/dist/{Faker-BgleOzVN.cjs → Faker-XuyEQflW.cjs} +37 -123
  6. package/dist/Faker-XuyEQflW.cjs.map +1 -0
  7. package/dist/components.cjs +1 -1
  8. package/dist/components.d.ts +1 -1
  9. package/dist/components.js +1 -1
  10. package/dist/{fakerGenerator-VJEVzLjc.cjs → fakerGenerator-BBr2WsG8.cjs} +236 -60
  11. package/dist/fakerGenerator-BBr2WsG8.cjs.map +1 -0
  12. package/dist/{fakerGenerator-D7daHCh6.js → fakerGenerator-BDNxA7KY.js} +235 -59
  13. package/dist/fakerGenerator-BDNxA7KY.js.map +1 -0
  14. package/dist/fakerGenerator-DSvAJTq3.d.ts +15 -0
  15. package/dist/generators.cjs +1 -1
  16. package/dist/generators.d.ts +1 -1
  17. package/dist/generators.js +1 -1
  18. package/dist/index.cjs +213 -42
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +33 -12
  21. package/dist/index.js +214 -43
  22. package/dist/index.js.map +1 -1
  23. package/dist/{printerFaker-CJiwzoto.d.ts → printerFaker-Bhwq62d1.d.ts} +63 -26
  24. package/extension.yaml +817 -0
  25. package/package.json +9 -13
  26. package/src/components/Faker.tsx +50 -64
  27. package/src/generators/fakerGenerator.tsx +107 -67
  28. package/src/plugin.ts +25 -21
  29. package/src/printers/printerFaker.ts +80 -16
  30. package/src/resolvers/resolverFaker.ts +29 -37
  31. package/src/types.ts +36 -23
  32. package/src/utils.ts +6 -105
  33. package/dist/Faker-BgleOzVN.cjs.map +0 -1
  34. package/dist/Faker-fcQEB9i5.js.map +0 -1
  35. package/dist/fakerGenerator-C3Ho3BaI.d.ts +0 -9
  36. package/dist/fakerGenerator-D7daHCh6.js.map +0 -1
  37. package/dist/fakerGenerator-VJEVzLjc.cjs.map +0 -1
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import "./chunk--u3MIqq1.js";
2
- import { t as Faker } from "./Faker-fcQEB9i5.js";
3
- import { n as printerFaker, t as fakerGenerator } from "./fakerGenerator-D7daHCh6.js";
2
+ import { n as printerFaker, t as fakerGenerator } from "./fakerGenerator-BDNxA7KY.js";
3
+ import { t as Faker } from "./Faker-DwIc_lta.js";
4
4
  import path from "node:path";
5
- import { PluginDriver, definePlugin, defineResolver } from "@kubb/core";
5
+ import { KubbDriver, definePlugin, defineResolver } from "@kubb/core";
6
6
  import { pluginTsName } from "@kubb/plugin-ts";
7
7
  import { createHash } from "node:crypto";
8
8
  //#region ../../internals/utils/src/casing.ts
@@ -48,42 +48,196 @@ function camelCase(text, { isFile, prefix = "", suffix = "" } = {}) {
48
48
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
49
49
  }
50
50
  //#endregion
51
- //#region src/resolvers/resolverFaker.ts
52
- function isValidStrictIdentifier(name) {
53
- try {
54
- new Function(`"use strict"; const ${name} = 1;`);
55
- } catch {
56
- return false;
57
- }
58
- return true;
51
+ //#region ../../internals/utils/src/reserved.ts
52
+ /**
53
+ * JavaScript and Java reserved words.
54
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
55
+ */
56
+ const reservedWords = new Set([
57
+ "abstract",
58
+ "arguments",
59
+ "boolean",
60
+ "break",
61
+ "byte",
62
+ "case",
63
+ "catch",
64
+ "char",
65
+ "class",
66
+ "const",
67
+ "continue",
68
+ "debugger",
69
+ "default",
70
+ "delete",
71
+ "do",
72
+ "double",
73
+ "else",
74
+ "enum",
75
+ "eval",
76
+ "export",
77
+ "extends",
78
+ "false",
79
+ "final",
80
+ "finally",
81
+ "float",
82
+ "for",
83
+ "function",
84
+ "goto",
85
+ "if",
86
+ "implements",
87
+ "import",
88
+ "in",
89
+ "instanceof",
90
+ "int",
91
+ "interface",
92
+ "let",
93
+ "long",
94
+ "native",
95
+ "new",
96
+ "null",
97
+ "package",
98
+ "private",
99
+ "protected",
100
+ "public",
101
+ "return",
102
+ "short",
103
+ "static",
104
+ "super",
105
+ "switch",
106
+ "synchronized",
107
+ "this",
108
+ "throw",
109
+ "throws",
110
+ "transient",
111
+ "true",
112
+ "try",
113
+ "typeof",
114
+ "var",
115
+ "void",
116
+ "volatile",
117
+ "while",
118
+ "with",
119
+ "yield",
120
+ "Array",
121
+ "Date",
122
+ "hasOwnProperty",
123
+ "Infinity",
124
+ "isFinite",
125
+ "isNaN",
126
+ "isPrototypeOf",
127
+ "length",
128
+ "Math",
129
+ "name",
130
+ "NaN",
131
+ "Number",
132
+ "Object",
133
+ "prototype",
134
+ "String",
135
+ "toString",
136
+ "undefined",
137
+ "valueOf"
138
+ ]);
139
+ /**
140
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * isValidVarName('status') // true
145
+ * isValidVarName('class') // false (reserved word)
146
+ * isValidVarName('42foo') // false (starts with digit)
147
+ * ```
148
+ */
149
+ function isValidVarName(name) {
150
+ if (!name || reservedWords.has(name)) return false;
151
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
59
152
  }
60
153
  /**
61
- * Naming convention resolver for Faker plugin.
154
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
155
+ * otherwise prefixes it with `_` so the result is a valid identifier.
62
156
  *
63
- * Provides default naming helpers using camelCase. Prefixes invalid identifiers with `_`.
157
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
158
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
159
+ * variable, type, or function names.
64
160
  *
65
161
  * @example
66
- * `resolverFaker.default('list pets', 'function') // → 'listPets'`
162
+ * ```ts
163
+ * ensureValidVarName('409') // '_409'
164
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
165
+ * ensureValidVarName('Pet') // 'Pet'
166
+ * ensureValidVarName('class') // '_class'
167
+ * ```
67
168
  */
68
- const resolverFaker = defineResolver((ctx) => {
169
+ function ensureValidVarName(name) {
170
+ if (!name || isValidVarName(name)) return name;
171
+ return `_${name}`;
172
+ }
173
+ //#endregion
174
+ //#region ../../internals/shared/src/group.ts
175
+ /**
176
+ * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
177
+ * shared default naming so every plugin groups output consistently:
178
+ *
179
+ * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
180
+ * - other groups use `${camelCase(group)}${suffix}` (e.g. `petController`).
181
+ *
182
+ * Returns `null` when grouping is disabled, matching the per-plugin convention.
183
+ *
184
+ * @param group - The user-supplied group option, or `undefined` to disable grouping.
185
+ * @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
186
+ * @param options.honorName - When `true`, a user-provided `group.name` overrides the default namer.
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * createGroupConfig(group, { suffix: 'Controller' }) // plugin-ts, plugin-zod
191
+ * createGroupConfig(group, { suffix: 'Controller', honorName: true }) // plugin-faker, plugin-client, …
192
+ * createGroupConfig(group, { suffix: 'Requests', honorName: true }) // plugin-cypress, plugin-mcp
193
+ * ```
194
+ */
195
+ function createGroupConfig(group, options) {
196
+ if (!group) return null;
197
+ const defaultName = (ctx) => {
198
+ if (group.type === "path") return `${ctx.group.split("/")[1]}`;
199
+ return `${camelCase(ctx.group)}${options.suffix}`;
200
+ };
201
+ return {
202
+ ...group,
203
+ name: options.honorName && group.name ? group.name : defaultName
204
+ };
205
+ }
206
+ //#endregion
207
+ //#region src/resolvers/resolverFaker.ts
208
+ /**
209
+ * Default resolver used by `@kubb/plugin-faker`. Decides the names and file
210
+ * paths for every generated mock factory. Functions and files are prefixed
211
+ * with `create` so `Pet` becomes `createPet`.
212
+ *
213
+ * @example Resolve a factory name
214
+ * ```ts
215
+ * import { resolverFaker } from '@kubb/plugin-faker'
216
+ *
217
+ * resolverFaker.default('list pets', 'function') // 'createListPets'
218
+ * ```
219
+ */
220
+ const resolverFaker = defineResolver(() => {
69
221
  return {
70
222
  name: "default",
71
223
  pluginName: "plugin-faker",
72
224
  default(name, type) {
73
- const resolvedName = camelCase(name, { isFile: type === "file" });
74
- if (type === "file" || isValidStrictIdentifier(resolvedName)) return resolvedName;
75
- return `_${resolvedName}`;
225
+ const resolvedName = camelCase(name, {
226
+ isFile: type === "file",
227
+ prefix: "create"
228
+ });
229
+ return type === "file" ? resolvedName : ensureValidVarName(resolvedName);
76
230
  },
77
231
  resolveName(name, type) {
78
- return ctx.default(name, type);
232
+ return this.default(name, type);
79
233
  },
80
234
  resolvePathName(name, type) {
81
- return ctx.default(name, type);
235
+ return this.default(name, type);
82
236
  },
83
237
  resolveFile({ name, extname, tag, path: groupPath }, context) {
84
- const pathMode = PluginDriver.getMode(path.resolve(context.root, context.output.path));
85
- const baseName = `${pathMode === "single" ? "" : ctx.resolveName(name, "file")}${extname}`;
86
- const filePath = ctx.resolvePath({
238
+ const pathMode = KubbDriver.getMode(path.resolve(context.root, context.output.path));
239
+ const baseName = `${pathMode === "single" ? "" : this.resolveName(name, "file")}${extname}`;
240
+ const filePath = this.resolvePath({
87
241
  baseName,
88
242
  pathMode,
89
243
  tag,
@@ -96,61 +250,78 @@ const resolverFaker = defineResolver((ctx) => {
96
250
  path: filePath,
97
251
  baseName,
98
252
  extname,
99
- meta: { pluginName: ctx.pluginName },
253
+ meta: { pluginName: this.pluginName },
100
254
  sources: [],
101
255
  imports: [],
102
256
  exports: []
103
257
  };
104
258
  },
105
259
  resolveParamName(node, param) {
106
- return ctx.resolveName(`${node.operationId} ${param.in} ${param.name}`);
260
+ return this.resolveName(`${node.operationId} ${param.in} ${param.name}`);
107
261
  },
108
262
  resolveDataName(node) {
109
- return ctx.resolveName(`${node.operationId} Data`);
263
+ return this.resolveName(`${node.operationId} Data`);
110
264
  },
111
265
  resolveResponseStatusName(node, statusCode) {
112
- return ctx.resolveName(`${node.operationId} Status ${statusCode}`);
266
+ return this.resolveName(`${node.operationId} Status ${statusCode}`);
113
267
  },
114
268
  resolveResponseName(node) {
115
- return ctx.resolveName(`${node.operationId} Response`);
269
+ return this.resolveName(`${node.operationId} Response`);
270
+ },
271
+ resolveResponsesName(node) {
272
+ return this.resolveName(`${node.operationId} Responses`);
116
273
  },
117
274
  resolvePathParamsName(node, param) {
118
- return ctx.resolveParamName(node, param);
275
+ return this.resolveParamName(node, param);
119
276
  },
120
277
  resolveQueryParamsName(node, param) {
121
- return ctx.resolveParamName(node, param);
278
+ return this.resolveParamName(node, param);
122
279
  },
123
280
  resolveHeaderParamsName(node, param) {
124
- return ctx.resolveParamName(node, param);
281
+ return this.resolveParamName(node, param);
125
282
  }
126
283
  };
127
284
  });
128
285
  //#endregion
129
286
  //#region src/plugin.ts
130
287
  /**
131
- * Canonical plugin name for `@kubb/plugin-faker`, used in driver lookups and warnings.
288
+ * Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
289
+ * cross-plugin dependency references.
132
290
  */
133
291
  const pluginFakerName = "plugin-faker";
134
292
  /**
135
- * Generates Faker mock data factories from OpenAPI/AST specification.
136
- *
137
- * Creates randomized test data and mock helpers from schema definitions.
293
+ * Generates one mock-data factory per OpenAPI schema using Faker.js. Call
294
+ * `createPet()` to get a realistic `Pet` object. Useful for tests, Storybook,
295
+ * and local development without a running backend.
138
296
  *
139
297
  * @example
140
- * `import pluginFaker from '@kubb/plugin-faker'; export default defineConfig({ plugins: [pluginFaker({ output: { path: 'mocks' } })], })`
298
+ * ```ts
299
+ * import { defineConfig } from 'kubb'
300
+ * import { pluginTs } from '@kubb/plugin-ts'
301
+ * import { pluginFaker } from '@kubb/plugin-faker'
302
+ *
303
+ * export default defineConfig({
304
+ * input: { path: './petStore.yaml' },
305
+ * output: { path: './src/gen' },
306
+ * plugins: [
307
+ * pluginTs(),
308
+ * pluginFaker({
309
+ * output: { path: './mocks' },
310
+ * seed: [100],
311
+ * }),
312
+ * ],
313
+ * })
314
+ * ```
141
315
  */
142
316
  const pluginFaker = definePlugin((options) => {
143
317
  const { output = {
144
318
  path: "mocks",
145
319
  barrelType: "named"
146
320
  }, seed, locale, group, exclude = [], include, override = [], mapper = {}, dateParser = "faker", generators: userGenerators = [], regexGenerator = "faker", paramsCasing, printer, resolver: userResolver, transformer: userTransformer } = options;
147
- const groupConfig = group ? {
148
- ...group,
149
- name: group.name ? group.name : (ctx) => {
150
- if (group.type === "path") return `${ctx.group.split("/")[1]}`;
151
- return `${camelCase(ctx.group)}Controller`;
152
- }
153
- } : void 0;
321
+ const groupConfig = createGroupConfig(group, {
322
+ suffix: "Controller",
323
+ honorName: true
324
+ });
154
325
  return {
155
326
  name: pluginFakerName,
156
327
  options,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../internals/utils/src/casing.ts","../src/resolvers/resolverFaker.ts","../src/plugin.ts"],"sourcesContent":["type Options = {\n /**\n * When `true`, dot-separated segments are split on `.` and joined with `/` after casing.\n */\n isFile?: boolean\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n const normalized = text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n\n const words = normalized.split(/[\\s\\-_./\\\\:]+/).filter(Boolean)\n\n return words\n .map((word, i) => {\n const allUpper = word.length > 1 && word === word.toUpperCase()\n if (allUpper) return word\n if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1)\n return word.charAt(0).toUpperCase() + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Splits `text` on `.` and applies `transformPart` to each segment.\n * The last segment receives `isLast = true`, all earlier segments receive `false`.\n * Segments are joined with `/` to form a file path.\n *\n * Only splits on dots followed by a letter so that version numbers\n * embedded in operationIds (e.g. `v2025.0`) are kept intact.\n */\nfunction applyToFileParts(text: string, transformPart: (part: string, isLast: boolean) => string): string {\n const parts = text.split(/\\.(?=[a-zA-Z])/)\n return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join('/')\n}\n\n/**\n * Converts `text` to camelCase.\n * When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.\n *\n * @example\n * camelCase('hello-world') // 'helloWorld'\n * camelCase('pet.petId', { isFile: true }) // 'pet/petId'\n */\nexport function camelCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string {\n if (isFile) {\n return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? { prefix, suffix } : {}))\n }\n\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n * When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.\n *\n * @example\n * pascalCase('hello-world') // 'HelloWorld'\n * pascalCase('pet.petId', { isFile: true }) // 'pet/PetId'\n */\nexport function pascalCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string {\n if (isFile) {\n return applyToFileParts(text, (part, isLast) => (isLast ? pascalCase(part, { prefix, suffix }) : camelCase(part)))\n }\n\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example\n * snakeCase('helloWorld') // 'hello_world'\n * snakeCase('Hello-World') // 'hello_world'\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Omit<Options, 'isFile'> = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example\n * screamingSnakeCase('helloWorld') // 'HELLO_WORLD'\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Omit<Options, 'isFile'> = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","import { createHash } from 'node:crypto'\nimport path from 'node:path'\nimport { camelCase } from '@internals/utils'\nimport { defineResolver, PluginDriver } from '@kubb/core'\nimport type { PluginFaker } from '../types.ts'\n\nfunction isValidStrictIdentifier(name: string): boolean {\n try {\n new Function(`\"use strict\"; const ${name} = 1;`)\n } catch {\n return false\n }\n\n return true\n}\n\n/**\n * Naming convention resolver for Faker plugin.\n *\n * Provides default naming helpers using camelCase. Prefixes invalid identifiers with `_`.\n *\n * @example\n * `resolverFaker.default('list pets', 'function') // → 'listPets'`\n */\nexport const resolverFaker = defineResolver<PluginFaker>((ctx) => {\n return {\n name: 'default',\n pluginName: 'plugin-faker',\n default(name, type) {\n const resolvedName = camelCase(name, { isFile: type === 'file' })\n\n if (type === 'file' || isValidStrictIdentifier(resolvedName)) {\n return resolvedName\n }\n\n return `_${resolvedName}`\n },\n resolveName(name, type) {\n return ctx.default(name, type)\n },\n resolvePathName(name, type) {\n return ctx.default(name, type)\n },\n resolveFile({ name, extname, tag, path: groupPath }, context) {\n const pathMode = PluginDriver.getMode(path.resolve(context.root, context.output.path))\n const baseName = `${pathMode === 'single' ? '' : ctx.resolveName(name, 'file')}${extname}` as `${string}.${string}`\n const filePath = ctx.resolvePath(\n {\n baseName,\n pathMode,\n tag,\n path: groupPath,\n },\n context,\n )\n\n return {\n kind: 'File',\n id: createHash('sha256').update(filePath).digest('hex'),\n name: path.basename(filePath, extname),\n path: filePath,\n baseName,\n extname,\n meta: { pluginName: ctx.pluginName },\n sources: [],\n imports: [],\n exports: [],\n }\n },\n resolveParamName(node, param) {\n return ctx.resolveName(`${node.operationId} ${param.in} ${param.name}`)\n },\n resolveDataName(node) {\n return ctx.resolveName(`${node.operationId} Data`)\n },\n resolveResponseStatusName(node, statusCode) {\n return ctx.resolveName(`${node.operationId} Status ${statusCode}`)\n },\n resolveResponseName(node) {\n return ctx.resolveName(`${node.operationId} Response`)\n },\n resolvePathParamsName(node, param) {\n return ctx.resolveParamName(node, param)\n },\n resolveQueryParamsName(node, param) {\n return ctx.resolveParamName(node, param)\n },\n resolveHeaderParamsName(node, param) {\n return ctx.resolveParamName(node, param)\n },\n }\n})\n","import { camelCase } from '@internals/utils'\nimport { definePlugin, type Group } from '@kubb/core'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { fakerGenerator } from './generators/fakerGenerator.tsx'\nimport { resolverFaker } from './resolvers/resolverFaker.ts'\nimport type { PluginFaker } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-faker`, used in driver lookups and warnings.\n */\nexport const pluginFakerName = 'plugin-faker' satisfies PluginFaker['name']\n\n/**\n * Generates Faker mock data factories from OpenAPI/AST specification.\n *\n * Creates randomized test data and mock helpers from schema definitions.\n *\n * @example\n * `import pluginFaker from '@kubb/plugin-faker'; export default defineConfig({ plugins: [pluginFaker({ output: { path: 'mocks' } })], })`\n */\nexport const pluginFaker = definePlugin<PluginFaker>((options) => {\n const {\n output = { path: 'mocks', barrelType: 'named' },\n seed,\n locale,\n group,\n exclude = [],\n include,\n override = [],\n mapper = {},\n dateParser = 'faker',\n generators: userGenerators = [],\n regexGenerator = 'faker',\n paramsCasing,\n printer,\n resolver: userResolver,\n transformer: userTransformer,\n } = options\n\n const groupConfig = group\n ? ({\n ...group,\n name: group.name\n ? group.name\n : (ctx: { group: string }) => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return `${camelCase(ctx.group)}Controller`\n },\n } satisfies Group)\n : undefined\n\n return {\n name: pluginFakerName,\n options,\n dependencies: [pluginTsName],\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n ctx.setOptions({\n output,\n seed,\n locale,\n exclude,\n include,\n override,\n group: groupConfig,\n mapper,\n dateParser,\n regexGenerator,\n paramsCasing,\n printer,\n })\n ctx.setResolver(userResolver ? { ...resolverFaker, ...userResolver } : resolverFaker)\n if (userTransformer) {\n ctx.setTransformer(userTransformer)\n }\n ctx.addGenerator(fakerGenerator)\n for (const generator of userGenerators) {\n ctx.addGenerator(generator)\n }\n },\n },\n }\n})\n\nexport default pluginFaker\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../internals/utils/src/casing.ts","../../../internals/utils/src/reserved.ts","../../../internals/shared/src/group.ts","../src/resolvers/resolverFaker.ts","../src/plugin.ts"],"sourcesContent":["type Options = {\n /**\n * When `true`, dot-separated segments are split on `.` and joined with `/` after casing.\n */\n isFile?: boolean\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n const normalized = text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n\n const words = normalized.split(/[\\s\\-_./\\\\:]+/).filter(Boolean)\n\n return words\n .map((word, i) => {\n const allUpper = word.length > 1 && word === word.toUpperCase()\n if (allUpper) return word\n if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1)\n return word.charAt(0).toUpperCase() + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Splits `text` on `.` and applies `transformPart` to each segment.\n * The last segment receives `isLast = true`, all earlier segments receive `false`.\n * Segments are joined with `/` to form a file path.\n *\n * Only splits on dots followed by a letter so that version numbers\n * embedded in operationIds (e.g. `v2025.0`) are kept intact.\n */\nfunction applyToFileParts(text: string, transformPart: (part: string, isLast: boolean) => string): string {\n const parts = text.split(/\\.(?=[a-zA-Z])/)\n return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join('/')\n}\n\n/**\n * Converts `text` to camelCase.\n * When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.\n *\n * @example\n * camelCase('hello-world') // 'helloWorld'\n * camelCase('pet.petId', { isFile: true }) // 'pet/petId'\n */\nexport function camelCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string {\n if (isFile) {\n return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? { prefix, suffix } : {}))\n }\n\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n * When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.\n *\n * @example\n * pascalCase('hello-world') // 'HelloWorld'\n * pascalCase('pet.petId', { isFile: true }) // 'pet/PetId'\n */\nexport function pascalCase(text: string, { isFile, prefix = '', suffix = '' }: Options = {}): string {\n if (isFile) {\n return applyToFileParts(text, (part, isLast) => (isLast ? pascalCase(part, { prefix, suffix }) : camelCase(part)))\n }\n\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example\n * snakeCase('helloWorld') // 'hello_world'\n * snakeCase('Hello-World') // 'hello_world'\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Omit<Options, 'isFile'> = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example\n * screamingSnakeCase('helloWorld') // 'HELLO_WORLD'\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Omit<Options, 'isFile'> = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","/**\n * JavaScript and Java reserved words.\n * @link https://github.com/jonschlinkert/reserved/blob/master/index.js\n */\nconst reservedWords = new Set([\n 'abstract',\n 'arguments',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n 'Array',\n 'Date',\n 'hasOwnProperty',\n 'Infinity',\n 'isFinite',\n 'isNaN',\n 'isPrototypeOf',\n 'length',\n 'Math',\n 'name',\n 'NaN',\n 'Number',\n 'Object',\n 'prototype',\n 'String',\n 'toString',\n 'undefined',\n 'valueOf',\n] as const)\n\n/**\n * Returns `true` when `name` is a syntactically valid JavaScript variable name.\n *\n * @example\n * ```ts\n * isValidVarName('status') // true\n * isValidVarName('class') // false (reserved word)\n * isValidVarName('42foo') // false (starts with digit)\n * ```\n */\nexport function isValidVarName(name: string): boolean {\n if (!name || reservedWords.has(name as 'valueOf')) {\n return false\n }\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)\n}\n\n/**\n * Returns `name` when it's a syntactically valid JavaScript variable name,\n * otherwise prefixes it with `_` so the result is a valid identifier.\n *\n * Useful for sanitizing OpenAPI schema names or operation IDs that start with\n * a digit (e.g. `409`, `504AccountCancel`) before using them as exported\n * variable, type, or function names.\n *\n * @example\n * ```ts\n * ensureValidVarName('409') // '_409'\n * ensureValidVarName('504AccountCancel') // '_504AccountCancel'\n * ensureValidVarName('Pet') // 'Pet'\n * ensureValidVarName('class') // '_class'\n * ```\n */\nexport function ensureValidVarName(name: string): string {\n if (!name || isValidVarName(name)) {\n return name\n }\n return `_${name}`\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from '@kubb/core'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use `${camelCase(group)}${suffix}` (e.g. `petController`).\n *\n * Returns `null` when grouping is disabled, matching the per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n * @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.\n * @param options.honorName - When `true`, a user-provided `group.name` overrides the default namer.\n *\n * @example\n * ```ts\n * createGroupConfig(group, { suffix: 'Controller' }) // plugin-ts, plugin-zod\n * createGroupConfig(group, { suffix: 'Controller', honorName: true }) // plugin-faker, plugin-client, …\n * createGroupConfig(group, { suffix: 'Requests', honorName: true }) // plugin-cypress, plugin-mcp\n * ```\n */\nexport function createGroupConfig(group: Group | undefined, options: { suffix: string; honorName?: boolean }): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return `${camelCase(ctx.group)}${options.suffix}`\n }\n\n return {\n ...group,\n name: options.honorName && group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { createHash } from 'node:crypto'\nimport path from 'node:path'\nimport { camelCase, ensureValidVarName } from '@internals/utils'\nimport { defineResolver, KubbDriver } from '@kubb/core'\nimport type { PluginFaker } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-faker`. Decides the names and file\n * paths for every generated mock factory. Functions and files are prefixed\n * with `create` so `Pet` becomes `createPet`.\n *\n * @example Resolve a factory name\n * ```ts\n * import { resolverFaker } from '@kubb/plugin-faker'\n *\n * resolverFaker.default('list pets', 'function') // 'createListPets'\n * ```\n */\nexport const resolverFaker = defineResolver<PluginFaker>(() => {\n return {\n name: 'default',\n pluginName: 'plugin-faker',\n default(name, type) {\n const resolvedName = camelCase(name, { isFile: type === 'file', prefix: 'create' })\n return type === 'file' ? resolvedName : ensureValidVarName(resolvedName)\n },\n resolveName(name, type) {\n return this.default(name, type)\n },\n resolvePathName(name, type) {\n return this.default(name, type)\n },\n resolveFile({ name, extname, tag, path: groupPath }, context) {\n const pathMode = KubbDriver.getMode(path.resolve(context.root, context.output.path))\n const baseName = `${pathMode === 'single' ? '' : this.resolveName(name, 'file')}${extname}` as `${string}.${string}`\n const filePath = this.resolvePath(\n {\n baseName,\n pathMode,\n tag,\n path: groupPath,\n },\n context,\n )\n\n return {\n kind: 'File',\n id: createHash('sha256').update(filePath).digest('hex'),\n name: path.basename(filePath, extname),\n path: filePath,\n baseName,\n extname,\n meta: { pluginName: this.pluginName },\n sources: [],\n imports: [],\n exports: [],\n }\n },\n resolveParamName(node, param) {\n return this.resolveName(`${node.operationId} ${param.in} ${param.name}`)\n },\n resolveDataName(node) {\n return this.resolveName(`${node.operationId} Data`)\n },\n resolveResponseStatusName(node, statusCode) {\n return this.resolveName(`${node.operationId} Status ${statusCode}`)\n },\n resolveResponseName(node) {\n return this.resolveName(`${node.operationId} Response`)\n },\n resolveResponsesName(node) {\n return this.resolveName(`${node.operationId} Responses`)\n },\n resolvePathParamsName(node, param) {\n return this.resolveParamName(node, param)\n },\n resolveQueryParamsName(node, param) {\n return this.resolveParamName(node, param)\n },\n resolveHeaderParamsName(node, param) {\n return this.resolveParamName(node, param)\n },\n }\n})\n","import { createGroupConfig } from '@internals/shared'\nimport { definePlugin } from '@kubb/core'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { fakerGenerator } from './generators/fakerGenerator.tsx'\nimport { resolverFaker } from './resolvers/resolverFaker.ts'\nimport type { PluginFaker } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginFakerName = 'plugin-faker' satisfies PluginFaker['name']\n\n/**\n * Generates one mock-data factory per OpenAPI schema using Faker.js. Call\n * `createPet()` to get a realistic `Pet` object. Useful for tests, Storybook,\n * and local development without a running backend.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginFaker } from '@kubb/plugin-faker'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginFaker({\n * output: { path: './mocks' },\n * seed: [100],\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginFaker = definePlugin<PluginFaker>((options) => {\n const {\n output = { path: 'mocks', barrelType: 'named' },\n seed,\n locale,\n group,\n exclude = [],\n include,\n override = [],\n mapper = {},\n dateParser = 'faker',\n generators: userGenerators = [],\n regexGenerator = 'faker',\n paramsCasing,\n printer,\n resolver: userResolver,\n transformer: userTransformer,\n } = options\n\n const groupConfig = createGroupConfig(group, { suffix: 'Controller', honorName: true })\n\n return {\n name: pluginFakerName,\n options,\n dependencies: [pluginTsName],\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n ctx.setOptions({\n output,\n seed,\n locale,\n exclude,\n include,\n override,\n group: groupConfig,\n mapper,\n dateParser,\n regexGenerator,\n paramsCasing,\n printer,\n })\n ctx.setResolver(userResolver ? { ...resolverFaker, ...userResolver } : resolverFaker)\n if (userTransformer) {\n ctx.setTransformer(userTransformer)\n }\n ctx.addGenerator(fakerGenerator)\n for (const generator of userGenerators) {\n ctx.addGenerator(generator)\n }\n },\n },\n }\n})\n\nexport default pluginFaker\n"],"mappings":"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"}
@@ -41,6 +41,13 @@ type ResolverFaker = Resolver & ast.OperationParamsResolver & {
41
41
  * `resolver.resolveResponseName(node) // -> 'listPetsResponse'`
42
42
  */
43
43
  resolveResponseName(this: ResolverFaker, node: ast.OperationNode): string;
44
+ /**
45
+ * Resolves the faker function name for the response collection.
46
+ *
47
+ * @example Responses collection names
48
+ * `resolver.resolveResponsesName(node) // -> 'listPetsResponses'`
49
+ */
50
+ resolveResponsesName(this: ResolverFaker, node: ast.OperationNode): string;
44
51
  /**
45
52
  * Resolves the faker function name for path parameters.
46
53
  *
@@ -65,80 +72,86 @@ type ResolverFaker = Resolver & ast.OperationParamsResolver & {
65
72
  };
66
73
  type Options = {
67
74
  /**
68
- * Specify the export location for the files and define the behavior of the output.
69
- * @default { path: 'mocks', barrelType: 'named' }
75
+ * Where the generated mock factories are written and how they are exported.
76
+ *
77
+ * @default { path: 'mocks', barrel: { type: 'named' } }
70
78
  */
71
79
  output?: Output;
72
80
  /**
73
- * Group the Faker mocks based on the provided name.
81
+ * Split generated files into subfolders based on the operation's tag.
74
82
  */
75
83
  group?: Group;
76
84
  /**
77
- * Tags, operations, or paths to exclude from generation.
85
+ * Skip operations matching at least one entry in the list.
78
86
  */
79
87
  exclude?: Array<Exclude>;
80
88
  /**
81
- * Tags, operations, or paths to include in generation.
89
+ * Restrict generation to operations matching at least one entry in the list.
82
90
  */
83
91
  include?: Array<Include>;
84
92
  /**
85
- * Override options for specific tags, operations, or paths.
93
+ * Apply a different options object to operations matching a pattern.
86
94
  */
87
95
  override?: Array<Override<ResolvedOptions>>;
88
96
  /**
89
- * Parser to use when formatting date/time values as strings.
97
+ * Library used to format string-represented date, time, and datetime fields.
98
+ * Any library exporting a default function works; Kubb adds the import for you.
90
99
  *
91
100
  * @default 'faker'
92
101
  */
93
102
  dateParser?: 'faker' | 'dayjs' | 'moment' | (string & {});
94
103
  /**
95
- * Generator to use for RegExp patterns.
104
+ * Library used to generate strings that satisfy a regex `pattern` keyword.
105
+ * - `'faker'` uses `faker.helpers.fromRegExp`. No extra dependency.
106
+ * - `'randexp'` uses the `randexp` package. Supports a wider regex grammar.
96
107
  *
97
108
  * @default 'faker'
98
109
  */
99
110
  regexGenerator?: 'faker' | 'randexp';
100
111
  /**
101
- * Provide per-property faker expressions keyed by property name.
112
+ * Map a schema name to a custom Faker expression. Use this when the schema name
113
+ * does not give Faker enough context (`'email'`, `'avatarUrl'`, `'phoneNumber'`).
102
114
  */
103
115
  mapper?: Record<string, string>;
104
116
  /**
105
- * Locale for generating mock data.
106
- * Imports the matching localized `@faker-js/faker` instance so names, addresses,
107
- * and phone numbers reflect the target region.
117
+ * Faker locale code. Switches the named import to `fakerXX` from `@faker-js/faker`
118
+ * so names, addresses, and phone numbers reflect the target region.
108
119
  *
109
120
  * @default 'en'
110
- *
111
121
  * @example German
112
122
  * `locale: 'de'`
113
- *
114
123
  * @example Austrian German
115
124
  * `locale: 'de_AT'`
116
- *
117
125
  * @see https://fakerjs.dev/api/localization.html
118
126
  */
119
127
  locale?: string;
120
128
  /**
121
- * Seed faker for deterministic output.
129
+ * Value passed to `faker.seed(...)`. Set this for deterministic mock output,
130
+ * which is useful for snapshot tests.
122
131
  */
123
- seed?: number | number[];
132
+ seed?: number | Array<number>;
124
133
  /**
125
- * Apply casing to parameter names to match your configuration.
134
+ * Rename properties inside path/query/header mocks. Body mocks are unaffected.
135
+ *
136
+ * @note Must match the value of `paramsCasing` on `@kubb/plugin-ts`.
126
137
  */
127
138
  paramsCasing?: 'camelcase';
128
139
  /**
129
- * Additional generators alongside the default generators.
140
+ * Custom generators that run alongside the built-in Faker generators.
130
141
  */
131
142
  generators?: Array<Generator<PluginFaker>>;
132
143
  /**
133
- * Override naming conventions for function names and types.
144
+ * Override the naming of generated factory helpers. Common use: append `Mock` or
145
+ * `Factory` so helpers do not clash with imported types.
134
146
  */
135
147
  resolver?: Partial<ResolverFaker> & ThisType<ResolverFaker>;
136
148
  /**
137
- * AST visitor to transform generated nodes.
149
+ * AST visitor applied to schema and operation nodes before printing.
138
150
  */
139
151
  transformer?: ast.Visitor;
140
152
  /**
141
- * Override individual faker printer node handlers.
153
+ * Replace the Faker handler for a specific schema type (`'integer'`, `'date'`, ...).
154
+ * Each handler returns the Faker expression as a string.
142
155
  */
143
156
  printer?: {
144
157
  nodes?: PrinterFakerNodes;
@@ -146,7 +159,7 @@ type Options = {
146
159
  };
147
160
  type ResolvedOptions = {
148
161
  output: Output;
149
- group: Group | undefined;
162
+ group: Group | null;
150
163
  exclude: NonNullable<Options['exclude']>;
151
164
  include: Options['include'];
152
165
  override: NonNullable<Options['override']>;
@@ -169,11 +182,29 @@ declare global {
169
182
  //#endregion
170
183
  //#region src/printers/printerFaker.d.ts
171
184
  /**
172
- * Partial printer nodes for Faker generation, mapping schema types to output strings.
185
+ * Partial map of node-type overrides for the Faker printer. Each key is a
186
+ * `SchemaType` (`'string'`, `'date'`, ...) and each handler returns the
187
+ * Faker expression for that schema as a string. Use `this.transform` to
188
+ * recurse into nested schema nodes and `this.options` to read printer options.
189
+ *
190
+ * @example Override the integer handler
191
+ * ```ts
192
+ * pluginFaker({
193
+ * printer: {
194
+ * nodes: {
195
+ * integer() {
196
+ * return 'faker.number.float()'
197
+ * },
198
+ * },
199
+ * },
200
+ * })
201
+ * ```
173
202
  */
174
203
  type PrinterFakerNodes = ast.PrinterPartial<string, PrinterFakerOptions>;
175
204
  /**
176
- * Configuration options for the Faker printer, including resolvers, mappers, and cyclic schema tracking.
205
+ * Options passed to the Faker printer at instantiation: the parser library
206
+ * for date strings, the regex generator, the user-supplied schema-name
207
+ * mapper, and the resolver used to compute identifiers.
177
208
  */
178
209
  type PrinterFakerOptions = {
179
210
  dateParser?: PluginFaker['resolvedOptions']['dateParser'];
@@ -183,6 +214,12 @@ type PrinterFakerOptions = {
183
214
  typeName?: string;
184
215
  schemaName?: string;
185
216
  nestedInObject?: boolean;
217
+ /**
218
+ * Set while printing the members of a union (`oneOf`). Object properties then index their
219
+ * type as `(NonNullable<T> & Record<K, unknown>)[K]` instead of `NonNullable<T>[K]`, so a key
220
+ * carried by only some branches stays valid (a plain index would be a TS2339).
221
+ */
222
+ nestedInUnion?: boolean;
186
223
  nodes?: PrinterFakerNodes;
187
224
  /**
188
225
  * Names of schemas that participate in a circular dependency chain.
@@ -203,4 +240,4 @@ type PrinterFakerFactory = ast.PrinterFactoryOptions<'faker', PrinterFakerOption
203
240
  declare const printerFaker: (options: PrinterFakerOptions) => ast.Printer<PrinterFakerFactory>;
204
241
  //#endregion
205
242
  export { Options as a, printerFaker as i, PrinterFakerNodes as n, PluginFaker as o, PrinterFakerOptions as r, ResolverFaker as s, PrinterFakerFactory as t };
206
- //# sourceMappingURL=printerFaker-CJiwzoto.d.ts.map
243
+ //# sourceMappingURL=printerFaker-Bhwq62d1.d.ts.map