@kubb/plugin-faker 5.0.0-beta.99 → 5.0.0

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
@@ -580,8 +580,9 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
580
580
  })();
581
581
  const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
582
582
  if (!useGenericOverride) {
583
+ const dataParamName = /\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data";
583
584
  const params = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
584
- name: /\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data",
585
+ name: dataParamName,
585
586
  type: dataType,
586
587
  optional: true
587
588
  })] });
@@ -605,7 +606,7 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
605
606
  const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
606
607
  const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
607
608
  const { cyclicSchemas, schemaName } = printer.options;
608
- const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => kubb_kit.ast.containsCircularRef(p.schema, {
609
+ const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, kubb_kit.containsCircularRef)(p.schema, {
609
610
  circularSchemas: cyclicSchemas,
610
611
  excludeName: schemaName
611
612
  })) ? `{
@@ -651,6 +652,45 @@ function dedupeParams(params) {
651
652
  //#endregion
652
653
  //#region ../../internals/shared/src/operation.ts
653
654
  /**
655
+ * Builds the `ResolverFileParams` every operation generator passes to
656
+ * `resolver.file`: a file named `name`, tagged by the operation's first
657
+ * tag (or `'default'`), at the operation's path. Centralizes the entry object
658
+ * that was repeated at dozens of call sites across the client and query plugins.
659
+ *
660
+ * @example
661
+ * ```ts
662
+ * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
663
+ * ```
664
+ */
665
+ function operationFileEntry(node, name, extname = ".ts") {
666
+ return {
667
+ name,
668
+ extname,
669
+ tag: node.tags[0] ?? "default",
670
+ path: node.path
671
+ };
672
+ }
673
+ /**
674
+ * Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the
675
+ * current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the
676
+ * same dependency for the same operation in one pass (a query plugin's several hook generators, the
677
+ * MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.
678
+ *
679
+ * @example Cache `plugin-ts`'s file for the current operation
680
+ * ```ts
681
+ * const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })
682
+ * ```
683
+ */
684
+ function resolveDependencyOperationFile(options) {
685
+ const { cache, node, resolver, root, output, group } = options;
686
+ return cache.ensureItem(`${resolver.pluginName}:operationFile`, () => resolver.file({
687
+ ...operationFileEntry(node, node.operationId),
688
+ root,
689
+ output,
690
+ group: group ?? void 0
691
+ }));
692
+ }
693
+ /**
654
694
  * Maps a content type to the PascalCase suffix used to name per-content-type variants
655
695
  * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
656
696
  */
@@ -698,16 +738,24 @@ function resolveContentTypeVariants(entries, baseName) {
698
738
  };
699
739
  });
700
740
  }
741
+ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
742
+ /**
743
+ * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
744
+ * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
745
+ * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
746
+ * same parameters once per plugin.
747
+ */
701
748
  function getOperationParameters(node) {
702
- return {
703
- path: dedupeParams(node.parameters.filter((param) => param.in === "path").map((param) => isValidVarName(param.name) ? param : {
704
- ...param,
705
- name: camelCase(param.name)
706
- })),
749
+ const cached = operationParameterGroupsByNode.get(node);
750
+ if (cached) return cached;
751
+ const groups = {
752
+ path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
707
753
  query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
708
754
  header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
709
755
  cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
710
756
  };
757
+ operationParameterGroupsByNode.set(node, groups);
758
+ return groups;
711
759
  }
712
760
  //#endregion
713
761
  //#region ../../internals/shared/src/resolver.ts
@@ -839,6 +887,18 @@ function mapSchemaItems(node, transform) {
839
887
  }
840
888
  //#endregion
841
889
  //#region src/printers/printerFaker.ts
890
+ /**
891
+ * Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
892
+ * 64-bit integers, so the mock has to be digits rather than letters.
893
+ *
894
+ * @see https://protobuf.dev/programming-guides/json/#int64-strings
895
+ */
896
+ const integerFormats = /* @__PURE__ */ new Set([
897
+ "int32",
898
+ "int64",
899
+ "uint64"
900
+ ]);
901
+ const maxInt32 = 2147483647;
842
902
  const fakerKeywordMapper = {
843
903
  any: () => "undefined",
844
904
  unknown: () => "undefined",
@@ -856,6 +916,10 @@ const fakerKeywordMapper = {
856
916
  return "faker.number.int()";
857
917
  },
858
918
  bigint: () => "faker.number.bigInt()",
919
+ integerString: (format) => {
920
+ if (format === "int32") return `faker.number.int({ max: ${maxInt32} }).toString()`;
921
+ return "faker.number.bigInt().toString()";
922
+ },
859
923
  string: (min, max) => {
860
924
  if (max !== void 0 && min !== void 0) return `faker.string.alpha({ length: { min: ${min}, max: ${max} } })`;
861
925
  if (max !== void 0) return `faker.string.alpha({ length: ${max} })`;
@@ -955,6 +1019,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
955
1019
  null: () => fakerKeywordMapper.null(),
956
1020
  string(node) {
957
1021
  if (node.pattern) return fakerKeywordMapper.matches(node.pattern, this.options.regexGenerator);
1022
+ if (node.format && integerFormats.has(node.format)) return fakerKeywordMapper.integerString(node.format);
958
1023
  return fakerKeywordMapper.string(node.min, node.max);
959
1024
  },
960
1025
  email: () => fakerKeywordMapper.email(),
@@ -1031,7 +1096,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
1031
1096
  typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
1032
1097
  nestedInObject: true
1033
1098
  }) ?? "undefined";
1034
- if (cyclicSchemas && kubb_kit.ast.containsCircularRef(property.schema, {
1099
+ if (cyclicSchemas && (0, kubb_kit.containsCircularRef)(property.schema, {
1035
1100
  circularSchemas: cyclicSchemas,
1036
1101
  excludeName: this.options.schemaName
1037
1102
  })) 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 }`;
@@ -1260,14 +1325,13 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1260
1325
  output,
1261
1326
  group: group ?? void 0
1262
1327
  }),
1263
- typeFile: tsResolver.file({
1264
- name: node.operationId,
1265
- extname: ".ts",
1266
- tag: node.tags[0] ?? "default",
1267
- path: node.path,
1328
+ typeFile: resolveDependencyOperationFile({
1329
+ cache: ctx.cache,
1330
+ node,
1331
+ resolver: tsResolver,
1268
1332
  root,
1269
1333
  output: pluginTs.options?.output ?? output,
1270
- group: pluginTs.options?.group ?? void 0
1334
+ group: pluginTs.options?.group
1271
1335
  })
1272
1336
  };
1273
1337
  function resolveMockImports(schema) {