@kubb/plugin-client 5.8.0-canary.20261025T193221 → 5.8.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
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- //#region \0rolldown/runtime.js
5
+ // \0rolldown/runtime.js
6
6
  var __create = Object.create;
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -23,7 +23,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  value: mod,
24
24
  enumerable: true
25
25
  }) : target, mod));
26
- //#endregion
27
26
  let kubb_kit = require("kubb/kit");
28
27
  let node_path = require("node:path");
29
28
  node_path = __toESM(node_path, 1);
@@ -31,7 +30,7 @@ let _kubb_plugin_ts = require("@kubb/plugin-ts");
31
30
  let _kubb_plugin_zod = require("@kubb/plugin-zod");
32
31
  let kubb_jsx = require("kubb/jsx");
33
32
  let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
34
- //#region ../../internals/shared/src/operation.ts
33
+ // ../../internals/shared/src/operation.ts
35
34
  /**
36
35
  * Builds the `ResolverFileParams` every operation generator passes to
37
36
  * `resolver.file`: a file named `name`, tagged by the operation's first
@@ -209,6 +208,16 @@ function getOperationParameters(node) {
209
208
  operationParameterGroupsByNode.set(node, groups);
210
209
  return groups;
211
210
  }
211
+ /**
212
+ * Builds the combined `{ body, path, query, headers }` options object schema for an operation,
213
+ * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s
214
+ * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same
215
+ * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod
216
+ * printer to emit `z.object(…)` rather than a record.
217
+ */
218
+ function hasRequestContentTypeChoice(node) {
219
+ return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
220
+ }
212
221
  function getStatusCodeNumber(statusCode) {
213
222
  const code = Number(statusCode);
214
223
  return Number.isNaN(code) ? null : code;
@@ -226,8 +235,7 @@ function getOperationSuccessResponses(node) {
226
235
  function getPrimarySuccessResponse(node) {
227
236
  return getOperationSuccessResponses(node)[0] ?? null;
228
237
  }
229
- //#endregion
230
- //#region ../../internals/utils/src/casing.ts
238
+ // ../../internals/utils/src/casing.ts
231
239
  /**
232
240
  * Shared implementation for camelCase and PascalCase conversion.
233
241
  * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
@@ -276,8 +284,7 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
276
284
  function pascalCase(text, { prefix = "", suffix = "" } = {}) {
277
285
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
278
286
  }
279
- //#endregion
280
- //#region ../../internals/utils/src/reserved.ts
287
+ // ../../internals/utils/src/reserved.ts
281
288
  /**
282
289
  * JavaScript and Java reserved words.
283
290
  * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
@@ -285,6 +292,7 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
285
292
  const reservedWords = /* @__PURE__ */ new Set([
286
293
  "abstract",
287
294
  "arguments",
295
+ "await",
288
296
  "boolean",
289
297
  "break",
290
298
  "byte",
@@ -415,8 +423,29 @@ function ensureValidVarName(name) {
415
423
  function isIdentifier(name) {
416
424
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
417
425
  }
418
- //#endregion
419
- //#region ../../internals/shared/src/group.ts
426
+ // ../../internals/shared/src/resolver.ts
427
+ function resolveOperationName(name) {
428
+ return ensureValidVarName(camelCase(name));
429
+ }
430
+ /**
431
+ * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
432
+ * it is, so two of them never share an allocation even when a custom resolver gives both the same
433
+ * name. Leave `scope` empty for the operation's own declaration.
434
+ *
435
+ * @example
436
+ * ```ts
437
+ * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
438
+ * ```
439
+ */
440
+ function operationKey(node, ...scope) {
441
+ return [
442
+ "operation",
443
+ node.method,
444
+ node.path,
445
+ ...scope.map(String)
446
+ ];
447
+ }
448
+ // ../../internals/shared/src/group.ts
420
449
  /**
421
450
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
422
451
  * shared default naming so every plugin groups output consistently:
@@ -446,17 +475,14 @@ function createGroupConfig(group) {
446
475
  name: group.name ? group.name : defaultName
447
476
  };
448
477
  }
449
- //#endregion
450
- //#region kubb-extension.json
478
+ // kubb-extension.json
451
479
  var compatibility = {
452
- "kubb": ">=5.8.3",
480
+ "kubb": ">=5.14.6",
453
481
  "node": ">=22.22"
454
482
  };
455
- //#endregion
456
- //#region package.json
457
- var version = "5.8.0-canary.20261025T193221";
458
- //#endregion
459
- //#region ../../internals/client/src/builders/validatorOptions.ts
483
+ // package.json
484
+ var version = "5.8.0";
485
+ // ../../internals/client/src/builders/validatorOptions.ts
460
486
  /**
461
487
  * Returns `true` when any direction of the validator uses zod (used for dependency checks).
462
488
  */
@@ -499,8 +525,7 @@ function buildZodErrorParse(node, zodResolver) {
499
525
  if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
500
526
  return zodResolver.response.error?.(node) || null;
501
527
  }
502
- //#endregion
503
- //#region ../../internals/client/src/builders/security.ts
528
+ // ../../internals/client/src/builders/security.ts
504
529
  function serializeAuth(auth) {
505
530
  const parts = [`type: '${auth.type}'`];
506
531
  if (auth.scheme) parts.push(`scheme: '${auth.scheme}'`);
@@ -571,8 +596,7 @@ function buildSecurityMetadata({ security }) {
571
596
  if (!security?.length) return null;
572
597
  return `[${security.map(serializeAuth).join(", ")}]`;
573
598
  }
574
- //#endregion
575
- //#region ../../internals/client/src/builders/validator.ts
599
+ // ../../internals/client/src/builders/validator.ts
576
600
  /**
577
601
  * Builds the validator-hook references for one operation. Request body and params validation run before the send.
578
602
  * Response validation runs on the success body only. Returns `null` references when the matching
@@ -614,17 +638,16 @@ function buildValidatorLiteral(hooks, keys) {
614
638
  const entries = keys.flatMap((key) => hooks?.[key] ? [`${key}: ${hooks[key]}`] : []);
615
639
  return entries.length ? `validator: { ${entries.join(", ")} }` : null;
616
640
  }
617
- //#endregion
618
- //#region ../../internals/client/src/builders/contentType.ts
641
+ // ../../internals/client/src/builders/contentType.ts
619
642
  /**
620
- * Builds the `contentType` entry baked into the call config, or `null` for the JSON default.
643
+ * Builds the `contentType` entry baked into the call config, or `null` without a request body.
621
644
  *
622
645
  * `merge` is `true` when the generated function must destructure `contentType` from `options` and
623
646
  * merge it over the baked request default, because the caller can also pick a response content type.
624
647
  */
625
648
  function buildContentType({ node }) {
626
649
  const { defaultContentType } = getContentTypeInfo(node);
627
- const requestContentType = Boolean(node.requestBody?.content?.[0]?.schema) && defaultContentType !== "application/json" ? defaultContentType : null;
650
+ const requestContentType = Boolean(node.requestBody?.content?.[0]?.schema) ? defaultContentType : null;
628
651
  if (!requestContentType) return {
629
652
  literal: null,
630
653
  merge: false
@@ -635,8 +658,7 @@ function buildContentType({ node }) {
635
658
  literal: merge ? `contentType: { request: '${requestContentType}', ...(typeof contentType === 'string' ? { request: contentType } : contentType) }` : `contentType: { request: '${requestContentType}' }`
636
659
  };
637
660
  }
638
- //#endregion
639
- //#region ../../internals/client/src/builders/generics.ts
661
+ // ../../internals/client/src/builders/generics.ts
640
662
  /**
641
663
  * Builds the `RequestResult` generic arguments for one operation: the per-status responses record
642
664
  * plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
@@ -667,8 +689,7 @@ function buildResultType({ node, types, returnType }) {
667
689
  if (returnType === "plain") return `Promise<RequestResult<${generics}>>`;
668
690
  return `Unwrappable<RequestResult<${generics}>>`;
669
691
  }
670
- //#endregion
671
- //#region ../../internals/client/src/builders/returnStatement.ts
692
+ // ../../internals/client/src/builders/returnStatement.ts
672
693
  /**
673
694
  * Builds the return statement of a generated operation function. With the default
674
695
  * `returnType: 'full'` the runtime call already resolves to `{ data, error, request, response }`.
@@ -692,22 +713,22 @@ function buildResultType({ node, types, returnType }) {
692
713
  * `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`
693
714
  */
694
715
  function buildReturnStatement({ node, types, callConfig, returnType, throwOnErrorDefault }) {
695
- if (returnType === "data") return `return unwrapResult(request(${callConfig}), config.throwOnError ?? ${throwOnErrorDefault}) as ${buildResultType({
716
+ const request = returnType !== "plain" && hasRequestContentTypeChoice(node) ? `request<${types.response.options(node)}['body']>` : "request";
717
+ if (returnType === "data") return `return unwrapResult(${request}(${callConfig}), config.throwOnError ?? ${throwOnErrorDefault}) as ${buildResultType({
696
718
  node,
697
719
  types,
698
720
  returnType
699
721
  })}`;
700
- if (returnType === "plain") return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
722
+ if (returnType === "plain") return `return ${request}(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
701
723
  node,
702
724
  types
703
725
  })}>>`;
704
- return `return withUnwrap(request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
726
+ return `return withUnwrap(${request}(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
705
727
  node,
706
728
  types
707
729
  })}>>)`;
708
730
  }
709
- //#endregion
710
- //#region ../../internals/client/src/builders/signature.ts
731
+ // ../../internals/client/src/builders/signature.ts
711
732
  const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
712
733
  /**
713
734
  * Builds the grouped-options signature for one operation: a single `options` object whose `TData`
@@ -735,16 +756,14 @@ function buildGroupedOptionsSignature({ node, types, returnType, throwOnErrorDef
735
756
  generics: [`ThrowOnError extends boolean = ${throwOnErrorDefault}`]
736
757
  };
737
758
  }
738
- //#endregion
739
- //#region ../../internals/client/src/builders/styles.ts
759
+ // ../../internals/client/src/builders/styles.ts
740
760
  /**
741
- * Renders a parameter name as an object-literal key, quoted when it is not a bare identifier.
742
- * Path keys are camelCased to match the URL template placeholders. Query, header, and cookie keys
743
- * keep the spec name, matching the remapped keys the runtime serializes.
761
+ * Renders a parameter name as an object-literal key, quoted when it is not a bare identifier. Every
762
+ * location keeps the spec name: the runtime looks path styles up by the `{name}` placeholder in the
763
+ * URL, and the other locations by the key it serializes.
744
764
  */
745
- function toKey(name, location) {
746
- const key = location === "path" ? camelCase(name) : name;
747
- return isValidVarName(key) ? key : JSON.stringify(key);
765
+ function toKey(name) {
766
+ return isValidVarName(name) ? name : JSON.stringify(name);
748
767
  }
749
768
  /**
750
769
  * Serializes one parameter's metadata into a `{ style, explode, allowReserved, contentType }`
@@ -781,8 +800,7 @@ function serializeBodyEncoding(node) {
781
800
  }
782
801
  /**
783
802
  * Builds the per-operation `styles` literal from the operation's parameters, grouped by location.
784
- * Path entries are keyed by the camelCased name to match the URL template placeholders; query,
785
- * header, and cookie entries keep the spec name to match the keys the runtime serializes.
803
+ * Entries are keyed by the spec name of the parameter.
786
804
  * Only parameters whose source defines `style`, `explode`, `allowReserved`, or `contentType` are
787
805
  * emitted, so calls without serialization metadata keep the runtime defaults and existing output
788
806
  * is unchanged. A form request body adds a `body` group keyed by property name from its `encoding`.
@@ -805,13 +823,12 @@ function buildStyles({ node }) {
805
823
  for (const parameter of node.parameters) {
806
824
  const literal = serializeParameter(parameter);
807
825
  if (!literal) continue;
808
- groups[parameter.in].push(`${toKey(parameter.name, parameter.in)}: ${literal}`);
826
+ groups[parameter.in].push(`${toKey(parameter.name)}: ${literal}`);
809
827
  }
810
828
  const entries = [...Object.keys(groups).filter((location) => groups[location].length > 0).map((location) => `${location}: { ${groups[location].join(", ")} }`), serializeBodyEncoding(node)].filter(Boolean);
811
829
  return entries.length > 0 ? `{ ${entries.join(", ")} }` : null;
812
830
  }
813
- //#endregion
814
- //#region ../../internals/client/src/components/Operation.tsx
831
+ // ../../internals/client/src/components/Operation.tsx
815
832
  /**
816
833
  * Renders one client operation: the grouped `<Name>Request` type and the function that forwards a
817
834
  * single `options` object to the resolved client and returns the `Unwrappable<RequestResult>`. The
@@ -888,8 +905,7 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
888
905
  })
889
906
  });
890
907
  }
891
- //#endregion
892
- //#region ../../internals/client/src/resolveOperationTypes.ts
908
+ // ../../internals/client/src/resolveOperationTypes.ts
893
909
  /**
894
910
  * A `plugin-ts` shaped resolver whose operation type names point at the types `pluginZod({ inferred })`
895
911
  * exports next to each schema, so code written against `plugin-ts` names picks up the zod types.
@@ -955,8 +971,7 @@ function resolveOperationTypes(driver, pluginName) {
955
971
  group: pluginZod.options.group ?? void 0
956
972
  };
957
973
  }
958
- //#endregion
959
- //#region ../../internals/client/src/generators/clientGenerator.tsx
974
+ // ../../internals/client/src/generators/clientGenerator.tsx
960
975
  /**
961
976
  * Builds the built-in per-operation generator shared by the client plugins (`@kubb/plugin-fetch`,
962
977
  * `@kubb/plugin-axios`). Emits one async function per OpenAPI operation using the shared
@@ -983,8 +998,12 @@ function createClientGenerator(name, resolveClientPath) {
983
998
  zodResolver
984
999
  });
985
1000
  const importedZodNames = validatorHooks.importedZodNames;
1001
+ const operationName = resolver.name(node.operationId);
986
1002
  const meta = {
987
- name: resolver.name(node.operationId),
1003
+ name: resolver.resolveName({
1004
+ key: operationKey(node),
1005
+ name: operationName
1006
+ }),
988
1007
  file: resolver.file({
989
1008
  ...operationFileEntry(node, node.operationId),
990
1009
  root,
@@ -1099,19 +1118,17 @@ function createClientGenerator(name, resolveClientPath) {
1099
1118
  }
1100
1119
  });
1101
1120
  }
1102
- //#endregion
1103
- //#region ../../internals/client/src/macros.ts
1121
+ // ../../internals/client/src/macros.ts
1104
1122
  /**
1105
1123
  * Macros the client plugins apply by default, ahead of any user macros. `macroSimplifyUnion`
1106
1124
  * drops union members a broader scalar already covers, keeping the generated response and error
1107
1125
  * unions tidy. A plugin wires them with `ctx.setMacros([...defaultMacros, ...userMacros])`.
1108
1126
  */
1109
1127
  const defaultMacros = [kubb_kit.macroSimplifyUnion];
1110
- //#endregion
1111
- //#region ../../internals/client/src/resolver.ts
1128
+ // ../../internals/client/src/resolver.ts
1112
1129
  /**
1113
- * Default resolver shared by the client plugins. Functions and files inherit the built-in camelCase
1114
- * `name` and `file`; classes and tag groups use PascalCase.
1130
+ * Default resolver shared by the client plugins. Functions use safe camelCase identifiers and
1131
+ * files inherit the built-in casing; classes and tag groups use PascalCase.
1115
1132
  *
1116
1133
  * @example
1117
1134
  * ```ts
@@ -1121,6 +1138,7 @@ const defaultMacros = [kubb_kit.macroSimplifyUnion];
1121
1138
  */
1122
1139
  const resolverClient = (0, kubb_kit.createResolver)({
1123
1140
  pluginName: "plugin-contract-client",
1141
+ name: resolveOperationName,
1124
1142
  className(name) {
1125
1143
  return ensureValidVarName(pascalCase(name));
1126
1144
  },
@@ -1131,16 +1149,14 @@ const resolverClient = (0, kubb_kit.createResolver)({
1131
1149
  return ensureValidVarName(camelCase(name));
1132
1150
  }
1133
1151
  });
1134
- //#endregion
1135
- //#region src/generators/clientGenerator.tsx
1152
+ // src/generators/clientGenerator.tsx
1136
1153
  /**
1137
1154
  * Built-in operation generator for `@kubb/plugin-client`. Emits one async function per OpenAPI
1138
1155
  * operation using the shared `Operation` component: a grouped `<Name>Request` type and a function
1139
1156
  * that forwards a single `options` object to the user-provided client module and returns the `RequestResult`.
1140
1157
  */
1141
1158
  const clientGenerator = createClientGenerator("client", (options) => options.importPath);
1142
- //#endregion
1143
- //#region src/plugin.ts
1159
+ // src/plugin.ts
1144
1160
  /**
1145
1161
  * Canonical plugin name for `@kubb/plugin-client`.
1146
1162
  */
@@ -1191,7 +1207,6 @@ const pluginClient = (0, kubb_kit.defineExtension)({
1191
1207
  };
1192
1208
  }
1193
1209
  });
1194
- //#endregion
1195
1210
  exports.default = pluginClient;
1196
1211
  exports.pluginClient = pluginClient;
1197
1212
  exports.pluginClientName = pluginClientName;