@kubb/plugin-fetch 5.13.0 → 5.13.2
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 +64 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +64 -11
- package/dist/index.js.map +1 -1
- package/docs/guides/serialization.md +6 -0
- package/package.json +4 -4
- package/templates/client.ts +13 -13
package/dist/index.js
CHANGED
|
@@ -107,22 +107,65 @@ function getEventStream(node) {
|
|
|
107
107
|
const content = getEventStreamContent(node);
|
|
108
108
|
return content ? content.stream?.shape ?? "data" : null;
|
|
109
109
|
}
|
|
110
|
+
function baseContentType(contentType) {
|
|
111
|
+
return contentType.split(";")[0].trim().toLowerCase();
|
|
112
|
+
}
|
|
113
|
+
function isJsonContentType(baseType) {
|
|
114
|
+
return baseType === "application/json" || baseType.endsWith("+json") || baseType === "text/json";
|
|
115
|
+
}
|
|
110
116
|
/**
|
|
111
|
-
*
|
|
117
|
+
* Parser for one response content entry.
|
|
112
118
|
*
|
|
113
|
-
*
|
|
114
|
-
* `
|
|
115
|
-
*
|
|
119
|
+
* JSON stays unset so the runtime detects it. `text/event-stream` is a stream. A binary schema
|
|
120
|
+
* (`format: binary` / `contentMediaType`) is a blob even when the media type is not a well-known
|
|
121
|
+
* binary type. Other `text/*` is text, and `application/octet-stream`, `application/pdf`,
|
|
122
|
+
* `image/*`, `audio/*`, and `video/*` are blobs.
|
|
116
123
|
*/
|
|
117
|
-
function
|
|
118
|
-
const baseType =
|
|
124
|
+
function responseTypeForContent(contentType, schema) {
|
|
125
|
+
const baseType = baseContentType(contentType);
|
|
119
126
|
if (!baseType) return void 0;
|
|
120
|
-
if (
|
|
127
|
+
if (isJsonContentType(baseType)) return void 0;
|
|
121
128
|
if (baseType === "text/event-stream") return "stream";
|
|
129
|
+
if (schema?.type === "blob") return "blob";
|
|
122
130
|
if (baseType.startsWith("text/")) return "text";
|
|
123
131
|
if (baseType === "application/octet-stream" || baseType === "application/pdf" || /^(image|audio|video)\//.test(baseType)) return "blob";
|
|
124
132
|
}
|
|
125
133
|
/**
|
|
134
|
+
* Derives the default `responseType` string for an operation from its primary success response.
|
|
135
|
+
*
|
|
136
|
+
* One content type uses {@link responseTypeForContent}. Several content types that all use the same
|
|
137
|
+
* parser collapse to that string, so a call can keep `responseType: 'blob'`. Mixed parsers return
|
|
138
|
+
* `undefined`; {@link getResponseTypeMap} carries the per-type choice.
|
|
139
|
+
*/
|
|
140
|
+
function getResponseType(node) {
|
|
141
|
+
const entries = getPrimarySuccessResponse(node)?.content ?? [];
|
|
142
|
+
if (entries.length === 0) return void 0;
|
|
143
|
+
const responseTypes = entries.map((entry) => responseTypeForContent(entry.contentType, entry.schema));
|
|
144
|
+
const first = responseTypes[0];
|
|
145
|
+
if (!first) return void 0;
|
|
146
|
+
if (responseTypes.every((responseType) => responseType === first)) return first;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Maps each base content type of a primary success response to its parser when those parsers differ.
|
|
150
|
+
*
|
|
151
|
+
* Keys are lowercased and stripped of parameters. JSON entries are kept as `'json'` so a catch-all
|
|
152
|
+
* entry cannot claim a JSON response. Returns `undefined` when {@link getResponseType} already
|
|
153
|
+
* covers the response with one string, or when no content type needs a parser other than JSON.
|
|
154
|
+
* The runtime matches the response `Content-Type` against this map instead of guessing from the media type.
|
|
155
|
+
*/
|
|
156
|
+
function getResponseTypeMap(node) {
|
|
157
|
+
if (getResponseType(node)) return void 0;
|
|
158
|
+
const entries = getPrimarySuccessResponse(node)?.content ?? [];
|
|
159
|
+
if (entries.length <= 1) return void 0;
|
|
160
|
+
const map = {};
|
|
161
|
+
for (const entry of entries) {
|
|
162
|
+
const baseType = baseContentType(entry.contentType);
|
|
163
|
+
const responseType = responseTypeForContent(entry.contentType, entry.schema) ?? (isJsonContentType(baseType) ? "json" : void 0);
|
|
164
|
+
if (baseType && responseType) map[baseType] = responseType;
|
|
165
|
+
}
|
|
166
|
+
return Object.values(map).some((responseType) => responseType !== "json") ? map : void 0;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
126
169
|
* Which of the grouped request options an operation carries.
|
|
127
170
|
*/
|
|
128
171
|
function getRequestGroups(node) {
|
|
@@ -150,7 +193,7 @@ function getRequestGroupOptionality(node) {
|
|
|
150
193
|
hasRequiredPath,
|
|
151
194
|
hasRequiredQuery,
|
|
152
195
|
hasRequiredHeader,
|
|
153
|
-
isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body
|
|
196
|
+
isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !(groups.body && node.requestBody?.required === true)
|
|
154
197
|
};
|
|
155
198
|
}
|
|
156
199
|
function buildOperationComments(node, options = {}) {
|
|
@@ -809,6 +852,17 @@ function buildStyles({ node }) {
|
|
|
809
852
|
}
|
|
810
853
|
// ../../internals/client/src/builders/callConfig.ts
|
|
811
854
|
/**
|
|
855
|
+
* `responseType` baked into a call. One parser is a string. Several parsers become a map from content
|
|
856
|
+
* type to parser so the runtime can choose from the response `Content-Type`.
|
|
857
|
+
*/
|
|
858
|
+
function buildResponseTypeLiteral(node) {
|
|
859
|
+
const responseType = getResponseType(node);
|
|
860
|
+
if (responseType) return `responseType: '${responseType}'`;
|
|
861
|
+
const responseTypes = getResponseTypeMap(node);
|
|
862
|
+
if (!responseTypes) return null;
|
|
863
|
+
return `responseType: { ${Object.entries(responseTypes).map(([contentType, type]) => `${JSON.stringify(contentType)}: '${type}'`).join(", ")} }`;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
812
866
|
* Builds the call config literal a generated operation forwards to the client, shared by the standalone
|
|
813
867
|
* functions and the SDK methods. The `throwOnError` fallback is applied after the `...config` spread.
|
|
814
868
|
*
|
|
@@ -835,7 +889,6 @@ function buildCallConfig({ node, validatorHooks, security, throwOnErrorDefault,
|
|
|
835
889
|
"error"
|
|
836
890
|
]);
|
|
837
891
|
const { literal: contentTypeLiteral, merge: mergeContentType } = buildContentType({ node });
|
|
838
|
-
const responseType = getResponseType(node);
|
|
839
892
|
return {
|
|
840
893
|
callConfig: `{ ${[
|
|
841
894
|
`method: '${node.method.toUpperCase()}'`,
|
|
@@ -844,7 +897,7 @@ function buildCallConfig({ node, validatorHooks, security, throwOnErrorDefault,
|
|
|
844
897
|
stylesLiteral ? `styles: ${stylesLiteral}` : null,
|
|
845
898
|
validatorLiteral,
|
|
846
899
|
contentTypeLiteral,
|
|
847
|
-
|
|
900
|
+
buildResponseTypeLiteral(node),
|
|
848
901
|
"...config",
|
|
849
902
|
`throwOnError: config.throwOnError ?? ${throwOnErrorDefault}`
|
|
850
903
|
].filter(Boolean).join(", ")} }`,
|
|
@@ -1650,7 +1703,7 @@ var compatibility = {
|
|
|
1650
1703
|
"node": ">=22.22"
|
|
1651
1704
|
};
|
|
1652
1705
|
// package.json
|
|
1653
|
-
var version = "5.13.
|
|
1706
|
+
var version = "5.13.2";
|
|
1654
1707
|
// src/plugin.ts
|
|
1655
1708
|
/**
|
|
1656
1709
|
* Canonical plugin name for `@kubb/plugin-fetch`. Used for driver lookups and cross-plugin
|