@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.js CHANGED
@@ -4,8 +4,7 @@ import { createFunctionParameter, createFunctionParameters, functionPrinter, plu
4
4
  import { pluginZodName } from "@kubb/plugin-zod";
5
5
  import { File, Function, jsxRenderer } from "kubb/jsx";
6
6
  import { jsx, jsxs } from "kubb/jsx/jsx-runtime";
7
- //#endregion
8
- //#region ../../internals/shared/src/operation.ts
7
+ // ../../internals/shared/src/operation.ts
9
8
  /**
10
9
  * Builds the `ResolverFileParams` every operation generator passes to
11
10
  * `resolver.file`: a file named `name`, tagged by the operation's first
@@ -183,6 +182,16 @@ function getOperationParameters(node) {
183
182
  operationParameterGroupsByNode.set(node, groups);
184
183
  return groups;
185
184
  }
185
+ /**
186
+ * Builds the combined `{ body, path, query, headers }` options object schema for an operation,
187
+ * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s
188
+ * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same
189
+ * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod
190
+ * printer to emit `z.object(…)` rather than a record.
191
+ */
192
+ function hasRequestContentTypeChoice(node) {
193
+ return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
194
+ }
186
195
  function getStatusCodeNumber(statusCode) {
187
196
  const code = Number(statusCode);
188
197
  return Number.isNaN(code) ? null : code;
@@ -200,8 +209,7 @@ function getOperationSuccessResponses(node) {
200
209
  function getPrimarySuccessResponse(node) {
201
210
  return getOperationSuccessResponses(node)[0] ?? null;
202
211
  }
203
- //#endregion
204
- //#region ../../internals/utils/src/casing.ts
212
+ // ../../internals/utils/src/casing.ts
205
213
  /**
206
214
  * Shared implementation for camelCase and PascalCase conversion.
207
215
  * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
@@ -250,8 +258,7 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
250
258
  function pascalCase(text, { prefix = "", suffix = "" } = {}) {
251
259
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
252
260
  }
253
- //#endregion
254
- //#region ../../internals/utils/src/reserved.ts
261
+ // ../../internals/utils/src/reserved.ts
255
262
  /**
256
263
  * JavaScript and Java reserved words.
257
264
  * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
@@ -259,6 +266,7 @@ function pascalCase(text, { prefix = "", suffix = "" } = {}) {
259
266
  const reservedWords = /* @__PURE__ */ new Set([
260
267
  "abstract",
261
268
  "arguments",
269
+ "await",
262
270
  "boolean",
263
271
  "break",
264
272
  "byte",
@@ -389,8 +397,29 @@ function ensureValidVarName(name) {
389
397
  function isIdentifier(name) {
390
398
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
391
399
  }
392
- //#endregion
393
- //#region ../../internals/shared/src/group.ts
400
+ // ../../internals/shared/src/resolver.ts
401
+ function resolveOperationName(name) {
402
+ return ensureValidVarName(camelCase(name));
403
+ }
404
+ /**
405
+ * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
406
+ * it is, so two of them never share an allocation even when a custom resolver gives both the same
407
+ * name. Leave `scope` empty for the operation's own declaration.
408
+ *
409
+ * @example
410
+ * ```ts
411
+ * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
412
+ * ```
413
+ */
414
+ function operationKey(node, ...scope) {
415
+ return [
416
+ "operation",
417
+ node.method,
418
+ node.path,
419
+ ...scope.map(String)
420
+ ];
421
+ }
422
+ // ../../internals/shared/src/group.ts
394
423
  /**
395
424
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
396
425
  * shared default naming so every plugin groups output consistently:
@@ -420,17 +449,14 @@ function createGroupConfig(group) {
420
449
  name: group.name ? group.name : defaultName
421
450
  };
422
451
  }
423
- //#endregion
424
- //#region kubb-extension.json
452
+ // kubb-extension.json
425
453
  var compatibility = {
426
- "kubb": ">=5.8.3",
454
+ "kubb": ">=5.14.6",
427
455
  "node": ">=22.22"
428
456
  };
429
- //#endregion
430
- //#region package.json
431
- var version = "5.8.0-canary.20261025T193221";
432
- //#endregion
433
- //#region ../../internals/client/src/builders/validatorOptions.ts
457
+ // package.json
458
+ var version = "5.8.0";
459
+ // ../../internals/client/src/builders/validatorOptions.ts
434
460
  /**
435
461
  * Returns `true` when any direction of the validator uses zod (used for dependency checks).
436
462
  */
@@ -473,8 +499,7 @@ function buildZodErrorParse(node, zodResolver) {
473
499
  if (!node.responses.some((res) => !isSuccessStatusCode(res.statusCode) && res.content?.some((entry) => entry.schema))) return null;
474
500
  return zodResolver.response.error?.(node) || null;
475
501
  }
476
- //#endregion
477
- //#region ../../internals/client/src/builders/security.ts
502
+ // ../../internals/client/src/builders/security.ts
478
503
  function serializeAuth(auth) {
479
504
  const parts = [`type: '${auth.type}'`];
480
505
  if (auth.scheme) parts.push(`scheme: '${auth.scheme}'`);
@@ -545,8 +570,7 @@ function buildSecurityMetadata({ security }) {
545
570
  if (!security?.length) return null;
546
571
  return `[${security.map(serializeAuth).join(", ")}]`;
547
572
  }
548
- //#endregion
549
- //#region ../../internals/client/src/builders/validator.ts
573
+ // ../../internals/client/src/builders/validator.ts
550
574
  /**
551
575
  * Builds the validator-hook references for one operation. Request body and params validation run before the send.
552
576
  * Response validation runs on the success body only. Returns `null` references when the matching
@@ -588,17 +612,16 @@ function buildValidatorLiteral(hooks, keys) {
588
612
  const entries = keys.flatMap((key) => hooks?.[key] ? [`${key}: ${hooks[key]}`] : []);
589
613
  return entries.length ? `validator: { ${entries.join(", ")} }` : null;
590
614
  }
591
- //#endregion
592
- //#region ../../internals/client/src/builders/contentType.ts
615
+ // ../../internals/client/src/builders/contentType.ts
593
616
  /**
594
- * Builds the `contentType` entry baked into the call config, or `null` for the JSON default.
617
+ * Builds the `contentType` entry baked into the call config, or `null` without a request body.
595
618
  *
596
619
  * `merge` is `true` when the generated function must destructure `contentType` from `options` and
597
620
  * merge it over the baked request default, because the caller can also pick a response content type.
598
621
  */
599
622
  function buildContentType({ node }) {
600
623
  const { defaultContentType } = getContentTypeInfo(node);
601
- const requestContentType = Boolean(node.requestBody?.content?.[0]?.schema) && defaultContentType !== "application/json" ? defaultContentType : null;
624
+ const requestContentType = Boolean(node.requestBody?.content?.[0]?.schema) ? defaultContentType : null;
602
625
  if (!requestContentType) return {
603
626
  literal: null,
604
627
  merge: false
@@ -609,8 +632,7 @@ function buildContentType({ node }) {
609
632
  literal: merge ? `contentType: { request: '${requestContentType}', ...(typeof contentType === 'string' ? { request: contentType } : contentType) }` : `contentType: { request: '${requestContentType}' }`
610
633
  };
611
634
  }
612
- //#endregion
613
- //#region ../../internals/client/src/builders/generics.ts
635
+ // ../../internals/client/src/builders/generics.ts
614
636
  /**
615
637
  * Builds the `RequestResult` generic arguments for one operation: the per-status responses record
616
638
  * plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the
@@ -641,8 +663,7 @@ function buildResultType({ node, types, returnType }) {
641
663
  if (returnType === "plain") return `Promise<RequestResult<${generics}>>`;
642
664
  return `Unwrappable<RequestResult<${generics}>>`;
643
665
  }
644
- //#endregion
645
- //#region ../../internals/client/src/builders/returnStatement.ts
666
+ // ../../internals/client/src/builders/returnStatement.ts
646
667
  /**
647
668
  * Builds the return statement of a generated operation function. With the default
648
669
  * `returnType: 'full'` the runtime call already resolves to `{ data, error, request, response }`.
@@ -666,22 +687,22 @@ function buildResultType({ node, types, returnType }) {
666
687
  * `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`
667
688
  */
668
689
  function buildReturnStatement({ node, types, callConfig, returnType, throwOnErrorDefault }) {
669
- if (returnType === "data") return `return unwrapResult(request(${callConfig}), config.throwOnError ?? ${throwOnErrorDefault}) as ${buildResultType({
690
+ const request = returnType !== "plain" && hasRequestContentTypeChoice(node) ? `request<${types.response.options(node)}['body']>` : "request";
691
+ if (returnType === "data") return `return unwrapResult(${request}(${callConfig}), config.throwOnError ?? ${throwOnErrorDefault}) as ${buildResultType({
670
692
  node,
671
693
  types,
672
694
  returnType
673
695
  })}`;
674
- if (returnType === "plain") return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
696
+ if (returnType === "plain") return `return ${request}(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
675
697
  node,
676
698
  types
677
699
  })}>>`;
678
- return `return withUnwrap(request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
700
+ return `return withUnwrap(${request}(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({
679
701
  node,
680
702
  types
681
703
  })}>>)`;
682
704
  }
683
- //#endregion
684
- //#region ../../internals/client/src/builders/signature.ts
705
+ // ../../internals/client/src/builders/signature.ts
685
706
  const declarationPrinter = functionPrinter({ mode: "declaration" });
686
707
  /**
687
708
  * Builds the grouped-options signature for one operation: a single `options` object whose `TData`
@@ -709,16 +730,14 @@ function buildGroupedOptionsSignature({ node, types, returnType, throwOnErrorDef
709
730
  generics: [`ThrowOnError extends boolean = ${throwOnErrorDefault}`]
710
731
  };
711
732
  }
712
- //#endregion
713
- //#region ../../internals/client/src/builders/styles.ts
733
+ // ../../internals/client/src/builders/styles.ts
714
734
  /**
715
- * Renders a parameter name as an object-literal key, quoted when it is not a bare identifier.
716
- * Path keys are camelCased to match the URL template placeholders. Query, header, and cookie keys
717
- * keep the spec name, matching the remapped keys the runtime serializes.
735
+ * Renders a parameter name as an object-literal key, quoted when it is not a bare identifier. Every
736
+ * location keeps the spec name: the runtime looks path styles up by the `{name}` placeholder in the
737
+ * URL, and the other locations by the key it serializes.
718
738
  */
719
- function toKey(name, location) {
720
- const key = location === "path" ? camelCase(name) : name;
721
- return isValidVarName(key) ? key : JSON.stringify(key);
739
+ function toKey(name) {
740
+ return isValidVarName(name) ? name : JSON.stringify(name);
722
741
  }
723
742
  /**
724
743
  * Serializes one parameter's metadata into a `{ style, explode, allowReserved, contentType }`
@@ -755,8 +774,7 @@ function serializeBodyEncoding(node) {
755
774
  }
756
775
  /**
757
776
  * Builds the per-operation `styles` literal from the operation's parameters, grouped by location.
758
- * Path entries are keyed by the camelCased name to match the URL template placeholders; query,
759
- * header, and cookie entries keep the spec name to match the keys the runtime serializes.
777
+ * Entries are keyed by the spec name of the parameter.
760
778
  * Only parameters whose source defines `style`, `explode`, `allowReserved`, or `contentType` are
761
779
  * emitted, so calls without serialization metadata keep the runtime defaults and existing output
762
780
  * is unchanged. A form request body adds a `body` group keyed by property name from its `encoding`.
@@ -779,13 +797,12 @@ function buildStyles({ node }) {
779
797
  for (const parameter of node.parameters) {
780
798
  const literal = serializeParameter(parameter);
781
799
  if (!literal) continue;
782
- groups[parameter.in].push(`${toKey(parameter.name, parameter.in)}: ${literal}`);
800
+ groups[parameter.in].push(`${toKey(parameter.name)}: ${literal}`);
783
801
  }
784
802
  const entries = [...Object.keys(groups).filter((location) => groups[location].length > 0).map((location) => `${location}: { ${groups[location].join(", ")} }`), serializeBodyEncoding(node)].filter(Boolean);
785
803
  return entries.length > 0 ? `{ ${entries.join(", ")} }` : null;
786
804
  }
787
- //#endregion
788
- //#region ../../internals/client/src/components/Operation.tsx
805
+ // ../../internals/client/src/components/Operation.tsx
789
806
  /**
790
807
  * Renders one client operation: the grouped `<Name>Request` type and the function that forwards a
791
808
  * single `options` object to the resolved client and returns the `Unwrappable<RequestResult>`. The
@@ -862,8 +879,7 @@ function Operation({ name, node, types, zodResolver, validator, returnType, thro
862
879
  })
863
880
  });
864
881
  }
865
- //#endregion
866
- //#region ../../internals/client/src/resolveOperationTypes.ts
882
+ // ../../internals/client/src/resolveOperationTypes.ts
867
883
  /**
868
884
  * A `plugin-ts` shaped resolver whose operation type names point at the types `pluginZod({ inferred })`
869
885
  * exports next to each schema, so code written against `plugin-ts` names picks up the zod types.
@@ -929,8 +945,7 @@ function resolveOperationTypes(driver, pluginName) {
929
945
  group: pluginZod.options.group ?? void 0
930
946
  };
931
947
  }
932
- //#endregion
933
- //#region ../../internals/client/src/generators/clientGenerator.tsx
948
+ // ../../internals/client/src/generators/clientGenerator.tsx
934
949
  /**
935
950
  * Builds the built-in per-operation generator shared by the client plugins (`@kubb/plugin-fetch`,
936
951
  * `@kubb/plugin-axios`). Emits one async function per OpenAPI operation using the shared
@@ -957,8 +972,12 @@ function createClientGenerator(name, resolveClientPath) {
957
972
  zodResolver
958
973
  });
959
974
  const importedZodNames = validatorHooks.importedZodNames;
975
+ const operationName = resolver.name(node.operationId);
960
976
  const meta = {
961
- name: resolver.name(node.operationId),
977
+ name: resolver.resolveName({
978
+ key: operationKey(node),
979
+ name: operationName
980
+ }),
962
981
  file: resolver.file({
963
982
  ...operationFileEntry(node, node.operationId),
964
983
  root,
@@ -1073,19 +1092,17 @@ function createClientGenerator(name, resolveClientPath) {
1073
1092
  }
1074
1093
  });
1075
1094
  }
1076
- //#endregion
1077
- //#region ../../internals/client/src/macros.ts
1095
+ // ../../internals/client/src/macros.ts
1078
1096
  /**
1079
1097
  * Macros the client plugins apply by default, ahead of any user macros. `macroSimplifyUnion`
1080
1098
  * drops union members a broader scalar already covers, keeping the generated response and error
1081
1099
  * unions tidy. A plugin wires them with `ctx.setMacros([...defaultMacros, ...userMacros])`.
1082
1100
  */
1083
1101
  const defaultMacros = [macroSimplifyUnion];
1084
- //#endregion
1085
- //#region ../../internals/client/src/resolver.ts
1102
+ // ../../internals/client/src/resolver.ts
1086
1103
  /**
1087
- * Default resolver shared by the client plugins. Functions and files inherit the built-in camelCase
1088
- * `name` and `file`; classes and tag groups use PascalCase.
1104
+ * Default resolver shared by the client plugins. Functions use safe camelCase identifiers and
1105
+ * files inherit the built-in casing; classes and tag groups use PascalCase.
1089
1106
  *
1090
1107
  * @example
1091
1108
  * ```ts
@@ -1095,6 +1112,7 @@ const defaultMacros = [macroSimplifyUnion];
1095
1112
  */
1096
1113
  const resolverClient = createResolver({
1097
1114
  pluginName: "plugin-contract-client",
1115
+ name: resolveOperationName,
1098
1116
  className(name) {
1099
1117
  return ensureValidVarName(pascalCase(name));
1100
1118
  },
@@ -1105,16 +1123,14 @@ const resolverClient = createResolver({
1105
1123
  return ensureValidVarName(camelCase(name));
1106
1124
  }
1107
1125
  });
1108
- //#endregion
1109
- //#region src/generators/clientGenerator.tsx
1126
+ // src/generators/clientGenerator.tsx
1110
1127
  /**
1111
1128
  * Built-in operation generator for `@kubb/plugin-client`. Emits one async function per OpenAPI
1112
1129
  * operation using the shared `Operation` component: a grouped `<Name>Request` type and a function
1113
1130
  * that forwards a single `options` object to the user-provided client module and returns the `RequestResult`.
1114
1131
  */
1115
1132
  const clientGenerator = createClientGenerator("client", (options) => options.importPath);
1116
- //#endregion
1117
- //#region src/plugin.ts
1133
+ // src/plugin.ts
1118
1134
  /**
1119
1135
  * Canonical plugin name for `@kubb/plugin-client`.
1120
1136
  */
@@ -1165,7 +1181,6 @@ const pluginClient = defineExtension({
1165
1181
  };
1166
1182
  }
1167
1183
  });
1168
- //#endregion
1169
1184
  export { pluginClient as default, pluginClient, pluginClientName };
1170
1185
 
1171
1186
  //# sourceMappingURL=index.js.map