@kubb/plugin-faker 5.2.0 → 5.2.2

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,13 +2,12 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- //#endregion
6
5
  let node_path = require("node:path");
7
6
  let kubb_kit = require("kubb/kit");
8
7
  let kubb_jsx = require("kubb/jsx");
9
8
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
10
9
  let _kubb_plugin_ts = require("@kubb/plugin-ts");
11
- //#region ../../internals/utils/src/casing.ts
10
+ // ../../internals/utils/src/casing.ts
12
11
  /**
13
12
  * Shared implementation for camelCase and PascalCase conversion.
14
13
  * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
@@ -45,8 +44,7 @@ function toCamelOrPascal(text, pascal) {
45
44
  function camelCase(text, { prefix = "", suffix = "" } = {}) {
46
45
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
47
46
  }
48
- //#endregion
49
- //#region ../../internals/utils/src/reserved.ts
47
+ // ../../internals/utils/src/reserved.ts
50
48
  /**
51
49
  * JavaScript and Java reserved words.
52
50
  * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
@@ -54,6 +52,7 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
54
52
  const reservedWords = /* @__PURE__ */ new Set([
55
53
  "abstract",
56
54
  "arguments",
55
+ "await",
57
56
  "boolean",
58
57
  "break",
59
58
  "byte",
@@ -184,8 +183,7 @@ function ensureValidVarName(name) {
184
183
  function isIdentifier(name) {
185
184
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
186
185
  }
187
- //#endregion
188
- //#region ../../internals/utils/src/strings.ts
186
+ // ../../internals/utils/src/strings.ts
189
187
  /**
190
188
  * Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
191
189
  * any backslash or single quote in the content.
@@ -246,6 +244,34 @@ function stringify(value) {
246
244
  function jsDocEscape(input) {
247
245
  return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
248
246
  }
247
+ const NEEDS_UNICODE = /(?<!\\)(?:\\\\)*\\[pPu]\{|[\u{10000}-\u{10FFFF}]/u;
248
+ const KEPT_ESCAPE = /[A-Za-z0-9^$\\.*+?()[\]{}|/]/;
249
+ /**
250
+ * Drops the backslash from escapes that the `u` flag rejects: an escaped punctuation character that is
251
+ * not a syntax character, and `\-` outside a class. Both match the same character without the backslash.
252
+ */
253
+ function dropIdentityEscapes(pattern) {
254
+ let inClass = false;
255
+ return pattern.replace(/\\(.)|[[\]]/gs, (match, escaped) => {
256
+ if (escaped === void 0) {
257
+ inClass = match === "[";
258
+ return match;
259
+ }
260
+ return KEPT_ESCAPE.test(escaped) || escaped === "-" && inClass ? match : escaped;
261
+ });
262
+ }
263
+ /**
264
+ * Builds the `RegExp` for a pattern, adding the `u` flag when it uses `\p{...}`, `\P{...}` or `\u{...}`, or
265
+ * holds a character outside the BMP. A pattern that is not valid under `u` keeps the flags it came with.
266
+ */
267
+ function toRegExp(pattern, flags) {
268
+ if (flags?.includes("u") || !NEEDS_UNICODE.test(pattern)) return new RegExp(pattern, flags);
269
+ try {
270
+ return new RegExp(dropIdentityEscapes(pattern), `${flags ?? ""}u`);
271
+ } catch {
272
+ return new RegExp(pattern, flags);
273
+ }
274
+ }
249
275
  /**
250
276
  * Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
251
277
  * Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
@@ -262,13 +288,11 @@ function toRegExpString(text, func = "RegExp") {
262
288
  const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
263
289
  const replacementTarget = match?.[1] ?? "";
264
290
  const matchedFlags = match?.[2];
265
- const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
266
- const { source, flags } = new RegExp(cleaned, matchedFlags);
291
+ const { source, flags } = toRegExp(raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, ""), matchedFlags);
267
292
  if (func === null) return `/${source}/${flags}`;
268
293
  return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
269
294
  }
270
- //#endregion
271
- //#region ../../internals/utils/src/codegen.ts
295
+ // ../../internals/utils/src/codegen.ts
272
296
  const INDENT = " ";
273
297
  /**
274
298
  * Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
@@ -305,8 +329,7 @@ function buildObject(entries) {
305
329
  if (entries.length === 0) return "{}";
306
330
  return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
307
331
  }
308
- //#endregion
309
- //#region ../../internals/utils/src/fs.ts
332
+ // ../../internals/utils/src/fs.ts
310
333
  function toSlash(p) {
311
334
  if (p.startsWith("\\\\?\\")) return p;
312
335
  return p.replaceAll("\\", "/");
@@ -348,8 +371,7 @@ function toFilePath(name, caseLast = camelCase) {
348
371
  const parts = name.split(/\.(?=[a-zA-Z])/);
349
372
  return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
350
373
  }
351
- //#endregion
352
- //#region src/utils.ts
374
+ // src/utils.ts
353
375
  /**
354
376
  * Returns the `@faker-js/faker` named export for a locale code.
355
377
  *
@@ -401,10 +423,16 @@ function canOverrideSchema(node) {
401
423
  return !NON_OVERRIDABLE_TYPES.has(node.type);
402
424
  }
403
425
  /**
404
- * Follows a ref, including alias chains, to the schema it resolves to. Unresolved refs are returned as is.
426
+ * Whether a schema can supply object properties when merging faker values.
405
427
  */
406
- function resolveRefTarget(node) {
407
- return node.type === "ref" && node.schema ? resolveRefTarget(node.schema) : node;
428
+ function isObjectSchema(node, seen = /* @__PURE__ */ new Set()) {
429
+ const resolved = kubb_kit.ast.resolveRef(node);
430
+ if (seen.has(resolved)) return false;
431
+ seen.add(resolved);
432
+ if (kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.object) || kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.ref)) return true;
433
+ const composition = kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.intersection) ?? kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.union);
434
+ if (!composition) return false;
435
+ return composition.type === kubb_kit.ast.schemaTypes.intersection && !composition.members?.length || (composition.members ?? []).some((member) => isObjectSchema(member, seen));
408
436
  }
