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

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
@@ -565,7 +565,7 @@ const SCALAR_TYPES = /* @__PURE__ */ new Set([
565
565
  "enum"
566
566
  ]);
567
567
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
568
- function Faker({ node, description, name, typeName, printer, seed, canOverride }) {
568
+ function Faker({ node, description, name, typeName, printer, canOverride }) {
569
569
  const fakerText = printer.print(node) ?? "undefined";
570
570
  const isArray = node.type === "array";
571
571
  const isObject = OBJECT_TYPES.has(node.type);
@@ -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
  })] });
@@ -592,24 +593,23 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
592
593
  name,
593
594
  isExportable: true,
594
595
  isIndexable: true,
595
- children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.Function, {
596
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.Function, {
596
597
  export: true,
597
598
  name,
598
599
  JSDoc: { comments: description ? [`@description ${jsStringEscape(description)}`] : [] },
599
600
  params: canOverride ? paramsSignature : void 0,
600
601
  returnType: returnType ?? void 0,
601
- 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}`]
602
+ children: `return ${returnExpression}`
602
603
  })
603
604
  });
604
605
  }
605
606
  const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
606
- const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
607
607
  const { cyclicSchemas, schemaName } = printer.options;
608
- const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => kubb_kit.ast.containsCircularRef(p.schema, {
608
+ const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, kubb_kit.containsCircularRef)(p.schema, {
609
609
  circularSchemas: cyclicSchemas,
610
610
  excludeName: schemaName
611
611
  })) ? `{
612
- ${seedCode}const defaultFakeData = ${fakerText}
612
+ const defaultFakeData = ${fakerText}
613
613
  if (data) {
614
614
  for (const [key, value] of Object.entries(data)) {
615
615
  Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
@@ -617,7 +617,7 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
617
617
  }
618
618
  return defaultFakeData as Omit<typeof defaultFakeData, keyof TData> & TData
619
619
  }` : `{
620
- ${seedCode}const defaultFakeData = ${fakerText}
620
+ const defaultFakeData = ${fakerText}
621
621
  return {
622
622
  ...defaultFakeData,
623
623
  ...(data || {}),
@@ -651,6 +651,45 @@ function dedupeParams(params) {
651
651
  //#endregion
652
652
  //#region ../../internals/shared/src/operation.ts
653
653
  /**
654
+ * Builds the `ResolverFileParams` every operation generator passes to
655
+ * `resolver.file`: a file named `name`, tagged by the operation's first
656
+ * tag (or `'default'`), at the operation's path. Centralizes the entry object
657
+ * that was repeated at dozens of call sites across the client and query plugins.
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
662
+ * ```
663
+ */
664
+ function operationFileEntry(node, name, extname = ".ts") {
665
+ return {
666
+ name,
667
+ extname,
668
+ tag: node.tags[0] ?? "default",
669
+ path: node.path
670
+ };
671
+ }
672
+ /**
673
+ * Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the
674
+ * current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the
675
+ * same dependency for the same operation in one pass (a query plugin's several hook generators, the
676
+ * MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.
677
+ *
678
+ * @example Cache `plugin-ts`'s file for the current operation
679
+ * ```ts
680
+ * const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })
681
+ * ```
682
+ */
683
+ function resolveDependencyOperationFile(options) {
684
+ const { cache, node, resolver, root, output, group } = options;
685
+ return cache.ensureItem(`${resolver.pluginName}:operationFile`, () => resolver.file({
686
+ ...operationFileEntry(node, node.operationId),
687
+ root,
688
+ output,
689
+ group: group ?? void 0
690
+ }));
691
+ }
692
+ /**
654
693
  * Maps a content type to the PascalCase suffix used to name per-content-type variants
655
694
  * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
656
695
  */
@@ -698,16 +737,24 @@ function resolveContentTypeVariants(entries, baseName) {
698
737
  };
699
738
  });
700
739
  }
740
+ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
741
+ /**
742
+ * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
743
+ * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
744
+ * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
745
+ * same parameters once per plugin.
746
+ */
701
747
  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
- })),
748
+ const cached = operationParameterGroupsByNode.get(node);
749
+ if (cached) return cached;
750
+ const groups = {
751
+ path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
707
752
  query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
708
753
  header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
709
754
  cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
710
755
  };
756
+ operationParameterGroupsByNode.set(node, groups);
757
+ return groups;
711
758
  }
712
759
  //#endregion
713
760
  //#region ../../internals/shared/src/resolver.ts
@@ -839,6 +886,18 @@ function mapSchemaItems(node, transform) {
839
886
  }
