@hey-api/openapi-ts 0.96.1 → 0.97.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/README.md +1 -1
- package/dist/clients/angular/client.ts +30 -20
- package/dist/clients/angular/types.ts +4 -2
- package/dist/clients/angular/utils.ts +4 -2
- package/dist/clients/fetch/client.ts +111 -129
- package/dist/clients/fetch/types.ts +4 -2
- package/dist/clients/fetch/utils.ts +4 -2
- package/dist/clients/ky/client.ts +156 -121
- package/dist/clients/ky/index.ts +0 -1
- package/dist/clients/ky/types.ts +22 -34
- package/dist/clients/ky/utils.ts +4 -2
- package/dist/clients/next/client.ts +102 -100
- package/dist/clients/next/types.ts +2 -1
- package/dist/clients/next/utils.ts +2 -1
- package/dist/clients/ofetch/client.ts +68 -58
- package/dist/clients/ofetch/types.ts +4 -2
- package/dist/clients/ofetch/utils.ts +5 -3
- package/dist/index.d.mts +582 -1017
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{init-D4xuNKgu.mjs → init-Bi6_Uyy_.mjs} +348 -26
- package/dist/init-Bi6_Uyy_.mjs.map +1 -0
- package/dist/internal.d.mts +1 -1
- package/dist/internal.mjs +1 -1
- package/dist/run.mjs +2 -2
- package/dist/{src-DlsTSwMY.mjs → src-CSz9FXkH.mjs} +19 -10
- package/dist/src-CSz9FXkH.mjs.map +1 -0
- package/dist/{types-DAEl4_a4.d.mts → types-KzipN7UT.d.mts} +7 -2
- package/dist/types-KzipN7UT.d.mts.map +1 -0
- package/package.json +6 -5
- package/dist/init-D4xuNKgu.mjs.map +0 -1
- package/dist/src-DlsTSwMY.mjs.map +0 -1
- package/dist/types-DAEl4_a4.d.mts.map +0 -1
|
@@ -72,131 +72,138 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
72
72
|
|
|
73
73
|
// @ts-expect-error
|
|
74
74
|
const request: Client['request'] = async (options) => {
|
|
75
|
-
const
|
|
75
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
76
|
+
|
|
77
|
+
let response: Response | undefined;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const { opts, url } = await beforeRequest(options);
|
|
76
81
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
for (const fn of interceptors.request.fns) {
|
|
83
|
+
if (fn) {
|
|
84
|
+
await fn(opts);
|
|
85
|
+
}
|
|
80
86
|
}
|
|
81
|
-
}
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
// fetch must be assigned here, otherwise it would throw the error:
|
|
89
|
+
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
|
|
90
|
+
const _fetch = opts.fetch!;
|
|
91
|
+
const requestInit: ReqInit = {
|
|
92
|
+
...opts,
|
|
93
|
+
body: getValidRequestBody(opts),
|
|
94
|
+
};
|
|
90
95
|
|
|
91
|
-
|
|
96
|
+
response = await _fetch(url, requestInit);
|
|
92
97
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
for (const fn of interceptors.response.fns) {
|
|
99
|
+
if (fn) {
|
|
100
|
+
response = await fn(response, opts);
|
|
101
|
+
}
|
|
96
102
|
}
|
|
97
|
-
}
|
|
98
103
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
const result = {
|
|
105
|
+
response,
|
|
106
|
+
};
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
if (response.ok) {
|
|
109
|
+
const parseAs =
|
|
110
|
+
(opts.parseAs === 'auto'
|
|
111
|
+
? getParseAs(response.headers.get('Content-Type'))
|
|
112
|
+
: opts.parseAs) ?? 'json';
|
|
113
|
+
|
|
114
|
+
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
|
|
115
|
+
let emptyData: any;
|
|
116
|
+
switch (parseAs) {
|
|
117
|
+
case 'arrayBuffer':
|
|
118
|
+
case 'blob':
|
|
119
|
+
case 'text':
|
|
120
|
+
emptyData = await response[parseAs]();
|
|
121
|
+
break;
|
|
122
|
+
case 'formData':
|
|
123
|
+
emptyData = new FormData();
|
|
124
|
+
break;
|
|
125
|
+
case 'stream':
|
|
126
|
+
emptyData = response.body;
|
|
127
|
+
break;
|
|
128
|
+
case 'json':
|
|
129
|
+
default:
|
|
130
|
+
emptyData = {};
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
data: emptyData,
|
|
135
|
+
...result,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
108
138
|
|
|
109
|
-
|
|
110
|
-
let emptyData: any;
|
|
139
|
+
let data: any;
|
|
111
140
|
switch (parseAs) {
|
|
112
141
|
case 'arrayBuffer':
|
|
113
142
|
case 'blob':
|
|
143
|
+
case 'formData':
|
|
114
144
|
case 'text':
|
|
115
|
-
|
|
145
|
+
data = await response[parseAs]();
|
|
116
146
|
break;
|
|
117
|
-
case '
|
|
118
|
-
|
|
147
|
+
case 'json': {
|
|
148
|
+
// Some servers return 200 with no Content-Length and empty body.
|
|
149
|
+
// response.json() would throw; read as text and parse if non-empty.
|
|
150
|
+
const text = await response.text();
|
|
151
|
+
data = text ? JSON.parse(text) : {};
|
|
119
152
|
break;
|
|
153
|
+
}
|
|
120
154
|
case 'stream':
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
emptyData = {};
|
|
126
|
-
break;
|
|
155
|
+
return {
|
|
156
|
+
data: response.body,
|
|
157
|
+
...result,
|
|
158
|
+
};
|
|
127
159
|
}
|
|
160
|
+
|
|
161
|
+
if (parseAs === 'json') {
|
|
162
|
+
if (opts.responseValidator) {
|
|
163
|
+
await opts.responseValidator(data);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (opts.responseTransformer) {
|
|
167
|
+
data = await opts.responseTransformer(data);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
128
171
|
return {
|
|
129
|
-
data
|
|
172
|
+
data,
|
|
130
173
|
...result,
|
|
131
174
|
};
|
|
132
175
|
}
|
|
133
176
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
break;
|
|
142
|
-
case 'json': {
|
|
143
|
-
// Some servers return 200 with no Content-Length and empty body.
|
|
144
|
-
// response.json() would throw; read as text and parse if non-empty.
|
|
145
|
-
const text = await response.text();
|
|
146
|
-
data = text ? JSON.parse(text) : {};
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
case 'stream':
|
|
150
|
-
return {
|
|
151
|
-
data: response.body,
|
|
152
|
-
...result,
|
|
153
|
-
};
|
|
177
|
+
const textError = await response.text();
|
|
178
|
+
let jsonError: unknown;
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
jsonError = JSON.parse(textError);
|
|
182
|
+
} catch {
|
|
183
|
+
// noop
|
|
154
184
|
}
|
|
155
185
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
186
|
+
throw jsonError ?? textError;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
let finalError = error;
|
|
160
189
|
|
|
161
|
-
|
|
162
|
-
|
|
190
|
+
for (const fn of interceptors.error.fns) {
|
|
191
|
+
if (fn) {
|
|
192
|
+
finalError = await fn(finalError, response, options as ResolvedRequestOptions);
|
|
163
193
|
}
|
|
164
194
|
}
|
|
165
195
|
|
|
166
|
-
|
|
167
|
-
data,
|
|
168
|
-
...result,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
196
|
+
finalError = finalError || {};
|
|
171
197
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
jsonError = JSON.parse(textError);
|
|
177
|
-
} catch {
|
|
178
|
-
// noop
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const error = jsonError ?? textError;
|
|
182
|
-
let finalError = error;
|
|
183
|
-
|
|
184
|
-
for (const fn of interceptors.error.fns) {
|
|
185
|
-
if (fn) {
|
|
186
|
-
finalError = (await fn(error, response, opts)) as string;
|
|
198
|
+
if (throwOnError) {
|
|
199
|
+
throw finalError;
|
|
187
200
|
}
|
|
188
|
-
}
|
|
189
201
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
return {
|
|
203
|
+
error: finalError,
|
|
204
|
+
response,
|
|
205
|
+
};
|
|
194
206
|
}
|
|
195
|
-
|
|
196
|
-
return {
|
|
197
|
-
error: finalError,
|
|
198
|
-
...result,
|
|
199
|
-
};
|
|
200
207
|
};
|
|
201
208
|
|
|
202
209
|
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
|
|
@@ -207,18 +214,13 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
207
214
|
return createSseClient({
|
|
208
215
|
...opts,
|
|
209
216
|
body: opts.body as BodyInit | null | undefined,
|
|
210
|
-
headers: opts.headers as unknown as Record<string, string>,
|
|
211
217
|
method,
|
|
212
218
|
onRequest: async (url, init) => {
|
|
213
219
|
let request = new Request(url, init);
|
|
214
|
-
const requestInit = {
|
|
215
|
-
...init,
|
|
216
|
-
method: init.method as Config['method'],
|
|
217
|
-
url,
|
|
218
|
-
};
|
|
220
|
+
const requestInit = { ...init, url };
|
|
219
221
|
for (const fn of interceptors.request.fns) {
|
|
220
222
|
if (fn) {
|
|
221
|
-
await fn(requestInit as
|
|
223
|
+
await fn(requestInit as ResolvedRequestOptions);
|
|
222
224
|
request = new Request(requestInit.url, requestInit);
|
|
223
225
|
}
|
|
224
226
|
}
|
|
@@ -97,7 +97,8 @@ export type RequestResult<
|
|
|
97
97
|
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
|
|
98
98
|
}
|
|
99
99
|
) & {
|
|
100
|
-
response
|
|
100
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
101
|
+
response?: Response;
|
|
101
102
|
}
|
|
102
103
|
>;
|
|
103
104
|
|
|
@@ -325,7 +325,8 @@ export const mergeHeaders = (
|
|
|
325
325
|
|
|
326
326
|
type ErrInterceptor<Err, Res, Options> = (
|
|
327
327
|
error: Err,
|
|
328
|
-
response
|
|
328
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
329
|
+
response: Res | undefined,
|
|
329
330
|
options: Options,
|
|
330
331
|
) => Err | Promise<Err>;
|
|
331
332
|
|
|
@@ -116,7 +116,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
116
116
|
// ignore request.body changes to avoid turning serialized bodies into streams
|
|
117
117
|
// body comes only from getValidRequestBody(options)
|
|
118
118
|
// reflect signal if present
|
|
119
|
-
opts.signal =
|
|
119
|
+
opts.signal = request.signal;
|
|
120
120
|
|
|
121
121
|
// When body is FormData, remove Content-Type header to avoid boundary mismatch.
|
|
122
122
|
// Note: We already delete Content-Type in resolveOptions for FormData, but the
|
|
@@ -138,92 +138,102 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
138
138
|
body: BodyInit | null | undefined,
|
|
139
139
|
responseType: OfetchResponseType | undefined,
|
|
140
140
|
) => {
|
|
141
|
-
const effectiveRetry = isRepeatableBody(body) ?
|
|
141
|
+
const effectiveRetry = isRepeatableBody(body) ? opts.retry : 0;
|
|
142
142
|
return buildOfetchOptions(opts, body, responseType, effectiveRetry);
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
const request: Client['request'] = async (options) => {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
146
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
147
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
148
|
+
|
|
149
|
+
let request: Request | undefined;
|
|
150
|
+
let response: Awaited<ReturnType<typeof ofetch.raw>> | undefined;
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const {
|
|
154
|
+
networkBody: initialNetworkBody,
|
|
155
|
+
opts,
|
|
156
|
+
url,
|
|
157
|
+
} = await resolveOptions(options as RequestOptions);
|
|
158
|
+
// map parseAs -> ofetch responseType once per request
|
|
159
|
+
const ofetchResponseType: OfetchResponseType | undefined = mapParseAsToResponseType(
|
|
160
|
+
opts.parseAs,
|
|
161
|
+
opts.responseType,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const $ofetch = opts.ofetch ?? ofetch;
|
|
165
|
+
|
|
166
|
+
// create Request before network to run middleware consistently
|
|
167
|
+
const networkBody = initialNetworkBody;
|
|
168
|
+
const requestInit: ReqInit = {
|
|
169
|
+
body: networkBody,
|
|
170
|
+
headers: opts.headers,
|
|
171
|
+
method: opts.method,
|
|
172
|
+
redirect: 'follow',
|
|
173
|
+
signal: opts.signal,
|
|
174
|
+
};
|
|
175
|
+
request = new Request(url, requestInit);
|
|
176
|
+
|
|
177
|
+
request = await applyRequestInterceptors(request, opts, networkBody);
|
|
178
|
+
const finalUrl = request.url;
|
|
179
|
+
|
|
180
|
+
// build ofetch options and perform the request (.raw keeps the Response)
|
|
181
|
+
const responseOptions = buildNetworkOptions(opts, networkBody, ofetchResponseType);
|
|
182
|
+
|
|
183
|
+
response = await $ofetch.raw(finalUrl, responseOptions);
|
|
184
|
+
|
|
185
|
+
for (const fn of interceptors.response.fns) {
|
|
186
|
+
if (fn) {
|
|
187
|
+
response = await fn(response, request, opts);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
175
190
|
|
|
176
|
-
|
|
191
|
+
const result = { request, response };
|
|
177
192
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
193
|
+
if (response.ok) {
|
|
194
|
+
const data = await parseSuccess(response, opts, ofetchResponseType);
|
|
195
|
+
return wrapDataReturn(data, result, opts.responseStyle);
|
|
181
196
|
}
|
|
182
|
-
}
|
|
183
197
|
|
|
184
|
-
|
|
198
|
+
throw await parseError(response);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
let finalError = error;
|
|
185
201
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
202
|
+
for (const fn of interceptors.error.fns) {
|
|
203
|
+
if (fn) {
|
|
204
|
+
finalError = await fn(finalError, response, request, options as ResolvedRequestOptions);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
190
207
|
|
|
191
|
-
|
|
208
|
+
// ensure error is never undefined after interceptors
|
|
209
|
+
finalError = finalError || ({} as string);
|
|
192
210
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
finalError = await fn(finalError, response, request, opts);
|
|
211
|
+
if (throwOnError) {
|
|
212
|
+
throw finalError;
|
|
196
213
|
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// ensure error is never undefined after interceptors
|
|
200
|
-
finalError = (finalError as any) || ({} as string);
|
|
201
214
|
|
|
202
|
-
|
|
203
|
-
throw finalError;
|
|
215
|
+
return wrapErrorReturn(finalError, { request, response }, responseStyle) as any;
|
|
204
216
|
}
|
|
205
|
-
|
|
206
|
-
return wrapErrorReturn(finalError, result, opts.responseStyle) as any;
|
|
207
217
|
};
|
|
208
218
|
|
|
209
219
|
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
|
|
210
|
-
request({ ...options, method }
|
|
220
|
+
request({ ...options, method });
|
|
211
221
|
|
|
212
222
|
const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
|
|
213
223
|
const { networkBody, opts, url } = await resolveOptions(options);
|
|
214
|
-
const optsForSse
|
|
224
|
+
const optsForSse = { ...opts };
|
|
215
225
|
delete optsForSse.body; // body is provided via serializedBody below
|
|
216
226
|
return createSseClient({
|
|
217
|
-
...optsForSse,
|
|
227
|
+
...(optsForSse as Omit<typeof opts, 'body'>),
|
|
218
228
|
fetch: opts.fetch,
|
|
219
|
-
headers: opts.headers
|
|
229
|
+
headers: opts.headers,
|
|
220
230
|
method,
|
|
221
231
|
onRequest: async (url, init) => {
|
|
222
232
|
let request = new Request(url, init);
|
|
223
233
|
request = await applyRequestInterceptors(request, opts, networkBody);
|
|
224
234
|
return request;
|
|
225
235
|
},
|
|
226
|
-
serializedBody: networkBody
|
|
236
|
+
serializedBody: networkBody,
|
|
227
237
|
signal: opts.signal,
|
|
228
238
|
url,
|
|
229
239
|
});
|
|
@@ -188,8 +188,10 @@ export type RequestResult<
|
|
|
188
188
|
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
|
|
189
189
|
}
|
|
190
190
|
) & {
|
|
191
|
-
request
|
|
192
|
-
|
|
191
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
192
|
+
request?: Request;
|
|
193
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
194
|
+
response?: Response;
|
|
193
195
|
}
|
|
194
196
|
>;
|
|
195
197
|
|
|
@@ -277,7 +277,7 @@ export const wrapDataReturn = <T>(
|
|
|
277
277
|
*/
|
|
278
278
|
export const wrapErrorReturn = <E>(
|
|
279
279
|
error: E,
|
|
280
|
-
result: { request: Request; response: Response },
|
|
280
|
+
result: { request: Request | undefined; response: Response | undefined },
|
|
281
281
|
responseStyle: ResponseStyle | undefined,
|
|
282
282
|
):
|
|
283
283
|
| undefined
|
|
@@ -405,8 +405,10 @@ export const parseError = async (response: Response): Promise<unknown> => {
|
|
|
405
405
|
|
|
406
406
|
type ErrInterceptor<Err, Res, Req, Options> = (
|
|
407
407
|
error: Err,
|
|
408
|
-
response
|
|
409
|
-
|
|
408
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
409
|
+
response: Res | undefined,
|
|
410
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
411
|
+
request: Req | undefined,
|
|
410
412
|
options: Options,
|
|
411
413
|
) => Err | Promise<Err>;
|
|
412
414
|
|