@kubb/plugin-fetch 5.5.0-canary.20260924T111237 → 5.5.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
@@ -502,7 +502,7 @@ function buildResultType({ node, types, returnType }) {
502
502
  * `withUnwrap`, so the caller can `await` it directly or call `.unwrap()` for the bare success
503
503
  * body. With `returnType: 'data'` it instead routes the call through the runtime's `unwrapResult`,
504
504
  * which narrows the resolved value down to the bare success body the same way `RequestResult`
505
- * already does, keeping the `throwOnError` default in one place instead of restating it per call.
505
+ * already does, using the plugin default when the call leaves `throwOnError` unset.
506
506
  *
507
507
  * Cast first, wrap second, for the `'full'` path. That order keeps `withUnwrap`'s generic inferred
508
508
  * as `RequestResult` instead of the runtime's own internal result type. Casting an `Unwrappable<A>`
@@ -512,10 +512,10 @@ function buildResultType({ node, types, returnType }) {
512
512
  * @example
513
513
  * `return withUnwrap(request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>)`
514
514
  * @example
515
- * `return unwrapResult(request({ method: 'POST', url: '/pet', ...config }), config.throwOnError) as Promise<UnwrappedResult<AddPetResponses, ThrowOnError>>`
515
+ * `return unwrapResult(request({ method: 'POST', url: '/pet', ...config }), config.throwOnError ?? false) as Promise<UnwrappedResult<AddPetResponses, ThrowOnError>>`
516
516
  */
517
- function buildReturnStatement({ node, types, callConfig, returnType }) {
518
- if (returnType === "data") return `return unwrapResult(request(${callConfig}), config.throwOnError) as ${buildResultType({
517
+ function buildReturnStatement({ node, types, callConfig, returnType, throwOnErrorDefault }) {
518
+ if (returnType === "data") return `return unwrapResult(request(${callConfig}), config.throwOnError ?? ${throwOnErrorDefault}) as ${buildResultType({
519
519
  node,
520
520
  types,
521
521
  returnType
@@ -605,7 +605,7 @@ const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declara
605
605
  * per-operation input type has to be emitted. Both names come from `types`, which is `plugin-ts` or
606
606
  * `plugin-zod`'s inferred types (see `resolveOperationTypes`).
607
607
  */
608
- function buildGroupedOptionsSignature({ node, types, returnType }) {
608
+ function buildGroupedOptionsSignature({ node, types, returnType, throwOnErrorDefault }) {
609
609
  const optionsName = types.response.options(node);
610
610
  const { isOptional } = getRequestGroupOptionality(node);
611
611
  return {
@@ -619,7 +619,7 @@ function buildGroupedOptionsSignature({ node, types, returnType }) {
619
619
  types,
620
620
  returnType
621
621
  }),
622
- generics: ["ThrowOnError extends boolean = true"]
622
+ generics: [`ThrowOnError extends boolean = ${throwOnErrorDefault}`]
623
623
  };
624
624
  }
625
625
  //#endregion
@@ -713,9 +713,10 @@ function buildValidatorHooks({ node, validator, zodResolver }) {
713
713
  /**
714
714
  * Builds the call config literal forwarded to the contract client, mirroring the shared `Operation`
715
715
  * component: `{ method, url, security?, validator?, ...config }`. The `...config` spread carries every
716
- * per-call field (including `throwOnError`), so the method stays a thin wrapper over the contract.
716
+ * per-call field. The plugin's `throwOnError` fallback is applied after the spread so it also wins
717
+ * over a client instance's runtime config when the call omits an override.
717
718
  */
718
- function buildCallConfig({ node, validator, zodResolver, security }) {
719
+ function buildCallConfig({ node, validator, zodResolver, security, throwOnErrorDefault }) {
719
720
  const validators = buildValidatorHooks({
720
721
  node,
721
722
  validator,
@@ -729,7 +730,8 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
729
730
  `url: '${node.path}'`,
730
731
  securityLiteral ? `security: ${securityLiteral}` : null,
731
732
  validatorLiteral,
732
- "...config"
733
+ "...config",
734
+ `throwOnError: config.throwOnError ?? ${throwOnErrorDefault}`
733
735
  ].filter(Boolean).join(", ")} }`;
734
736
  }
735
737
  /**
@@ -739,12 +741,13 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
739
741
  * instance client, so one operation can be routed to a different environment without a new
740
742
  * instance.
741
743
  */
742
- function buildSdkMethod({ node, name, types, zodResolver, validator, security, returnType }) {
744
+ function buildSdkMethod({ node, name, types, zodResolver, validator, security, returnType, throwOnErrorDefault }) {
743
745
  if (!kubb_kit.ast.isHttpOperationNode(node)) return "";
744
746
  const signature = buildGroupedOptionsSignature({
745
747
  node,
746
748
  types,
747
- returnType
749
+ returnType,
750
+ throwOnErrorDefault
748
751
  });
749
752
  const returnStatement = buildReturnStatement({
750
753
  node,
@@ -753,9 +756,11 @@ function buildSdkMethod({ node, name, types, zodResolver, validator, security, r
753
756
  node,
754
757
  validator,
755
758
  zodResolver,
756
- security
759
+ security,
760
+ throwOnErrorDefault
757
761
  }),
758
- returnType
762
+ returnType,
763
+ throwOnErrorDefault
759
764
  });
760
765
  const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
761
766
  const jsdoc = buildJSDoc(buildOperationComments(node, {
@@ -831,12 +836,13 @@ function buildStyles({ node }) {
831
836
  * type, signature, and call config are built with the AST factory, and only the jsx-renderer emits
832
837
  * the source.
833
838
  */
834
- function Operation({ name, node, types, zodResolver, validator, returnType, security, isExportable = true, isIndexable = true }) {
839
+ function Operation({ name, node, types, zodResolver, validator, returnType, throwOnErrorDefault, security, isExportable = true, isIndexable = true }) {
835
840
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
836
841
  const signature = buildGroupedOptionsSignature({
837
842
  node,
838
843
  types,
839
- returnType
844
+ returnType,
845
+ throwOnErrorDefault
840
846
  });
841
847
  const validators = buildValidatorHooks({
842
848
  node,
@@ -866,7 +872,8 @@ function Operation({ name, node, types, zodResolver, validator, returnType, secu
866
872
  validatorLiteral,
867
873
  contentTypeLiteral,
868
874
  responseTypeLiteral,
869
- "...config"
875
+ "...config",
876
+ `throwOnError: config.throwOnError ?? ${throwOnErrorDefault}`
870
877
  ].filter(Boolean).join(", ")} }`;
871
878
  const eventType = `SuccessOf<${types.response.responses(node)}>`;
872
879
  const functionReturnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
@@ -874,7 +881,8 @@ function Operation({ name, node, types, zodResolver, validator, returnType, secu
874
881
  node,
875
882
  types,
876
883
  callConfig,
877
- returnType
884
+ returnType,
885
+ throwOnErrorDefault
878
886
  });
879
887
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
880
888
  name,
@@ -907,7 +915,7 @@ function Operation({ name, node, types, zodResolver, validator, returnType, secu
907
915
  * instance: `const api = new PetClient({ baseURL }); api.getPetById(...)`. A per-call `client` option
908
916
  * still overrides the instance client for a one-off call.
909
917
  */
910
- function SdkClient({ name, isExportable = true, isIndexable = true, operations, validator, returnType, children }) {
918
+ function SdkClient({ name, isExportable = true, isIndexable = true, operations, validator, returnType, throwOnErrorDefault, children }) {
911
919
  const methods = operations.map(({ node, name: methodName, types, zodResolver, security }) => buildSdkMethod({
912
920
  node,
913
921
  name: methodName,
@@ -915,7 +923,8 @@ function SdkClient({ name, isExportable = true, isIndexable = true, operations,
915
923
  zodResolver,
916
924
  validator,
917
925
  security,
918
- returnType
926
+ returnType,
927
+ throwOnErrorDefault
919
928
  }));
920
929
  const classCode = `export class ${name} {\n${[
921
930
  " private readonly client: ClientInstance",
@@ -995,7 +1004,7 @@ function createClientGenerator(name) {
995
1004
  operation(node, ctx) {
996
1005
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
997
1006
  const { config, driver, resolver, root } = ctx;
998
- const { output, validator, returnType, group } = ctx.options;
1007
+ const { output, validator, returnType, throwOnErrorDefault, group } = ctx.options;
999
1008
  const types = resolveOperationTypes(driver);
1000
1009
  if (!types) {
1001
1010
  ctx.warn(MISSING_OPERATION_TYPES_WARNING);
@@ -1098,6 +1107,7 @@ function createClientGenerator(name) {
1098
1107
  zodResolver,
1099
1108
  validator,
1100
1109
  returnType,
1110
+ throwOnErrorDefault,
1101
1111
  security
1102
1112
  })
1103
1113
  ]
@@ -1238,7 +1248,7 @@ function createSdkGenerator() {
1238
1248
  renderer: kubb_jsx.jsxRenderer,
1239
1249
  operations(nodes, ctx) {
1240
1250
  const { config, resolver, root } = ctx;
1241
- const { output, group, validator, returnType, sdk } = ctx.options;
1251
+ const { output, group, validator, returnType, throwOnErrorDefault, sdk } = ctx.options;
1242
1252
  if (!sdk) return null;
1243
1253
  const types = resolveOperationTypes(ctx.driver);
1244
1254
  if (!types) {
@@ -1324,7 +1334,8 @@ function createSdkGenerator() {
1324
1334
  name: className,
1325
1335
  operations: ops,
1326
1336
  validator,
1327
- returnType
1337
+ returnType,
1338
+ throwOnErrorDefault
1328
1339
  })
1329
1340
  ]
1330
1341
  }, file.path);
@@ -1410,6 +1421,27 @@ const resolverClient = (0, kubb_kit.createResolver)({
1410
1421
  }
1411
1422
  });
1412
1423
  //#endregion
1424
+ //#region ../../internals/client/src/runtimeTemplate.ts
1425
+ /** Apply the active TypeScript parser's import extension to a copied client runtime. */
1426
+ function runtimeTemplate(path, config) {
1427
+ const parser = config.parsers.find((item) => item.extNames?.includes(".ts"));
1428
+ const probe = kubb_kit.ast.factory.createFile({
1429
+ baseName: "probe.ts",
1430
+ path: "probe.ts",
1431
+ imports: [kubb_kit.ast.factory.createImport({
1432
+ name: ["KubbRuntimeImport"],
1433
+ path: "/probeDependency.ts",
1434
+ root: "/"
1435
+ })],
1436
+ sources: [kubb_kit.ast.factory.createSource({
1437
+ name: "probe",
1438
+ nodes: [kubb_kit.ast.factory.createText("KubbRuntimeImport")]
1439
+ })]
1440
+ });
1441
+ const extension = parser?.parse(probe).match(/from ['"]\.\/probeDependency(\.[^'"]+)?['"]/)?.[1] ?? "";
1442
+ return (0, node_fs.readFileSync)(path, "utf8").replace(/(from ['"]\.\/(?:serializers|standardSchema))(?:\.ts|\.js)?(['"])/g, `$1${extension}$2`);
1443
+ }
1444
+ //#endregion
1413
1445
  //#region src/generators/clientGenerator.tsx
1414
1446
  /**
1415
1447
  * Built-in operation generator for `@kubb/plugin-fetch`. Emits one async function per OpenAPI
@@ -1461,7 +1493,7 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
1461
1493
  const { output = {
1462
1494
  path: "clients",
1463
1495
  barrel: { type: "named" }
1464
- }, exclude = [], include, override = [], baseURL, validator = false, returnType = "full", group, sdk, resolver: userResolver } = options;
1496
+ }, exclude = [], include, override = [], baseURL, throwOnErrorDefault = true, validator = false, returnType = "full", group, sdk, resolver: userResolver } = options;
1465
1497
  const resolved = {
1466
1498
  output,
1467
1499
  exclude,
@@ -1469,6 +1501,7 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
1469
1501
  override,
1470
1502
  group: createGroupConfig(group),
1471
1503
  baseURL,
1504
+ throwOnErrorDefault,
1472
1505
  validator,
1473
1506
  returnType,
1474
1507
  sdk: sdk ? {
@@ -1494,52 +1527,10 @@ const pluginFetch = (0, kubb_kit.definePlugin)((options) => {
1494
1527
  path: node_path.default.resolve(root, ".kubb/serializers.ts"),
1495
1528
  copy: fetchSerializersTemplatePath
1496
1529
  });
1497
- const clientPath = node_path.default.resolve(root, ".kubb/client.ts");
1498
- const clientSource = (0, node_fs.readFileSync)(fetchClientTemplatePath, "utf8");
1499
- const clientBody = clientSource.slice(clientSource.indexOf("\n\n") + 2);
1500
- const runtimeRoot = node_path.default.dirname(clientPath);
1501
1530
  ctx.injectFile({
1502
1531
  baseName: "client.ts",
1503
- path: clientPath,
1504
- imports: [
1505
- kubb_kit.ast.factory.createImport({
1506
- name: [
1507
- "applyHeaderStyles",
1508
- "defaultBodySerializer",
1509
- "defaultPathSerializer",
1510
- "defaultQuerySerializer",
1511
- "isDefaultJsonBody",
1512
- "serializeCookies"
1513
- ],
1514
- path: node_path.default.resolve(root, ".kubb/serializers.ts"),
1515
- root: runtimeRoot
1516
- }),
1517
- kubb_kit.ast.factory.createImport({
1518
- name: [
1519
- "HeadersInit",
1520
- "PathParamStyle",
1521
- "PathSerializer",
1522
- "RequestBody",
1523
- "Serializers",
1524
- "Styles"
1525
- ],
1526
- path: node_path.default.resolve(root, ".kubb/serializers.ts"),
1527
- root: runtimeRoot,
1528
- isTypeOnly: true
1529
- }),
1530
- kubb_kit.ast.factory.createImport({
1531
- name: ["ParseError", "validateStandardSchema"],
1532
- path: node_path.default.resolve(root, ".kubb/standardSchema.ts"),
1533
- root: runtimeRoot
1534
- }),
1535
- kubb_kit.ast.factory.createImport({
1536
- name: ["StandardSchemaValidator"],
1537
- path: node_path.default.resolve(root, ".kubb/standardSchema.ts"),
1538
- root: runtimeRoot,
1539
- isTypeOnly: true
1540
- })
1541
- ],
1542
- sources: [kubb_kit.ast.factory.createSource({ nodes: [kubb_kit.ast.factory.createText(clientBody)] })],
1532
+ path: node_path.default.resolve(root, ".kubb/client.ts"),
1533
+ banner: runtimeTemplate(fetchClientTemplatePath, ctx.config),
1543
1534
  footer: baseURLExpression ? `client.setConfig({ baseURL: ${baseURLExpression} })` : void 0
1544
1535
  });
1545
1536
  ctx.injectFile({