840
887
  //#endregion
841
888
  //#region src/printers/printerFaker.ts
889
+ /**
890
+ * Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
891
+ * 64-bit integers, so the mock has to be digits rather than letters.
892
+ *
893
+ * @see https://protobuf.dev/programming-guides/json/#int64-strings
894
+ */
895
+ const integerFormats = /* @__PURE__ */ new Set([
896
+ "int32",
897
+ "int64",
898
+ "uint64"
899
+ ]);
900
+ const maxInt32 = 2147483647;
842
901
  const fakerKeywordMapper = {
843
902
  any: () => "undefined",
844
903
  unknown: () => "undefined",
@@ -856,6 +915,10 @@ const fakerKeywordMapper = {
856
915
  return "faker.number.int()";
857
916
  },
858
917
  bigint: () => "faker.number.bigInt()",
918
+ integerString: (format) => {
919
+ if (format === "int32") return `faker.number.int({ max: ${maxInt32} }).toString()`;
920
+ return "faker.number.bigInt().toString()";
921
+ },
859
922
  string: (min, max) => {
860
923
  if (max !== void 0 && min !== void 0) return `faker.string.alpha({ length: { min: ${min}, max: ${max} } })`;
861
924
  if (max !== void 0) return `faker.string.alpha({ length: ${max} })`;
@@ -955,6 +1018,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
955
1018
  null: () => fakerKeywordMapper.null(),
956
1019
  string(node) {
957
1020
  if (node.pattern) return fakerKeywordMapper.matches(node.pattern, this.options.regexGenerator);
1021
+ if (node.format && integerFormats.has(node.format)) return fakerKeywordMapper.integerString(node.format);
958
1022
  return fakerKeywordMapper.string(node.min, node.max);
959
1023
  },
960
1024
  email: () => fakerKeywordMapper.email(),
@@ -1031,7 +1095,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
1031
1095
  typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
1032
1096
  nestedInObject: true
1033
1097
  }) ?? "undefined";
1034
- if (cyclicSchemas && kubb_kit.ast.containsCircularRef(property.schema, {
1098
+ if (cyclicSchemas && (0, kubb_kit.containsCircularRef)(property.schema, {
1035
1099
  circularSchemas: cyclicSchemas,
1036
1100
  excludeName: this.options.schemaName
1037
1101
  })) 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 }`;
@@ -1162,13 +1226,16 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1162
1226
  imp.path,
1163
1227
  imp.name
1164
1228
  ].join("-"))),
1229
+ seed ? /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1230
+ name: "faker-seed",
1231
+ children: `faker.seed(${JSON.stringify(seed)})`
1232
+ }) : void 0,
1165
1233
  /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Faker, {
1166
1234
  name: meta.name,
1167
1235
  typeName: typeReference.typeName,
1168
1236
  description: node.description,
1169
1237
  node,
1170
1238
  printer: printerInstance,
1171
- seed,
1172
1239
  canOverride
1173
1240
  })
1174
1241
  ]
@@ -1260,14 +1327,13 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1260
1327
  output,
1261
1328
  group: group ?? void 0
1262
1329
  }),
1263
- typeFile: tsResolver.file({
1264
- name: node.operationId,
1265
- extname: ".ts",
1266
- tag: node.tags[0] ?? "default",
1267
- path: node.path,
1330
+ typeFile: resolveDependencyOperationFile({
1331
+ cache: ctx.cache,
1332
+ node,
1333
+ resolver: tsResolver,
1268
1334
  root,
1269
1335
  output: pluginTs.options?.output ?? output,
1270
- group: pluginTs.options?.group ?? void 0
1336
+ group: pluginTs.options?.group
1271
1337
  })
1272
1338
  };
1273
1339
  function resolveMockImports(schema) {
@@ -1326,7 +1392,6 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1326
1392
  ...printerInstance,
1327
1393
  print: () => rewrittenFakerText
1328
1394
  },
1329
- seed,
1330
1395
  canOverride
1331
1396
  })
1332
1397
  ] });
@@ -1367,6 +1432,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1367
1432
  path: dateParser,
1368
1433
  name: dateParser
1369
1434
  }),
1435
+ seed ? /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1436
+ name: "faker-seed",
1437
+ children: `faker.seed(${JSON.stringify(seed)})`
1438
+ }) : void 0,
1370
1439
  paramGroups.map((group) => renderEntry(group)),
1371
1440
  responseUnits.map((unit) => renderEntry({
1372
1441
  schema: unit.schema,