409
437
  function shouldInlineSingleResponseSchema(schema) {
410
438
  return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
@@ -417,11 +445,16 @@ function buildResponseUnionSchema(node, resolver) {
417
445
  const responses = node.responses.filter((response) => response.content?.[0]?.schema);
418
446
  if (!responses.length) return null;
419
447
  if (responses.length === 1) {
420
- const schema = responses[0].content?.[0]?.schema;
448
+ const schemas = responses[0].content?.flatMap((content) => content.schema ? [content.schema] : []) ?? [];
449
+ const schema = schemas.length > 1 ? kubb_kit.ast.factory.createSchema({
450
+ type: "union",
451
+ members: schemas
452
+ }) : schemas[0];
421
453
  if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
422
454
  return kubb_kit.ast.factory.createSchema({
423
455
  type: "ref",
424
- name: resolver.response.status(node, responses[0].statusCode)
456
+ name: resolver.response.status(node, responses[0].statusCode),
457
+ schema: responses[0].content?.length === 1 ? schema : void 0
425
458
  });
426
459
  }
427
460
  return kubb_kit.ast.factory.createSchema({
@@ -490,7 +523,8 @@ function getScalarType(node, typeName) {
490
523
  * Determines the data type, return type, and whether it uses the type name.
491
524
  */
492
525
  function resolveFakerTypeUsage(node, typeName, canOverride) {
493
- const scalarType = SCALAR_TYPES.has(node.type) ? `${getScalarType(node, typeName)}${node.nullable ? " | null" : ""}` : void 0;
526
+ const resolvedNode = kubb_kit.ast.resolveRef(node);
527
+ const scalarType = SCALAR_TYPES.has(resolvedNode.type) ? `${getScalarType(resolvedNode, typeName)}${node.nullable || resolvedNode.nullable ? " | null" : ""}` : void 0;
494
528
  const dataType = scalarType ?? `Partial<${typeName}>`;
495
529
  const returnType = scalarType ?? (canOverride ? typeName : null);
496
530
  return {
@@ -499,28 +533,27 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
499
533
  usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
500
534
  };
501
535
  }
502
- //#endregion
503
- //#region src/components/Faker.tsx
504
- const OBJECT_TYPES = /* @__PURE__ */ new Set(["object", "intersection"]);
505
- function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred" }) {
536
+ // src/components/Faker.tsx
537
+ function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred", keysToOmit }) {
506
538
  const fakerText = printer.print(node) ?? "undefined";
507
539
  const isArray = node.type === "array";
508
- const isObject = OBJECT_TYPES.has(node.type);
540
+ const isObject = !!kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.object) || node.type === kubb_kit.ast.schemaTypes.intersection && isObjectSchema(node);
541
+ const isValueIntersection = node.type === kubb_kit.ast.schemaTypes.intersection && !isObject;
509
542
  const isTuple = node.type === "tuple";
510
543
  const isScalar = SCALAR_TYPES.has(node.type);
511
544
  const isUnion = node.type === "union";
512
- const useObjectOverride = canOverride && isObject;
545
+ const useObjectOverride = canOverride && (isObject || !!keysToOmit?.length);
513
546
  const fakerTextWithOverride = (() => {
514
547
  if (canOverride && node.type === "tuple") return `data && data.length === ${node.items?.length ?? 0} && !data.includes(undefined) ? data : ${fakerText}`;
515
548
  if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || []).filter((item) => item !== undefined),\n]`;
516
- if (canOverride && (isScalar || isUnion)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
549
+ if (canOverride && (isScalar || isUnion || isValueIntersection)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
517
550
  return fakerText;
518
551
  })();
519
552
  const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
520
553
  if (!useObjectOverride) {
521
554
  const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
522
555
  const returnType = resolvedReturnType;
523
- const returnExpression = canOverride && !!returnType && (node.type === "ref" || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
556
+ const returnExpression = canOverride && !!returnType && (node.type === "ref" && !SCALAR_TYPES.has(kubb_kit.ast.resolveRef(node).type) || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
524
557
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
525
558
  name,
526
559
  isExportable: true,
@@ -535,18 +568,21 @@ function Faker({ node, description, name, typeName, printer, canOverride, typeMo
535
568
  })
536
569
  });
537
570
  }
538
- const returnType = typeMode === "schema" ? typeName : "Omit<typeof defaultFakeData, keyof NoInfer<TData>> & NoInfer<TData>";
539
571
  const { cyclicSchemas, schemaName } = printer.options;
540
- const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, kubb_kit.containsCircularRef)(p.schema, {
572
+ const isCyclic = !!schemaName && !!cyclicSchemas?.has(schemaName);
573
+ const returnType = typeMode === "schema" ? typeName : `Omit<${isCyclic ? typeName : "typeof defaultFakeData"}, keyof NoInfer<TData>> & NoInfer<TData>`;
574
+ const hasGetters = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, kubb_kit.containsCircularRef)(p.schema, {
541
575
  circularSchemas: cyclicSchemas,
542
576
  excludeName: schemaName
543
- })) ? `const defaultFakeData = ${fakerText}
577
+ }));
578
+ const declaration = `const ${keysToOmit?.length ? `{ ${keysToOmit.map((key, index) => `${objectKey(key)}: _omit${index}`).join(", ")}, ...defaultFakeData }` : "defaultFakeData"} = ${fakerText}`;
579
+ const functionBody = hasGetters ? `${declaration}
544
580
  if (data) {
545
581
  for (const [key, value] of Object.entries(data)) {
546
582
  Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
547
583
  }
548
584
  }
549
- return defaultFakeData as ${returnType}` : `const defaultFakeData = ${fakerText}
585
+ return defaultFakeData as ${returnType}` : `${declaration}
550
586
  return {
551
587
  ...defaultFakeData,
552
588
  ...(data || {}),
@@ -561,13 +597,12 @@ return {
561
597
  JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
562
598
  generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
563
599
  params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
564
- returnType: typeMode === "schema" ? typeName : void 0,
600
+ returnType: typeMode === "schema" || isCyclic ? returnType : void 0,
565
601
  children: functionBody
566
602
  })
567
603
  });
568
604
  }
569
- //#endregion
570
- //#region ../../internals/shared/src/operation.ts
605
+ // ../../internals/shared/src/operation.ts
571
606
  /**
572
607
  * Builds the `ResolverFileParams` every operation generator passes to
573
608
  * `resolver.file`: a file named `name`, tagged by the operation's first
@@ -682,17 +717,24 @@ function getOperationParameters(node) {
682
717
  operationParameterGroupsByNode.set(node, groups);
683
718
  return groups;
684
719
  }
685
- //#endregion
686
- //#region ../../internals/shared/src/resolver.ts
720
+ // ../../internals/shared/src/resolver.ts
687
721
  /**
688
- * Resolves a single operation parameter name with the
689
- * `<operationId> <in> <name>` template.
722
+ * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
723
+ * it is, so two of them never share an allocation even when a custom resolver gives both the same
724
+ * name. Leave `scope` empty for the operation's own declaration.
690
725
  *
691
726
  * @example
692
- * `operationParamName.call(resolver, node, param) // → 'DeletePetPathPetId'`
727
+ * ```ts
728
+ * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
729
+ * ```
693
730
  */
694
- function operationParamName(node, param) {
695
- return this.name(`${node.operationId} ${param.in} ${param.name}`);
731
+ function operationKey(node, ...scope) {
732
+ return [
733
+ "operation",
734
+ node.method,
735
+ node.path,
736
+ ...scope.map(String)
737
+ ];
696
738
  }
697
739
  /**
698
740
  * Builds the shared `param` namespace. Spread the result into `createResolver`
@@ -705,15 +747,33 @@ function operationParamName(node, param) {
705
747
  */
706
748
  function createOperationParamResolver() {
707
749
  return {
708
- name: operationParamName,
750
+ name(node, param) {
751
+ const name = this.name(`${node.operationId} ${param.in} ${param.name}`);
752
+ return this.resolveName({
753
+ key: operationKey(node, "param", "name", param.in, param.name),
754
+ name
755
+ });
756
+ },
709
757
  path(node) {
710
- return this.name(`${node.operationId} Path`);
758
+ const name = this.name(`${node.operationId} Path`);
759
+ return this.resolveName({
760
+ key: operationKey(node, "param", "path"),
761
+ name
762
+ });
711
763
  },
712
764
  query(node) {
713
- return this.name(`${node.operationId} Query`);
765
+ const name = this.name(`${node.operationId} Query`);
766
+ return this.resolveName({
767
+ key: operationKey(node, "param", "query"),
768
+ name
769
+ });
714
770
  },
715
771
  headers(node) {
716
- return this.name(`${node.operationId} Headers`);
772
+ const name = this.name(`${node.operationId} Headers`);
773
+ return this.resolveName({
774
+ key: operationKey(node, "param", "headers"),
775
+ name
776
+ });
717
777
  }
718
778
  };
719
779
  }
@@ -730,16 +790,32 @@ function createOperationParamResolver() {
730
790
  function createOperationResponseResolver() {
731
791
  return {
732
792
  status(node, statusCode) {
733
- return this.name(`${node.operationId} Status ${statusCode}`);
793
+ const name = this.name(`${node.operationId} Status ${statusCode}`);
794
+ return this.resolveName({
795
+ key: operationKey(node, "response", "status", statusCode),
796
+ name
797
+ });
734
798
  },
735
799
  body(node) {
736
- return this.name(`${node.operationId} Body`);
800
+ const name = this.name(`${node.operationId} Body`);
801
+ return this.resolveName({
802
+ key: operationKey(node, "response", "body"),
803
+ name
804
+ });
737
805
  },
738
806
  responses(node) {
739
- return this.name(`${node.operationId} Responses`);
807
+ const name = this.name(`${node.operationId} Responses`);
808
+ return this.resolveName({
809
+ key: operationKey(node, "response", "responses"),
810
+ name
811
+ });
740
812
  },
741
813
  response(node) {
742
- return this.name(`${node.operationId} Response`);
814
+ const name = this.name(`${node.operationId} Response`);
815
+ return this.resolveName({
816
+ key: operationKey(node, "response", "response"),
817
+ name
818
+ });
743
819
  }
744
820
  };
745
821
  }
@@ -757,8 +833,7 @@ function createCasedFile(caseLast) {
757
833
  return `${toFilePath(name, caseLast)}${extname}`;
758
834
  } };
759
835
  }
760
- //#endregion
761
- //#region ../../internals/shared/src/group.ts
836
+ // ../../internals/shared/src/group.ts
762
837
  /**
763
838
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
764
839
  * shared default naming so every plugin groups output consistently:
@@ -788,8 +863,7 @@ function createGroupConfig(group) {
788
863
  name: group.name ? group.name : defaultName
789
864
  };
790
865
  }
791
- //#endregion
792
- //#region ../../internals/shared/src/schemaTraversal.ts
866
+ // ../../internals/shared/src/schemaTraversal.ts
793
867
  /**
794
868
  * Maps each member of a union or intersection schema to its transformed output, pairing every
795
869
  * result with the original member.
@@ -810,8 +884,7 @@ function mapSchemaItems(node, transform) {
810
884
  output: transform(schema)
811
885
  }));
812
886
  }
813
- //#endregion
814
- //#region src/utils/imports.ts
887
+ // src/utils/imports.ts
815
888
  function escapeRegExp(value) {
816
889
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
817
890
  }
@@ -859,8 +932,7 @@ function aliasConflictingImports(imports, reservedNames) {
859
932
  function rewriteAliasedImports(text, aliases) {
860
933
  return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
861
934
  }
862
- //#endregion
863
- //#region src/printers/printerFaker.ts
935
+ // src/printers/printerFaker.ts
864
936
  /**
865
937
  * Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
866
938
  * 64-bit integers, so the mock has to be digits rather than letters.
@@ -991,12 +1063,14 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
991
1063
  });
992
1064
  if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
993
1065
  const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
994
- if (!this.options.nestedInObject && canOverrideSchema(resolveRefTarget(node))) return `${resolvedName}(data)`;
1066
+ if (!this.options.nestedInObject && canOverrideSchema(kubb_kit.ast.resolveRef(node))) return `${resolvedName}(data)`;
995
1067
  return `${resolvedName}()`;
996
1068
  },
997
1069
  enum(node) {
998
1070
  const { typeName } = this.options;
999
- return `faker.helpers.arrayElement${typeName ? `<${typeName}>` : ""}([${kubb_kit.ast.getSchemaLiteralValues(node).map(parseEnumValue).join(", ")}])`;
1071
+ const values = kubb_kit.ast.getSchemaLiteralValues(node);
1072
+ if (values.length === 1 && values[0] !== null && typeof values[0] === "object") return JSON.stringify(values[0]);
1073
+ return `faker.helpers.arrayElement${typeName ? `<${typeName}>` : ""}([${values.map(parseEnumValue).join(", ")}])`;
1000
1074
  },
1001
1075
  union(node) {
1002
1076
  const { discriminatorPropertyName } = node;
@@ -1020,9 +1094,14 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
1020
1094
  }).map(({ output }) => output).filter((item) => Boolean(item)).join(", ")}])`;
1021
1095
  },
1022
1096
  intersection(node) {
1023
- const items = mapSchemaMembers(node, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
1097
+ const objectMembers = (node.members ?? []).filter((member) => isObjectSchema(member));
1098
+ const members = objectMembers.length ? objectMembers : node.members;
1099
+ const items = mapSchemaMembers({
1100
+ ...node,
1101
+ members
1102
+ }, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
1024
1103
  if (items.length === 0) return "{}";
1025
- return items.length === 1 ? items[0] : `{...${items.join(", ...")}}`;
1104
+ return !objectMembers.length || items.length === 1 ? items.at(-1) : `{...${items.join(", ...")}}`;
1026
1105
  },
1027
1106
  array(node) {
1028
1107
  const items = mapSchemaItems(node, (member) => printNested(member, {
@@ -1045,7 +1124,13 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
1045
1124
  },
1046
1125
  object(node) {
1047
1126
  const cyclicSchemas = this.options.cyclicSchemas;
1048
- return buildObject((node.properties ?? []).map((property) => {
1127
+ const keySchema = node.propertyNames && (0, kubb_kit.syncSchemaRef)(node.propertyNames);
1128
+ const valueSchema = node.additionalProperties;
1129
+ const recordProperties = keySchema?.type === "enum" && typeof valueSchema === "object" ? kubb_kit.ast.getSchemaLiteralValues(keySchema).filter((key) => typeof key === "string" && !node.properties.some((property) => property.name === key)).map((name) => kubb_kit.ast.factory.createProperty({
1130
+ name,
1131
+ schema: valueSchema
1132
+ })) : [];
1133
+ return buildObject([...node.properties, ...recordProperties].map((property) => {
1049
1134
  const value = printNested(property.schema, {
1050
1135
  typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
1051
1136
  nestedInObject: true
@@ -1061,8 +1146,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
1061
1146
  overrides: options.nodes
1062
1147
  };
1063
1148
  });
1064
- //#endregion
1065
- //#region src/generators/fakerGenerator.tsx
1149
+ // src/generators/fakerGenerator.tsx
1066
1150
  /**
1067
1151
  * Built-in generator for `@kubb/plugin-faker`. Emits one `createX` factory
1068
1152
  * per schema in the spec plus per-operation request/response factories. Each
@@ -1234,7 +1318,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1234
1318
  name: baseName,
1235
1319
  typeName: tsBaseName,
1236
1320
  description,
1237
- skipImportNames: []
1321
+ keysToOmit: primary.keysToOmit
1238
1322
  }];
1239
1323
  }
1240
1324
  const variants = resolveContentTypeVariants(entries, baseName);
@@ -1251,7 +1335,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1251
1335
  name: variant.name,
1252
1336
  typeName: getPerContentTypeName(tsBaseName, variant.suffix),
1253
1337
  description,
1254
- skipImportNames: []
1338
+ keysToOmit: variant.keysToOmit
1255
1339
  })), {
1256
1340
  schema: unionSchema,
1257
1341
  name: baseName,
@@ -1301,8 +1385,15 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1301
1385
  group: group ?? void 0
1302
1386
  }).filter((entry) => entry.path !== meta.file.path);
1303
1387
  }
1304
- function renderEntry({ schema, name, typeName, description, skipImportNames = [] }) {
1388
+ function renderEntry({ schema, name, typeName, description, keysToOmit, skipImportNames = [] }) {
1305
1389
  if (!schema) return null;
1390
+ if (schema.type === kubb_kit.ast.schemaTypes.object && keysToOmit?.length) {
1391
+ schema = {
1392
+ ...schema,
1393
+ properties: schema.properties.filter((property) => !keysToOmit?.includes(property.name))
1394
+ };
1395
+ keysToOmit = void 0;
1396
+ }
1306
1397
  const canOverride = canOverrideSchema(schema);
1307
1398
  const printerInstance = printerFaker({
1308
1399
  resolver,
@@ -1311,7 +1402,8 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1311
1402
  dateParser,
1312
1403
  regexGenerator,
1313
1404
  nodes: printer?.nodes,
1314
- cyclicSchemas
1405
+ cyclicSchemas,
1406
+ nestedInObject: !!keysToOmit?.length
1315
1407
  });
1316
1408
  const fakerText = printerInstance.print(schema) ?? "undefined";
1317
1409
  const { imports, aliases } = aliasConflictingImports(filterUsedImports(resolveMockImports(schema), fakerText, skipImportNames), localHelperNames);
@@ -1350,7 +1442,8 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1350
1442
  print: () => rewrittenFakerText
1351
1443
  },
1352
1444
  canOverride,
1353
- typeMode
1445
+ typeMode,
1446
+ keysToOmit
1354
1447
  })
1355
1448
  ] });
1356
1449
  }
@@ -1407,17 +1500,14 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1407
1500
  });
1408
1501
  }
1409
1502
  });
1410
- //#endregion
1411
- //#region kubb-extension.json
1503
+ // kubb-extension.json
1412
1504
  var compatibility = {
1413
- "kubb": ">=5.8.3",
1505
+ "kubb": ">=5.14.6",
1414
1506
  "node": ">=22.22"
1415
1507
  };
1416
- //#endregion
1417
- //#region package.json
1418
- var version = "5.2.0";
1419
- //#endregion
1420
- //#region src/resolvers/resolverFaker.ts
1508
+ // package.json
1509
+ var version = "5.2.2";
1510
+ // src/resolvers/resolverFaker.ts
1421
1511
  /**
1422
1512
  * Default resolver used by `@kubb/plugin-faker`. Decides the names and file
1423
1513
  * paths for every generated mock factory. Functions and files are prefixed
@@ -1439,8 +1529,7 @@ const resolverFaker = (0, kubb_kit.createResolver)({
1439
1529
  param: createOperationParamResolver(),
1440
1530
  response: createOperationResponseResolver()
1441
1531
  });
1442
- //#endregion
1443
- //#region src/plugin.ts
1532
+ // src/plugin.ts
1444
1533
  /**
1445
1534
  * Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
1446
1535
  * cross-plugin dependency references.
@@ -1501,7 +1590,6 @@ const pluginFaker = (0, kubb_kit.defineExtension)({
1501
1590
  };
1502
1591
  }
1503
1592
  });
1504
- //#endregion
1505
1593
  exports.Faker = Faker;
1506
1594
  exports.default = pluginFaker;
1507
1595
  exports.fakerGenerator = fakerGenerator;