@hey-api/openapi-ts 0.96.1 → 0.97.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/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 +645 -1080
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{init-D4xuNKgu.mjs → init-EigcXVTH.mjs} +344 -23
- package/dist/init-EigcXVTH.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-ErSC87Z1.mjs} +19 -10
- package/dist/src-ErSC87Z1.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
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ Start with our [Contributing](https://heyapi.dev/openapi-ts/community/contributi
|
|
|
55
55
|
|
|
56
56
|
## Sponsors
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
Partners behind the future of API tooling. [Become a sponsor](https://github.com/sponsors/hey-api).
|
|
59
59
|
|
|
60
60
|
<h3 align="center">Gold</h3>
|
|
61
61
|
|
|
@@ -85,7 +85,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
85
85
|
opts.headers.delete('Content-Type');
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const url = buildUrl(opts as
|
|
88
|
+
const url = buildUrl(opts as Config & RequestOptions);
|
|
89
89
|
|
|
90
90
|
const req = new HttpRequest<unknown>(opts.method ?? 'GET', url, getValidRequestBody(opts), {
|
|
91
91
|
redirect: 'follow',
|
|
@@ -120,34 +120,39 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
const request: Client['request'] = async (options) => {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
let req = initialReq;
|
|
126
|
-
|
|
127
|
-
for (const fn of interceptors.request.fns) {
|
|
128
|
-
if (fn) {
|
|
129
|
-
req = await fn(req, opts as any);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
123
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
124
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
132
125
|
|
|
133
126
|
const result: {
|
|
134
|
-
request
|
|
135
|
-
response
|
|
127
|
+
request?: HttpRequest<unknown>;
|
|
128
|
+
response?: any;
|
|
136
129
|
} = {
|
|
137
|
-
request:
|
|
138
|
-
response:
|
|
130
|
+
request: undefined,
|
|
131
|
+
response: undefined,
|
|
139
132
|
};
|
|
140
133
|
|
|
141
134
|
try {
|
|
142
|
-
|
|
135
|
+
const { opts, req: initialReq } = await beforeRequest(options);
|
|
136
|
+
|
|
137
|
+
let req = initialReq;
|
|
138
|
+
result.request = req;
|
|
139
|
+
|
|
140
|
+
for (const fn of interceptors.request.fns) {
|
|
141
|
+
if (fn) {
|
|
142
|
+
req = await fn(req, opts as ResolvedRequestOptions);
|
|
143
|
+
result.request = req;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
result.response = await firstValueFrom(
|
|
143
148
|
opts
|
|
144
149
|
.httpClient!.request(req)
|
|
145
150
|
.pipe(filter((event) => event.type === HttpEventType.Response)),
|
|
146
|
-
)
|
|
151
|
+
);
|
|
147
152
|
|
|
148
153
|
for (const fn of interceptors.response.fns) {
|
|
149
154
|
if (fn) {
|
|
150
|
-
result.response = await fn(result.response, req, opts as
|
|
155
|
+
result.response = await fn(result.response, req, opts as ResolvedRequestOptions);
|
|
151
156
|
}
|
|
152
157
|
}
|
|
153
158
|
|
|
@@ -171,15 +176,20 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
171
176
|
|
|
172
177
|
for (const fn of interceptors.error.fns) {
|
|
173
178
|
if (fn) {
|
|
174
|
-
finalError =
|
|
179
|
+
finalError = await fn(
|
|
180
|
+
finalError,
|
|
181
|
+
result.response,
|
|
182
|
+
result.request,
|
|
183
|
+
options as ResolvedRequestOptions,
|
|
184
|
+
);
|
|
175
185
|
}
|
|
176
186
|
}
|
|
177
187
|
|
|
178
|
-
if (
|
|
188
|
+
if (throwOnError) {
|
|
179
189
|
throw finalError;
|
|
180
190
|
}
|
|
181
191
|
|
|
182
|
-
return
|
|
192
|
+
return responseStyle === 'data'
|
|
183
193
|
? undefined
|
|
184
194
|
: {
|
|
185
195
|
error: finalError,
|
|
@@ -130,8 +130,10 @@ export type RequestResult<
|
|
|
130
130
|
| {
|
|
131
131
|
data: undefined;
|
|
132
132
|
error: TError[keyof TError];
|
|
133
|
-
request
|
|
134
|
-
|
|
133
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
134
|
+
request?: HttpRequest<unknown>;
|
|
135
|
+
/** response may be undefined, because error may be from building the request object itself or from a network error */
|
|
136
|
+
response?: HttpErrorResponse & {
|
|
135
137
|
error: TError[keyof TError] | null;
|
|
136
138
|
};
|
|
137
139
|
}
|
|
@@ -312,8 +312,10 @@ export const mergeHeaders = (
|
|
|
312
312
|
|
|
313
313
|
type ErrInterceptor<Err, Res, Req, Options> = (
|
|
314
314
|
error: Err,
|
|
315
|
-
response
|
|
316
|
-
|
|
315
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
316
|
+
response: Res | undefined,
|
|
317
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
318
|
+
request: Req | undefined,
|
|
317
319
|
options: Options,
|
|
318
320
|
) => Err | Promise<Err>;
|
|
319
321
|
|
|
@@ -73,171 +73,154 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
const request: Client['request'] = async (options) => {
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
redirect: 'follow',
|
|
79
|
-
...opts,
|
|
80
|
-
body: getValidRequestBody(opts),
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
let request = new Request(url, requestInit);
|
|
84
|
-
|
|
85
|
-
for (const fn of interceptors.request.fns) {
|
|
86
|
-
if (fn) {
|
|
87
|
-
request = await fn(request, opts);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
76
|
+
const throwOnError = options.throwOnError ?? _config.throwOnError;
|
|
77
|
+
const responseStyle = options.responseStyle ?? _config.responseStyle;
|
|
90
78
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const _fetch = opts.fetch!;
|
|
94
|
-
let response: Response;
|
|
79
|
+
let request: Request | undefined;
|
|
80
|
+
let response: Response | undefined;
|
|
95
81
|
|
|
96
82
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
const { opts, url } = await beforeRequest(options);
|
|
84
|
+
const requestInit: ReqInit = {
|
|
85
|
+
redirect: 'follow',
|
|
86
|
+
...opts,
|
|
87
|
+
body: getValidRequestBody(opts),
|
|
88
|
+
};
|
|
101
89
|
|
|
102
|
-
|
|
90
|
+
request = new Request(url, requestInit);
|
|
91
|
+
|
|
92
|
+
for (const fn of interceptors.request.fns) {
|
|
103
93
|
if (fn) {
|
|
104
|
-
|
|
94
|
+
request = await fn(request, opts);
|
|
105
95
|
}
|
|
106
96
|
}
|
|
107
97
|
|
|
108
|
-
|
|
98
|
+
// fetch must be assigned here, otherwise it would throw the error:
|
|
99
|
+
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
|
|
100
|
+
const _fetch = opts.fetch!;
|
|
109
101
|
|
|
110
|
-
|
|
111
|
-
throw finalError;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Return error response
|
|
115
|
-
return opts.responseStyle === 'data'
|
|
116
|
-
? undefined
|
|
117
|
-
: {
|
|
118
|
-
error: finalError,
|
|
119
|
-
request,
|
|
120
|
-
response: undefined as any,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
102
|
+
response = await _fetch(request);
|
|
123
103
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
104
|
+
for (const fn of interceptors.response.fns) {
|
|
105
|
+
if (fn) {
|
|
106
|
+
response = await fn(response, request, opts);
|
|
107
|
+
}
|
|
127
108
|
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const result = {
|
|
131
|
-
request,
|
|
132
|
-
response,
|
|
133
|
-
};
|
|
134
109
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
110
|
+
const result = {
|
|
111
|
+
request,
|
|
112
|
+
response,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (response.ok) {
|
|
116
|
+
const parseAs =
|
|
117
|
+
(opts.parseAs === 'auto'
|
|
118
|
+
? getParseAs(response.headers.get('Content-Type'))
|
|
119
|
+
: opts.parseAs) ?? 'json';
|
|
120
|
+
|
|
121
|
+
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
|
|
122
|
+
let emptyData: any;
|
|
123
|
+
switch (parseAs) {
|
|
124
|
+
case 'arrayBuffer':
|
|
125
|
+
case 'blob':
|
|
126
|
+
case 'text':
|
|
127
|
+
emptyData = await response[parseAs]();
|
|
128
|
+
break;
|
|
129
|
+
case 'formData':
|
|
130
|
+
emptyData = new FormData();
|
|
131
|
+
break;
|
|
132
|
+
case 'stream':
|
|
133
|
+
emptyData = response.body;
|
|
134
|
+
break;
|
|
135
|
+
case 'json':
|
|
136
|
+
default:
|
|
137
|
+
emptyData = {};
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
return opts.responseStyle === 'data'
|
|
141
|
+
? emptyData
|
|
142
|
+
: {
|
|
143
|
+
data: emptyData,
|
|
144
|
+
...result,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
140
147
|
|
|
141
|
-
|
|
142
|
-
let emptyData: any;
|
|
148
|
+
let data: any;
|
|
143
149
|
switch (parseAs) {
|
|
144
150
|
case 'arrayBuffer':
|
|
145
151
|
case 'blob':
|
|
152
|
+
case 'formData':
|
|
146
153
|
case 'text':
|
|
147
|
-
|
|
154
|
+
data = await response[parseAs]();
|
|
148
155
|
break;
|
|
149
|
-
case '
|
|
150
|
-
|
|
156
|
+
case 'json': {
|
|
157
|
+
// Some servers return 200 with no Content-Length and empty body.
|
|
158
|
+
// response.json() would throw; read as text and parse if non-empty.
|
|
159
|
+
const text = await response.text();
|
|
160
|
+
data = text ? JSON.parse(text) : {};
|
|
151
161
|
break;
|
|
162
|
+
}
|
|
152
163
|
case 'stream':
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
164
|
+
return opts.responseStyle === 'data'
|
|
165
|
+
? response.body
|
|
166
|
+
: {
|
|
167
|
+
data: response.body,
|
|
168
|
+
...result,
|
|
169
|
+
};
|
|
159
170
|
}
|
|
171
|
+
|
|
172
|
+
if (parseAs === 'json') {
|
|
173
|
+
if (opts.responseValidator) {
|
|
174
|
+
await opts.responseValidator(data);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (opts.responseTransformer) {
|
|
178
|
+
data = await opts.responseTransformer(data);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
160
182
|
return opts.responseStyle === 'data'
|
|
161
|
-
?
|
|
183
|
+
? data
|
|
162
184
|
: {
|
|
163
|
-
data
|
|
185
|
+
data,
|
|
164
186
|
...result,
|
|
165
187
|
};
|
|
166
188
|
}
|
|
167
189
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
break;
|
|
176
|
-
case 'json': {
|
|
177
|
-
// Some servers return 200 with no Content-Length and empty body.
|
|
178
|
-
// response.json() would throw; read as text and parse if non-empty.
|
|
179
|
-
const text = await response.text();
|
|
180
|
-
data = text ? JSON.parse(text) : {};
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
case 'stream':
|
|
184
|
-
return opts.responseStyle === 'data'
|
|
185
|
-
? response.body
|
|
186
|
-
: {
|
|
187
|
-
data: response.body,
|
|
188
|
-
...result,
|
|
189
|
-
};
|
|
190
|
+
const textError = await response.text();
|
|
191
|
+
let jsonError: unknown;
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
jsonError = JSON.parse(textError);
|
|
195
|
+
} catch {
|
|
196
|
+
// noop
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
199
|
+
throw jsonError ?? textError;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
let finalError = error;
|
|
196
202
|
|
|
197
|
-
|
|
198
|
-
|
|
203
|
+
for (const fn of interceptors.error.fns) {
|
|
204
|
+
if (fn) {
|
|
205
|
+
finalError = await fn(finalError, response, request, options as ResolvedRequestOptions);
|
|
199
206
|
}
|
|
200
207
|
}
|
|
201
208
|
|
|
202
|
-
|
|
203
|
-
? data
|
|
204
|
-
: {
|
|
205
|
-
data,
|
|
206
|
-
...result,
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const textError = await response.text();
|
|
211
|
-
let jsonError: unknown;
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
jsonError = JSON.parse(textError);
|
|
215
|
-
} catch {
|
|
216
|
-
// noop
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const error = jsonError ?? textError;
|
|
220
|
-
let finalError = error;
|
|
209
|
+
finalError = finalError || {};
|
|
221
210
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
finalError = (await fn(error, response, request, opts)) as string;
|
|
211
|
+
if (throwOnError) {
|
|
212
|
+
throw finalError;
|
|
225
213
|
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
finalError = finalError || ({} as string);
|
|
229
214
|
|
|
230
|
-
|
|
231
|
-
|
|
215
|
+
// TODO: we probably want to return error and improve types
|
|
216
|
+
return responseStyle === 'data'
|
|
217
|
+
? undefined
|
|
218
|
+
: {
|
|
219
|
+
error: finalError,
|
|
220
|
+
request,
|
|
221
|
+
response,
|
|
222
|
+
};
|
|
232
223
|
}
|
|
233
|
-
|
|
234
|
-
// TODO: we probably want to return error and improve types
|
|
235
|
-
return opts.responseStyle === 'data'
|
|
236
|
-
? undefined
|
|
237
|
-
: {
|
|
238
|
-
error: finalError,
|
|
239
|
-
...result,
|
|
240
|
-
};
|
|
241
224
|
};
|
|
242
225
|
|
|
243
226
|
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
|
|
@@ -248,7 +231,6 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
248
231
|
return createSseClient({
|
|
249
232
|
...opts,
|
|
250
233
|
body: opts.body as BodyInit | null | undefined,
|
|
251
|
-
headers: opts.headers as unknown as Record<string, string>,
|
|
252
234
|
method,
|
|
253
235
|
onRequest: async (url, init) => {
|
|
254
236
|
let request = new Request(url, init);
|
|
@@ -125,8 +125,10 @@ export type RequestResult<
|
|
|
125
125
|
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
|
|
126
126
|
}
|
|
127
127
|
) & {
|
|
128
|
-
request
|
|
129
|
-
|
|
128
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
129
|
+
request?: Request;
|
|
130
|
+
/** response may be undefined, because error may be from building the request object itself or from a network error */
|
|
131
|
+
response?: Response;
|
|
130
132
|
}
|
|
131
133
|
>;
|
|
132
134
|
|
|
@@ -216,8 +216,10 @@ export const mergeHeaders = (
|
|
|
216
216
|
|
|
217
217
|
type ErrInterceptor<Err, Res, Req, Options> = (
|
|
218
218
|
error: Err,
|
|
219
|
-
response
|
|
220
|
-
|
|
219
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
220
|
+
response: Res | undefined,
|
|
221
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
222
|
+
request: Req | undefined,
|
|
221
223
|
options: Options,
|
|
222
224
|
) => Err | Promise<Err>;
|
|
223
225
|
|