@kubb/plugin-fetch 5.5.0-canary.20260924T111237 → 5.5.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 +37 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.js +37 -68
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/plugin.ts +5 -33
- package/templates/fetch.ts +4 -9
package/dist/index.d.ts
CHANGED
|
@@ -25,9 +25,8 @@ type Mode = 'tag' | 'flat';
|
|
|
25
25
|
/**
|
|
26
26
|
* Shape of the value a generated operation function resolves to.
|
|
27
27
|
* - `'full'`: the complete `{ status, data, error, contentType, request, response }` result.
|
|
28
|
-
* - `'data'`: the bare success body
|
|
29
|
-
*
|
|
30
|
-
* needs `error` to discriminate a failed response.
|
|
28
|
+
* - `'data'`: the bare success body when `throwOnError` is true, or the full result when it is false
|
|
29
|
+
* so callers can inspect `error`.
|
|
31
30
|
*/
|
|
32
31
|
type ReturnTypeOption = 'full' | 'data';
|
|
33
32
|
/**
|
|
@@ -71,13 +70,20 @@ type Options = OutputOptions & {
|
|
|
71
70
|
/**
|
|
72
71
|
* Apply a different options object to operations matching a pattern.
|
|
73
72
|
*/
|
|
74
|
-
override?: Array<Override<ResolvedOptions
|
|
73
|
+
override?: Array<Override<Omit<ResolvedOptions, 'throwOnErrorDefault'>>>;
|
|
75
74
|
/**
|
|
76
75
|
* Base URL prepended to every request. When omitted, falls back to the adapter's server URL.
|
|
77
76
|
* Values containing a `${...}` interpolation are emitted as template literals in the generated
|
|
78
77
|
* client config, which keeps runtime environment reads dynamic.
|
|
79
78
|
*/
|
|
80
79
|
baseURL?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Default error behavior for generated operations and their client. Per-call `throwOnError`
|
|
82
|
+
* takes precedence.
|
|
83
|
+
*
|
|
84
|
+
* @default true
|
|
85
|
+
*/
|
|
86
|
+
throwOnErrorDefault?: boolean;
|
|
81
87
|
/**
|
|
82
88
|
* Validate request and response bodies with schemas from `@kubb/plugin-zod`.
|
|
83
89
|
*
|
|
@@ -160,9 +166,10 @@ type ResolvedOptions = {
|
|
|
160
166
|
output: Output;
|
|
161
167
|
exclude: Array<Exclude>;
|
|
162
168
|
include: Array<Include> | undefined;
|
|
163
|
-
override: Array<Override<ResolvedOptions
|
|
169
|
+
override: Array<Override<Omit<ResolvedOptions, 'throwOnErrorDefault'>>>;
|
|
164
170
|
group: Group | null;
|
|
165
171
|
baseURL: Options['baseURL'];
|
|
172
|
+
throwOnErrorDefault: boolean;
|
|
166
173
|
validator: NonNullable<Options['validator']>;
|
|
167
174
|
returnType: ReturnTypeOption;
|
|
168
175
|
sdk: {
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import { createFunctionParameter, createFunctionParameters, functionPrinter, plu
|
|
|
5
5
|
import { File, Function, jsxRenderer } from "kubb/jsx";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
7
7
|
import { pluginZodName } from "@kubb/plugin-zod";
|
|
8
|
-
import { readFileSync } from "node:fs";
|
|
9
8
|
import { fileURLToPath } from "node:url";
|
|
10
9
|
//#region ../../internals/shared/src/params.ts
|
|
11
10
|
/**
|
|
@@ -476,7 +475,7 @@ function buildResultType({ node, types, returnType }) {
|
|
|
476
475
|
* `withUnwrap`, so the caller can `await` it directly or call `.unwrap()` for the bare success
|
|
477
476
|
* body. With `returnType: 'data'` it instead routes the call through the runtime's `unwrapResult`,
|
|
478
477
|
* which narrows the resolved value down to the bare success body the same way `RequestResult`
|
|
479
|
-
* already does,
|
|
478
|
+
* already does, using the plugin default when the call leaves `throwOnError` unset.
|
|
480
479
|
*
|
|
481
480
|
* Cast first, wrap second, for the `'full'` path. That order keeps `withUnwrap`'s generic inferred
|
|
482
481
|
* as `RequestResult` instead of the runtime's own internal result type. Casting an `Unwrappable<A>`
|
|
@@ -486,10 +485,10 @@ function buildResultType({ node, types, returnType }) {
|
|
|
486
485
|
* @example
|
|
487
486
|
* `return withUnwrap(request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>)`
|
|
488
487
|
* @example
|
|
489
|
-
* `return unwrapResult(request({ method: 'POST', url: '/pet', ...config }), config.throwOnError) as Promise<UnwrappedResult<AddPetResponses, ThrowOnError>>`
|
|
488
|
+
* `return unwrapResult(request({ method: 'POST', url: '/pet', ...config }), config.throwOnError ?? false) as Promise<UnwrappedResult<AddPetResponses, ThrowOnError>>`
|
|
490
489
|
*/
|
|
491
|
-
function buildReturnStatement({ node, types, callConfig, returnType }) {
|
|
492
|
-
if (returnType === "data") return `return unwrapResult(request(${callConfig}), config.throwOnError) as ${buildResultType({
|
|
490
|
+
function buildReturnStatement({ node, types, callConfig, returnType, throwOnErrorDefault }) {
|
|
491
|
+
if (returnType === "data") return `return unwrapResult(request(${callConfig}), config.throwOnError ?? ${throwOnErrorDefault}) as ${buildResultType({
|
|
493
492
|
node,
|
|
494
493
|
types,
|
|
495
494
|
returnType
|
|
@@ -579,7 +578,7 @@ const declarationPrinter = functionPrinter({ mode: "declaration" });
|
|
|
579
578
|
* per-operation input type has to be emitted. Both names come from `types`, which is `plugin-ts` or
|
|
580
579
|
* `plugin-zod`'s inferred types (see `resolveOperationTypes`).
|
|
581
580
|
*/
|
|
582
|
-
function buildGroupedOptionsSignature({ node, types, returnType }) {
|
|
581
|
+
function buildGroupedOptionsSignature({ node, types, returnType, throwOnErrorDefault }) {
|
|
583
582
|
const optionsName = types.response.options(node);
|
|
584
583
|
const { isOptional } = getRequestGroupOptionality(node);
|
|
585
584
|
return {
|
|
@@ -593,7 +592,7 @@ function buildGroupedOptionsSignature({ node, types, returnType }) {
|
|
|
593
592
|
types,
|
|
594
593
|
returnType
|
|
595
594
|
}),
|
|
596
|
-
generics: [
|
|
595
|
+
generics: [`ThrowOnError extends boolean = ${throwOnErrorDefault}`]
|
|
597
596
|
};
|
|
598
597
|
}
|
|
599
598
|
//#endregion
|
|
@@ -687,9 +686,10 @@ function buildValidatorHooks({ node, validator, zodResolver }) {
|
|
|
687
686
|
/**
|
|
688
687
|
* Builds the call config literal forwarded to the contract client, mirroring the shared `Operation`
|
|
689
688
|
* component: `{ method, url, security?, validator?, ...config }`. The `...config` spread carries every
|
|
690
|
-
* per-call field
|
|
689
|
+
* per-call field. The plugin's `throwOnError` fallback is applied after the spread so it also wins
|
|
690
|
+
* over a client instance's runtime config when the call omits an override.
|
|
691
691
|
*/
|
|
692
|
-
function buildCallConfig({ node, validator, zodResolver, security }) {
|
|
692
|
+
function buildCallConfig({ node, validator, zodResolver, security, throwOnErrorDefault }) {
|
|
693
693
|
const validators = buildValidatorHooks({
|
|
694
694
|
node,
|
|
695
695
|
validator,
|
|
@@ -703,7 +703,8 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
|
|
|
703
703
|
`url: '${node.path}'`,
|
|
704
704
|
securityLiteral ? `security: ${securityLiteral}` : null,
|
|
705
705
|
validatorLiteral,
|
|
706
|
-
"...config"
|
|
706
|
+
"...config",
|
|
707
|
+
`throwOnError: config.throwOnError ?? ${throwOnErrorDefault}`
|
|
707
708
|
].filter(Boolean).join(", ")} }`;
|
|
708
709
|
}
|
|
709
710
|
/**
|
|
@@ -713,12 +714,13 @@ function buildCallConfig({ node, validator, zodResolver, security }) {
|
|
|
713
714
|
* instance client, so one operation can be routed to a different environment without a new
|
|
714
715
|
* instance.
|
|
715
716
|
*/
|
|
716
|
-
function buildSdkMethod({ node, name, types, zodResolver, validator, security, returnType }) {
|
|
717
|
+
function buildSdkMethod({ node, name, types, zodResolver, validator, security, returnType, throwOnErrorDefault }) {
|
|
717
718
|
if (!ast.isHttpOperationNode(node)) return "";
|
|
718
719
|
const signature = buildGroupedOptionsSignature({
|
|
719
720
|
node,
|
|
720
721
|
types,
|
|
721
|
-
returnType
|
|
722
|
+
returnType,
|
|
723
|
+
throwOnErrorDefault
|
|
722
724
|
});
|
|
723
725
|
const returnStatement = buildReturnStatement({
|
|
724
726
|
node,
|
|
@@ -727,9 +729,11 @@ function buildSdkMethod({ node, name, types, zodResolver, validator, security, r
|
|
|
727
729
|
node,
|
|
728
730
|
validator,
|
|
729
731
|
zodResolver,
|
|
730
|
-
security
|
|
732
|
+
security,
|
|
733
|
+
throwOnErrorDefault
|
|
731
734
|
}),
|
|
732
|
-
returnType
|
|
735
|
+
returnType,
|
|
736
|
+
throwOnErrorDefault
|
|
733
737
|
});
|
|
734
738
|
const generics = signature.generics.length ? `<${signature.generics.join(", ")}>` : "";
|
|
735
739
|
const jsdoc = buildJSDoc(buildOperationComments(node, {
|
|
@@ -805,12 +809,13 @@ function buildStyles({ node }) {
|
|
|
805
809
|
* type, signature, and call config are built with the AST factory, and only the jsx-renderer emits
|
|
806
810
|
* the source.
|
|
807
811
|
*/
|
|
808
|
-
function Operation({ name, node, types, zodResolver, validator, returnType, security, isExportable = true, isIndexable = true }) {
|
|
812
|
+
function Operation({ name, node, types, zodResolver, validator, returnType, throwOnErrorDefault, security, isExportable = true, isIndexable = true }) {
|
|
809
813
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
810
814
|
const signature = buildGroupedOptionsSignature({
|
|
811
815
|
node,
|
|
812
816
|
types,
|
|
813
|
-
returnType
|
|
817
|
+
returnType,
|
|
818
|
+
throwOnErrorDefault
|
|
814
819
|
});
|
|
815
820
|
const validators = buildValidatorHooks({
|
|
816
821
|
node,
|
|
@@ -840,7 +845,8 @@ function Operation({ name, node, types, zodResolver, validator, returnType, secu
|
|
|
840
845
|
validatorLiteral,
|
|
841
846
|
contentTypeLiteral,
|
|
842
847
|
responseTypeLiteral,
|
|
843
|
-
"...config"
|
|
848
|
+
"...config",
|
|
849
|
+
`throwOnError: config.throwOnError ?? ${throwOnErrorDefault}`
|
|
844
850
|
].filter(Boolean).join(", ")} }`;
|
|
845
851
|
const eventType = `SuccessOf<${types.response.responses(node)}>`;
|
|
846
852
|
const functionReturnType = eventStream ? `Promise<EventStreamResult<${eventType}>>` : signature.returnType;
|
|
@@ -848,7 +854,8 @@ function Operation({ name, node, types, zodResolver, validator, returnType, secu
|
|
|
848
854
|
node,
|
|
849
855
|
types,
|
|
850
856
|
callConfig,
|
|
851
|
-
returnType
|
|
857
|
+
returnType,
|
|
858
|
+
throwOnErrorDefault
|
|
852
859
|
});
|
|
853
860
|
return /* @__PURE__ */ jsx(File.Source, {
|
|
854
861
|
name,
|
|
@@ -881,7 +888,7 @@ function Operation({ name, node, types, zodResolver, validator, returnType, secu
|
|
|
881
888
|
* instance: `const api = new PetClient({ baseURL }); api.getPetById(...)`. A per-call `client` option
|
|
882
889
|
* still overrides the instance client for a one-off call.
|
|
883
890
|
*/
|
|
884
|
-
function SdkClient({ name, isExportable = true, isIndexable = true, operations, validator, returnType, children }) {
|
|
891
|
+
function SdkClient({ name, isExportable = true, isIndexable = true, operations, validator, returnType, throwOnErrorDefault, children }) {
|
|
885
892
|
const methods = operations.map(({ node, name: methodName, types, zodResolver, security }) => buildSdkMethod({
|
|
886
893
|
node,
|
|
887
894
|
name: methodName,
|
|
@@ -889,7 +896,8 @@ function SdkClient({ name, isExportable = true, isIndexable = true, operations,
|
|
|
889
896
|
zodResolver,
|
|
890
897
|
validator,
|
|
891
898
|
security,
|
|
892
|
-
returnType
|
|
899
|
+
returnType,
|
|
900
|
+
throwOnErrorDefault
|
|
893
901
|
}));
|
|
894
902
|
const classCode = `export class ${name} {\n${[
|
|
895
903
|
" private readonly client: ClientInstance",
|
|
@@ -969,7 +977,7 @@ function createClientGenerator(name) {
|
|
|
969
977
|
operation(node, ctx) {
|
|
970
978
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
971
979
|
const { config, driver, resolver, root } = ctx;
|
|
972
|
-
const { output, validator, returnType, group } = ctx.options;
|
|
980
|
+
const { output, validator, returnType, throwOnErrorDefault, group } = ctx.options;
|
|
973
981
|
const types = resolveOperationTypes(driver);
|
|
974
982
|
if (!types) {
|
|
975
983
|
ctx.warn(MISSING_OPERATION_TYPES_WARNING);
|
|
@@ -1072,6 +1080,7 @@ function createClientGenerator(name) {
|
|
|
1072
1080
|
zodResolver,
|
|
1073
1081
|
validator,
|
|
1074
1082
|
returnType,
|
|
1083
|
+
throwOnErrorDefault,
|
|
1075
1084
|
security
|
|
1076
1085
|
})
|
|
1077
1086
|
]
|
|
@@ -1212,7 +1221,7 @@ function createSdkGenerator() {
|
|
|
1212
1221
|
renderer: jsxRenderer,
|
|
1213
1222
|
operations(nodes, ctx) {
|
|
1214
1223
|
const { config, resolver, root } = ctx;
|
|
1215
|
-
const { output, group, validator, returnType, sdk } = ctx.options;
|
|
1224
|
+
const { output, group, validator, returnType, throwOnErrorDefault, sdk } = ctx.options;
|
|
1216
1225
|
if (!sdk) return null;
|
|
1217
1226
|
const types = resolveOperationTypes(ctx.driver);
|
|
1218
1227
|
if (!types) {
|
|
@@ -1298,7 +1307,8 @@ function createSdkGenerator() {
|
|
|
1298
1307
|
name: className,
|
|
1299
1308
|
operations: ops,
|
|
1300
1309
|
validator,
|
|
1301
|
-
returnType
|
|
1310
|
+
returnType,
|
|
1311
|
+
throwOnErrorDefault
|
|
1302
1312
|
})
|
|
1303
1313
|
]
|
|
1304
1314
|
}, file.path);
|
|
@@ -1435,7 +1445,7 @@ const pluginFetch = definePlugin((options) => {
|
|
|
1435
1445
|
const { output = {
|
|
1436
1446
|
path: "clients",
|
|
1437
1447
|
barrel: { type: "named" }
|
|
1438
|
-
}, exclude = [], include, override = [], baseURL, validator = false, returnType = "full", group, sdk, resolver: userResolver } = options;
|
|
1448
|
+
}, exclude = [], include, override = [], baseURL, throwOnErrorDefault = true, validator = false, returnType = "full", group, sdk, resolver: userResolver } = options;
|
|
1439
1449
|
const resolved = {
|
|
1440
1450
|
output,
|
|
1441
1451
|
exclude,
|
|
@@ -1443,6 +1453,7 @@ const pluginFetch = definePlugin((options) => {
|
|
|
1443
1453
|
override,
|
|
1444
1454
|
group: createGroupConfig(group),
|
|
1445
1455
|
baseURL,
|
|
1456
|
+
throwOnErrorDefault,
|
|
1446
1457
|
validator,
|
|
1447
1458
|
returnType,
|
|
1448
1459
|
sdk: sdk ? {
|
|
@@ -1468,52 +1479,10 @@ const pluginFetch = definePlugin((options) => {
|
|
|
1468
1479
|
path: path.resolve(root, ".kubb/serializers.ts"),
|
|
1469
1480
|
copy: fetchSerializersTemplatePath
|
|
1470
1481
|
});
|
|
1471
|
-
const clientPath = path.resolve(root, ".kubb/client.ts");
|
|
1472
|
-
const clientSource = readFileSync(fetchClientTemplatePath, "utf8");
|
|
1473
|
-
const clientBody = clientSource.slice(clientSource.indexOf("\n\n") + 2);
|
|
1474
|
-
const runtimeRoot = path.dirname(clientPath);
|
|
1475
1482
|
ctx.injectFile({
|
|
1476
1483
|
baseName: "client.ts",
|
|
1477
|
-
path:
|
|
1478
|
-
|
|
1479
|
-
ast.factory.createImport({
|
|
1480
|
-
name: [
|
|
1481
|
-
"applyHeaderStyles",
|
|
1482
|
-
"defaultBodySerializer",
|
|
1483
|
-
"defaultPathSerializer",
|
|
1484
|
-
"defaultQuerySerializer",
|
|
1485
|
-
"isDefaultJsonBody",
|
|
1486
|
-
"serializeCookies"
|
|
1487
|
-
],
|
|
1488
|
-
path: path.resolve(root, ".kubb/serializers.ts"),
|
|
1489
|
-
root: runtimeRoot
|
|
1490
|
-
}),
|
|
1491
|
-
ast.factory.createImport({
|
|
1492
|
-
name: [
|
|
1493
|
-
"HeadersInit",
|
|
1494
|
-
"PathParamStyle",
|
|
1495
|
-
"PathSerializer",
|
|
1496
|
-
"RequestBody",
|
|
1497
|
-
"Serializers",
|
|
1498
|
-
"Styles"
|
|
1499
|
-
],
|
|
1500
|
-
path: path.resolve(root, ".kubb/serializers.ts"),
|
|
1501
|
-
root: runtimeRoot,
|
|
1502
|
-
isTypeOnly: true
|
|
1503
|
-
}),
|
|
1504
|
-
ast.factory.createImport({
|
|
1505
|
-
name: ["ParseError", "validateStandardSchema"],
|
|
1506
|
-
path: path.resolve(root, ".kubb/standardSchema.ts"),
|
|
1507
|
-
root: runtimeRoot
|
|
1508
|
-
}),
|
|
1509
|
-
ast.factory.createImport({
|
|
1510
|
-
name: ["StandardSchemaValidator"],
|
|
1511
|
-
path: path.resolve(root, ".kubb/standardSchema.ts"),
|
|
1512
|
-
root: runtimeRoot,
|
|
1513
|
-
isTypeOnly: true
|
|
1514
|
-
})
|
|
1515
|
-
],
|
|
1516
|
-
sources: [ast.factory.createSource({ nodes: [ast.factory.createText(clientBody)] })],
|
|
1484
|
+
path: path.resolve(root, ".kubb/client.ts"),
|
|
1485
|
+
copy: fetchClientTemplatePath,
|
|
1517
1486
|
footer: baseURLExpression ? `client.setConfig({ baseURL: ${baseURLExpression} })` : void 0
|
|
1518
1487
|
});
|
|
1519
1488
|
ctx.injectFile({
|