@hey-api/openapi-ts 0.83.1 → 0.84.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 +2 -1
- package/dist/chunk-TA6X5D7W.js +54 -0
- package/dist/chunk-TA6X5D7W.js.map +1 -0
- package/dist/clients/axios/client.ts +1 -1
- package/dist/clients/axios/types.ts +1 -1
- package/dist/clients/axios/utils.ts +11 -3
- package/dist/clients/ofetch/client.ts +272 -0
- package/dist/clients/ofetch/index.ts +23 -0
- package/dist/clients/ofetch/types.ts +333 -0
- package/dist/clients/ofetch/utils.ts +540 -0
- package/dist/index.cjs +42 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +308 -113
- package/dist/index.d.ts +308 -113
- package/dist/index.js +30 -33
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +23 -26
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +2 -2
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +1 -1
- package/dist/{types.d-CRtO-Prt.d.cts → types.d-DOXd97cA.d.cts} +2281 -2273
- package/dist/{types.d-CRtO-Prt.d.ts → types.d-DOXd97cA.d.ts} +2281 -2273
- package/package.json +12 -10
- package/dist/chunk-3AYBIZLR.js +0 -57
- package/dist/chunk-3AYBIZLR.js.map +0 -1
|
@@ -78,7 +78,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
78
78
|
const { auth, ...optsWithoutAuth } = opts;
|
|
79
79
|
const response = await _axios({
|
|
80
80
|
...optsWithoutAuth,
|
|
81
|
-
baseURL:
|
|
81
|
+
baseURL: '', // the baseURL is already included in `url`
|
|
82
82
|
data: getValidRequestBody(opts),
|
|
83
83
|
headers: opts.headers as RawAxiosRequestHeaders,
|
|
84
84
|
// let `paramsSerializer()` handle query params if it exists
|
|
@@ -123,9 +123,16 @@ export const setAuthParams = async ({
|
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
125
|
|
|
126
|
-
export const buildUrl: Client['buildUrl'] = (options) =>
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
export const buildUrl: Client['buildUrl'] = (options) => {
|
|
127
|
+
const instanceBaseUrl = options.axios?.defaults?.baseURL;
|
|
128
|
+
|
|
129
|
+
const baseUrl =
|
|
130
|
+
!!options.baseURL && typeof options.baseURL === 'string'
|
|
131
|
+
? options.baseURL
|
|
132
|
+
: instanceBaseUrl;
|
|
133
|
+
|
|
134
|
+
return getUrl({
|
|
135
|
+
baseUrl: baseUrl as string,
|
|
129
136
|
path: options.path,
|
|
130
137
|
// let `paramsSerializer()` handle query params if it exists
|
|
131
138
|
query: !options.paramsSerializer ? options.query : undefined,
|
|
@@ -135,6 +142,7 @@ export const buildUrl: Client['buildUrl'] = (options) =>
|
|
|
135
142
|
: createQuerySerializer(options.querySerializer),
|
|
136
143
|
url: options.url,
|
|
137
144
|
});
|
|
145
|
+
};
|
|
138
146
|
|
|
139
147
|
export const mergeConfigs = (a: Config, b: Config): Config => {
|
|
140
148
|
const config = { ...a, ...b };
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { ofetch, type ResponseType as OfetchResponseType } from 'ofetch';
|
|
2
|
+
|
|
3
|
+
import { createSseClient } from '../core/serverSentEvents';
|
|
4
|
+
import type { HttpMethod } from '../core/types';
|
|
5
|
+
import { getValidRequestBody } from '../core/utils';
|
|
6
|
+
import type {
|
|
7
|
+
Client,
|
|
8
|
+
Config,
|
|
9
|
+
RequestOptions,
|
|
10
|
+
ResolvedRequestOptions,
|
|
11
|
+
} from './types';
|
|
12
|
+
import {
|
|
13
|
+
buildOfetchOptions,
|
|
14
|
+
buildUrl,
|
|
15
|
+
createConfig,
|
|
16
|
+
createInterceptors,
|
|
17
|
+
isRepeatableBody,
|
|
18
|
+
mapParseAsToResponseType,
|
|
19
|
+
mergeConfigs,
|
|
20
|
+
mergeHeaders,
|
|
21
|
+
parseError,
|
|
22
|
+
parseSuccess,
|
|
23
|
+
setAuthParams,
|
|
24
|
+
wrapDataReturn,
|
|
25
|
+
wrapErrorReturn,
|
|
26
|
+
} from './utils';
|
|
27
|
+
|
|
28
|
+
type ReqInit = Omit<RequestInit, 'body' | 'headers'> & {
|
|
29
|
+
body?: BodyInit | null | undefined;
|
|
30
|
+
headers: ReturnType<typeof mergeHeaders>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const createClient = (config: Config = {}): Client => {
|
|
34
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
35
|
+
|
|
36
|
+
const getConfig = (): Config => ({ ..._config });
|
|
37
|
+
|
|
38
|
+
const setConfig = (config: Config): Config => {
|
|
39
|
+
_config = mergeConfigs(_config, config);
|
|
40
|
+
return getConfig();
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const interceptors = createInterceptors<
|
|
44
|
+
Request,
|
|
45
|
+
Response,
|
|
46
|
+
unknown,
|
|
47
|
+
ResolvedRequestOptions
|
|
48
|
+
>();
|
|
49
|
+
|
|
50
|
+
// precompute serialized / network body
|
|
51
|
+
const resolveOptions = async (options: RequestOptions) => {
|
|
52
|
+
const opts = {
|
|
53
|
+
..._config,
|
|
54
|
+
...options,
|
|
55
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
56
|
+
serializedBody: undefined,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
if (opts.security) {
|
|
60
|
+
await setAuthParams({
|
|
61
|
+
...opts,
|
|
62
|
+
security: opts.security,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (opts.requestValidator) {
|
|
67
|
+
await opts.requestValidator(opts);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (opts.body !== undefined && opts.bodySerializer) {
|
|
71
|
+
opts.serializedBody = opts.bodySerializer(opts.body);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// remove Content-Type if body is empty to avoid invalid requests
|
|
75
|
+
if (opts.body === undefined || opts.serializedBody === '') {
|
|
76
|
+
opts.headers.delete('Content-Type');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// if a raw body is provided (no serializer), adjust Content-Type only when it
|
|
80
|
+
// equals the default JSON value to better match the concrete body type
|
|
81
|
+
if (
|
|
82
|
+
opts.body !== undefined &&
|
|
83
|
+
opts.bodySerializer === null &&
|
|
84
|
+
(opts.headers.get('Content-Type') || '').toLowerCase() ===
|
|
85
|
+
'application/json'
|
|
86
|
+
) {
|
|
87
|
+
const b: unknown = opts.body;
|
|
88
|
+
if (typeof FormData !== 'undefined' && b instanceof FormData) {
|
|
89
|
+
// let the runtime set the multipart boundary
|
|
90
|
+
opts.headers.delete('Content-Type');
|
|
91
|
+
} else if (
|
|
92
|
+
typeof URLSearchParams !== 'undefined' &&
|
|
93
|
+
b instanceof URLSearchParams
|
|
94
|
+
) {
|
|
95
|
+
// standard urlencoded content type (+ charset)
|
|
96
|
+
opts.headers.set(
|
|
97
|
+
'Content-Type',
|
|
98
|
+
'application/x-www-form-urlencoded;charset=UTF-8',
|
|
99
|
+
);
|
|
100
|
+
} else if (typeof Blob !== 'undefined' && b instanceof Blob) {
|
|
101
|
+
const t = b.type?.trim();
|
|
102
|
+
if (t) {
|
|
103
|
+
opts.headers.set('Content-Type', t);
|
|
104
|
+
} else {
|
|
105
|
+
// unknown blob type: avoid sending a misleading JSON header
|
|
106
|
+
opts.headers.delete('Content-Type');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// precompute network body (stability for retries and interceptors)
|
|
112
|
+
const networkBody = getValidRequestBody(opts) as
|
|
113
|
+
| RequestInit['body']
|
|
114
|
+
| null
|
|
115
|
+
| undefined;
|
|
116
|
+
|
|
117
|
+
const url = buildUrl(opts);
|
|
118
|
+
|
|
119
|
+
return { networkBody, opts, url };
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// apply request interceptors and mirror header/method/signal back to opts
|
|
123
|
+
const applyRequestInterceptors = async (
|
|
124
|
+
request: Request,
|
|
125
|
+
opts: ResolvedRequestOptions,
|
|
126
|
+
) => {
|
|
127
|
+
for (const fn of interceptors.request.fns) {
|
|
128
|
+
if (fn) {
|
|
129
|
+
request = await fn(request, opts);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// reflect interceptor changes into opts used by the network layer
|
|
133
|
+
opts.headers = request.headers;
|
|
134
|
+
opts.method = request.method as Uppercase<HttpMethod>;
|
|
135
|
+
// ignore request.body changes to avoid turning serialized bodies into streams
|
|
136
|
+
// body comes only from getValidRequestBody(options)
|
|
137
|
+
// reflect signal if present
|
|
138
|
+
opts.signal = (request as any).signal as AbortSignal | undefined;
|
|
139
|
+
return request;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// build ofetch options with stable retry logic based on body repeatability
|
|
143
|
+
const buildNetworkOptions = (
|
|
144
|
+
opts: ResolvedRequestOptions,
|
|
145
|
+
body: BodyInit | null | undefined,
|
|
146
|
+
responseType: OfetchResponseType | undefined,
|
|
147
|
+
) => {
|
|
148
|
+
const effectiveRetry = isRepeatableBody(body)
|
|
149
|
+
? (opts.retry as any)
|
|
150
|
+
: (0 as any);
|
|
151
|
+
return buildOfetchOptions(opts, body, responseType, effectiveRetry);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const request: Client['request'] = async (options) => {
|
|
155
|
+
const {
|
|
156
|
+
networkBody: initialNetworkBody,
|
|
157
|
+
opts,
|
|
158
|
+
url,
|
|
159
|
+
} = await resolveOptions(options as any);
|
|
160
|
+
// map parseAs -> ofetch responseType once per request
|
|
161
|
+
const ofetchResponseType: OfetchResponseType | undefined =
|
|
162
|
+
mapParseAsToResponseType(opts.parseAs, opts.responseType);
|
|
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 as Headers,
|
|
171
|
+
method: opts.method,
|
|
172
|
+
redirect: 'follow',
|
|
173
|
+
signal: opts.signal,
|
|
174
|
+
};
|
|
175
|
+
let request = new Request(url, requestInit);
|
|
176
|
+
|
|
177
|
+
request = await applyRequestInterceptors(request, opts);
|
|
178
|
+
const finalUrl = request.url;
|
|
179
|
+
|
|
180
|
+
// build ofetch options and perform the request (.raw keeps the Response)
|
|
181
|
+
const responseOptions = buildNetworkOptions(
|
|
182
|
+
opts as ResolvedRequestOptions,
|
|
183
|
+
networkBody,
|
|
184
|
+
ofetchResponseType,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
let response = await $ofetch.raw(finalUrl, responseOptions);
|
|
188
|
+
|
|
189
|
+
for (const fn of interceptors.response.fns) {
|
|
190
|
+
if (fn) {
|
|
191
|
+
response = await fn(response, request, opts);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const result = { request, response };
|
|
196
|
+
|
|
197
|
+
if (response.ok) {
|
|
198
|
+
const data = await parseSuccess(response, opts, ofetchResponseType);
|
|
199
|
+
return wrapDataReturn(data, result, opts.responseStyle);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
let finalError = await parseError(response);
|
|
203
|
+
|
|
204
|
+
for (const fn of interceptors.error.fns) {
|
|
205
|
+
if (fn) {
|
|
206
|
+
finalError = await fn(finalError, response, request, opts);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ensure error is never undefined after interceptors
|
|
211
|
+
finalError = (finalError as any) || ({} as string);
|
|
212
|
+
|
|
213
|
+
if (opts.throwOnError) {
|
|
214
|
+
throw finalError;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return wrapErrorReturn(finalError, result, opts.responseStyle) as any;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const makeMethodFn =
|
|
221
|
+
(method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
|
|
222
|
+
request({ ...options, method } as any);
|
|
223
|
+
|
|
224
|
+
const makeSseFn =
|
|
225
|
+
(method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
|
|
226
|
+
const { networkBody, opts, url } = await resolveOptions(options);
|
|
227
|
+
const optsForSse: any = { ...opts };
|
|
228
|
+
delete optsForSse.body; // body is provided via serializedBody below
|
|
229
|
+
return createSseClient({
|
|
230
|
+
...optsForSse,
|
|
231
|
+
fetch: opts.fetch,
|
|
232
|
+
headers: opts.headers as Headers,
|
|
233
|
+
method,
|
|
234
|
+
onRequest: async (url, init) => {
|
|
235
|
+
let request = new Request(url, init);
|
|
236
|
+
request = await applyRequestInterceptors(request, opts);
|
|
237
|
+
return request;
|
|
238
|
+
},
|
|
239
|
+
serializedBody: networkBody as BodyInit | null | undefined,
|
|
240
|
+
signal: opts.signal,
|
|
241
|
+
url,
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
buildUrl,
|
|
247
|
+
connect: makeMethodFn('CONNECT'),
|
|
248
|
+
delete: makeMethodFn('DELETE'),
|
|
249
|
+
get: makeMethodFn('GET'),
|
|
250
|
+
getConfig,
|
|
251
|
+
head: makeMethodFn('HEAD'),
|
|
252
|
+
interceptors,
|
|
253
|
+
options: makeMethodFn('OPTIONS'),
|
|
254
|
+
patch: makeMethodFn('PATCH'),
|
|
255
|
+
post: makeMethodFn('POST'),
|
|
256
|
+
put: makeMethodFn('PUT'),
|
|
257
|
+
request,
|
|
258
|
+
setConfig,
|
|
259
|
+
sse: {
|
|
260
|
+
connect: makeSseFn('CONNECT'),
|
|
261
|
+
delete: makeSseFn('DELETE'),
|
|
262
|
+
get: makeSseFn('GET'),
|
|
263
|
+
head: makeSseFn('HEAD'),
|
|
264
|
+
options: makeSseFn('OPTIONS'),
|
|
265
|
+
patch: makeSseFn('PATCH'),
|
|
266
|
+
post: makeSseFn('POST'),
|
|
267
|
+
put: makeSseFn('PUT'),
|
|
268
|
+
trace: makeSseFn('TRACE'),
|
|
269
|
+
},
|
|
270
|
+
trace: makeMethodFn('TRACE'),
|
|
271
|
+
} as Client;
|
|
272
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type { Auth } from '../core/auth';
|
|
2
|
+
export type { QuerySerializerOptions } from '../core/bodySerializer';
|
|
3
|
+
export {
|
|
4
|
+
formDataBodySerializer,
|
|
5
|
+
jsonBodySerializer,
|
|
6
|
+
urlSearchParamsBodySerializer,
|
|
7
|
+
} from '../core/bodySerializer';
|
|
8
|
+
export { buildClientParams } from '../core/params';
|
|
9
|
+
export { createClient } from './client';
|
|
10
|
+
export type {
|
|
11
|
+
Client,
|
|
12
|
+
ClientOptions,
|
|
13
|
+
Config,
|
|
14
|
+
CreateClientConfig,
|
|
15
|
+
Options,
|
|
16
|
+
OptionsLegacyParser,
|
|
17
|
+
RequestOptions,
|
|
18
|
+
RequestResult,
|
|
19
|
+
ResolvedRequestOptions,
|
|
20
|
+
ResponseStyle,
|
|
21
|
+
TDataShape,
|
|
22
|
+
} from './types';
|
|
23
|
+
export { createConfig, mergeHeaders } from './utils';
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FetchOptions as OfetchOptions,
|
|
3
|
+
ResponseType as OfetchResponseType,
|
|
4
|
+
} from 'ofetch';
|
|
5
|
+
import type { ofetch } from 'ofetch';
|
|
6
|
+
|
|
7
|
+
import type { Auth } from '../core/auth';
|
|
8
|
+
import type {
|
|
9
|
+
ServerSentEventsOptions,
|
|
10
|
+
ServerSentEventsResult,
|
|
11
|
+
} from '../core/serverSentEvents';
|
|
12
|
+
import type {
|
|
13
|
+
Client as CoreClient,
|
|
14
|
+
Config as CoreConfig,
|
|
15
|
+
} from '../core/types';
|
|
16
|
+
import type { Middleware } from './utils';
|
|
17
|
+
|
|
18
|
+
export type ResponseStyle = 'data' | 'fields';
|
|
19
|
+
|
|
20
|
+
export interface Config<T extends ClientOptions = ClientOptions>
|
|
21
|
+
extends Omit<RequestInit, 'body' | 'headers' | 'method'>,
|
|
22
|
+
CoreConfig {
|
|
23
|
+
/**
|
|
24
|
+
* HTTP(S) agent configuration (Node.js only). Passed through to ofetch.
|
|
25
|
+
*/
|
|
26
|
+
agent?: OfetchOptions['agent'];
|
|
27
|
+
/**
|
|
28
|
+
* Base URL for all requests made by this client.
|
|
29
|
+
*/
|
|
30
|
+
baseUrl?: T['baseUrl'];
|
|
31
|
+
/**
|
|
32
|
+
* Node-only proxy/agent options.
|
|
33
|
+
*/
|
|
34
|
+
dispatcher?: OfetchOptions['dispatcher'];
|
|
35
|
+
/**
|
|
36
|
+
* Fetch API implementation. Used for SSE streaming. You can use this option
|
|
37
|
+
* to provide a custom fetch instance.
|
|
38
|
+
*
|
|
39
|
+
* @default globalThis.fetch
|
|
40
|
+
*/
|
|
41
|
+
fetch?: typeof fetch;
|
|
42
|
+
/**
|
|
43
|
+
* Controls the native ofetch behaviour that throws `FetchError` when
|
|
44
|
+
* `response.ok === false`. We default to suppressing it to match the fetch
|
|
45
|
+
* client semantics and let `throwOnError` drive the outcome.
|
|
46
|
+
*/
|
|
47
|
+
ignoreResponseError?: OfetchOptions['ignoreResponseError'];
|
|
48
|
+
// No custom fetch option: provide custom instance via `ofetch` instead
|
|
49
|
+
/**
|
|
50
|
+
* Please don't use the Fetch client for Next.js applications. The `next`
|
|
51
|
+
* options won't have any effect.
|
|
52
|
+
*
|
|
53
|
+
* Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
|
|
54
|
+
*/
|
|
55
|
+
next?: never;
|
|
56
|
+
/**
|
|
57
|
+
* Custom ofetch instance created via `ofetch.create()`. If provided, it will
|
|
58
|
+
* be used for requests instead of the default `ofetch` export.
|
|
59
|
+
*/
|
|
60
|
+
ofetch?: typeof ofetch;
|
|
61
|
+
/**
|
|
62
|
+
* ofetch hook called before a request is sent.
|
|
63
|
+
*/
|
|
64
|
+
onRequest?: OfetchOptions['onRequest'];
|
|
65
|
+
/**
|
|
66
|
+
* ofetch hook called when a request fails before receiving a response
|
|
67
|
+
* (e.g., network errors or aborted requests).
|
|
68
|
+
*/
|
|
69
|
+
onRequestError?: OfetchOptions['onRequestError'];
|
|
70
|
+
/**
|
|
71
|
+
* ofetch hook called after a successful response is received and parsed.
|
|
72
|
+
*/
|
|
73
|
+
onResponse?: OfetchOptions['onResponse'];
|
|
74
|
+
/**
|
|
75
|
+
* ofetch hook called when the response indicates an error (non-ok status)
|
|
76
|
+
* or when response parsing fails.
|
|
77
|
+
*/
|
|
78
|
+
onResponseError?: OfetchOptions['onResponseError'];
|
|
79
|
+
/**
|
|
80
|
+
* Return the response data parsed in a specified format. By default, `auto`
|
|
81
|
+
* will infer the appropriate method from the `Content-Type` response header.
|
|
82
|
+
* You can override this behavior with any of the {@link Body} methods.
|
|
83
|
+
* Select `stream` if you don't want to parse response data at all.
|
|
84
|
+
*
|
|
85
|
+
* @default 'auto'
|
|
86
|
+
*/
|
|
87
|
+
parseAs?:
|
|
88
|
+
| 'arrayBuffer'
|
|
89
|
+
| 'auto'
|
|
90
|
+
| 'blob'
|
|
91
|
+
| 'formData'
|
|
92
|
+
| 'json'
|
|
93
|
+
| 'stream'
|
|
94
|
+
| 'text';
|
|
95
|
+
/** Custom response parser (ofetch). */
|
|
96
|
+
parseResponse?: OfetchOptions['parseResponse'];
|
|
97
|
+
/**
|
|
98
|
+
* Should we return only data or multiple fields (data, error, response, etc.)?
|
|
99
|
+
*
|
|
100
|
+
* @default 'fields'
|
|
101
|
+
*/
|
|
102
|
+
responseStyle?: ResponseStyle;
|
|
103
|
+
/**
|
|
104
|
+
* ofetch responseType override. If provided, it will be passed directly to
|
|
105
|
+
* ofetch and take precedence over `parseAs`.
|
|
106
|
+
*/
|
|
107
|
+
responseType?: OfetchResponseType;
|
|
108
|
+
/**
|
|
109
|
+
* Automatically retry failed requests.
|
|
110
|
+
*/
|
|
111
|
+
retry?: OfetchOptions['retry'];
|
|
112
|
+
/**
|
|
113
|
+
* Delay (in ms) between retry attempts.
|
|
114
|
+
*/
|
|
115
|
+
retryDelay?: OfetchOptions['retryDelay'];
|
|
116
|
+
/**
|
|
117
|
+
* HTTP status codes that should trigger a retry.
|
|
118
|
+
*/
|
|
119
|
+
retryStatusCodes?: OfetchOptions['retryStatusCodes'];
|
|
120
|
+
/**
|
|
121
|
+
* Throw an error instead of returning it in the response?
|
|
122
|
+
*
|
|
123
|
+
* @default false
|
|
124
|
+
*/
|
|
125
|
+
throwOnError?: T['throwOnError'];
|
|
126
|
+
/**
|
|
127
|
+
* Abort the request after the given milliseconds.
|
|
128
|
+
*/
|
|
129
|
+
timeout?: number;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface RequestOptions<
|
|
133
|
+
TData = unknown,
|
|
134
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
135
|
+
ThrowOnError extends boolean = boolean,
|
|
136
|
+
Url extends string = string,
|
|
137
|
+
> extends Config<{
|
|
138
|
+
responseStyle: TResponseStyle;
|
|
139
|
+
throwOnError: ThrowOnError;
|
|
140
|
+
}>,
|
|
141
|
+
Pick<
|
|
142
|
+
ServerSentEventsOptions<TData>,
|
|
143
|
+
| 'onSseError'
|
|
144
|
+
| 'onSseEvent'
|
|
145
|
+
| 'sseDefaultRetryDelay'
|
|
146
|
+
| 'sseMaxRetryAttempts'
|
|
147
|
+
| 'sseMaxRetryDelay'
|
|
148
|
+
> {
|
|
149
|
+
/**
|
|
150
|
+
* Any body that you want to add to your request.
|
|
151
|
+
*
|
|
152
|
+
* {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
|
|
153
|
+
*/
|
|
154
|
+
body?: unknown;
|
|
155
|
+
path?: Record<string, unknown>;
|
|
156
|
+
query?: Record<string, unknown>;
|
|
157
|
+
/**
|
|
158
|
+
* Security mechanism(s) to use for the request.
|
|
159
|
+
*/
|
|
160
|
+
security?: ReadonlyArray<Auth>;
|
|
161
|
+
url: Url;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface ResolvedRequestOptions<
|
|
165
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
166
|
+
ThrowOnError extends boolean = boolean,
|
|
167
|
+
Url extends string = string,
|
|
168
|
+
> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
|
|
169
|
+
serializedBody?: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export type RequestResult<
|
|
173
|
+
TData = unknown,
|
|
174
|
+
TError = unknown,
|
|
175
|
+
ThrowOnError extends boolean = boolean,
|
|
176
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
177
|
+
> = ThrowOnError extends true
|
|
178
|
+
? Promise<
|
|
179
|
+
TResponseStyle extends 'data'
|
|
180
|
+
? TData extends Record<string, unknown>
|
|
181
|
+
? TData[keyof TData]
|
|
182
|
+
: TData
|
|
183
|
+
: {
|
|
184
|
+
data: TData extends Record<string, unknown>
|
|
185
|
+
? TData[keyof TData]
|
|
186
|
+
: TData;
|
|
187
|
+
request: Request;
|
|
188
|
+
response: Response;
|
|
189
|
+
}
|
|
190
|
+
>
|
|
191
|
+
: Promise<
|
|
192
|
+
TResponseStyle extends 'data'
|
|
193
|
+
?
|
|
194
|
+
| (TData extends Record<string, unknown>
|
|
195
|
+
? TData[keyof TData]
|
|
196
|
+
: TData)
|
|
197
|
+
| undefined
|
|
198
|
+
: (
|
|
199
|
+
| {
|
|
200
|
+
data: TData extends Record<string, unknown>
|
|
201
|
+
? TData[keyof TData]
|
|
202
|
+
: TData;
|
|
203
|
+
error: undefined;
|
|
204
|
+
}
|
|
205
|
+
| {
|
|
206
|
+
data: undefined;
|
|
207
|
+
error: TError extends Record<string, unknown>
|
|
208
|
+
? TError[keyof TError]
|
|
209
|
+
: TError;
|
|
210
|
+
}
|
|
211
|
+
) & {
|
|
212
|
+
request: Request;
|
|
213
|
+
response: Response;
|
|
214
|
+
}
|
|
215
|
+
>;
|
|
216
|
+
|
|
217
|
+
export interface ClientOptions {
|
|
218
|
+
baseUrl?: string;
|
|
219
|
+
responseStyle?: ResponseStyle;
|
|
220
|
+
throwOnError?: boolean;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
type MethodFn = <
|
|
224
|
+
TData = unknown,
|
|
225
|
+
TError = unknown,
|
|
226
|
+
ThrowOnError extends boolean = false,
|
|
227
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
228
|
+
>(
|
|
229
|
+
options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>,
|
|
230
|
+
) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
|
|
231
|
+
|
|
232
|
+
type SseFn = <
|
|
233
|
+
TData = unknown,
|
|
234
|
+
TError = unknown,
|
|
235
|
+
ThrowOnError extends boolean = false,
|
|
236
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
237
|
+
>(
|
|
238
|
+
options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>,
|
|
239
|
+
) => Promise<ServerSentEventsResult<TData, TError>>;
|
|
240
|
+
|
|
241
|
+
type RequestFn = <
|
|
242
|
+
TData = unknown,
|
|
243
|
+
TError = unknown,
|
|
244
|
+
ThrowOnError extends boolean = false,
|
|
245
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
246
|
+
>(
|
|
247
|
+
options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> &
|
|
248
|
+
Pick<
|
|
249
|
+
Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>,
|
|
250
|
+
'method'
|
|
251
|
+
>,
|
|
252
|
+
) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
|
|
253
|
+
|
|
254
|
+
type BuildUrlFn = <
|
|
255
|
+
TData extends {
|
|
256
|
+
body?: unknown;
|
|
257
|
+
path?: Record<string, unknown>;
|
|
258
|
+
query?: Record<string, unknown>;
|
|
259
|
+
url: string;
|
|
260
|
+
},
|
|
261
|
+
>(
|
|
262
|
+
options: Pick<TData, 'url'> & Options<TData>,
|
|
263
|
+
) => string;
|
|
264
|
+
|
|
265
|
+
export type Client = CoreClient<
|
|
266
|
+
RequestFn,
|
|
267
|
+
Config,
|
|
268
|
+
MethodFn,
|
|
269
|
+
BuildUrlFn,
|
|
270
|
+
SseFn
|
|
271
|
+
> & {
|
|
272
|
+
interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* The `createClientConfig()` function will be called on client initialization
|
|
277
|
+
* and the returned object will become the client's initial configuration.
|
|
278
|
+
*
|
|
279
|
+
* You may want to initialize your client this way instead of calling
|
|
280
|
+
* `setConfig()`. This is useful for example if you're using Next.js
|
|
281
|
+
* to ensure your client always has the correct values.
|
|
282
|
+
*/
|
|
283
|
+
export type CreateClientConfig<T extends ClientOptions = ClientOptions> = (
|
|
284
|
+
override?: Config<ClientOptions & T>,
|
|
285
|
+
) => Config<Required<ClientOptions> & T>;
|
|
286
|
+
|
|
287
|
+
export interface TDataShape {
|
|
288
|
+
body?: unknown;
|
|
289
|
+
headers?: unknown;
|
|
290
|
+
path?: unknown;
|
|
291
|
+
query?: unknown;
|
|
292
|
+
url: string;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
|
|
296
|
+
|
|
297
|
+
export type Options<
|
|
298
|
+
TData extends TDataShape = TDataShape,
|
|
299
|
+
ThrowOnError extends boolean = boolean,
|
|
300
|
+
TResponse = unknown,
|
|
301
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
302
|
+
> = OmitKeys<
|
|
303
|
+
RequestOptions<TResponse, TResponseStyle, ThrowOnError>,
|
|
304
|
+
'body' | 'path' | 'query' | 'url'
|
|
305
|
+
> &
|
|
306
|
+
Omit<TData, 'url'>;
|
|
307
|
+
|
|
308
|
+
export type OptionsLegacyParser<
|
|
309
|
+
TData = unknown,
|
|
310
|
+
ThrowOnError extends boolean = boolean,
|
|
311
|
+
TResponseStyle extends ResponseStyle = 'fields',
|
|
312
|
+
> = TData extends { body?: any }
|
|
313
|
+
? TData extends { headers?: any }
|
|
314
|
+
? OmitKeys<
|
|
315
|
+
RequestOptions<unknown, TResponseStyle, ThrowOnError>,
|
|
316
|
+
'body' | 'headers' | 'url'
|
|
317
|
+
> &
|
|
318
|
+
TData
|
|
319
|
+
: OmitKeys<
|
|
320
|
+
RequestOptions<unknown, TResponseStyle, ThrowOnError>,
|
|
321
|
+
'body' | 'url'
|
|
322
|
+
> &
|
|
323
|
+
TData &
|
|
324
|
+
Pick<RequestOptions<unknown, TResponseStyle, ThrowOnError>, 'headers'>
|
|
325
|
+
: TData extends { headers?: any }
|
|
326
|
+
? OmitKeys<
|
|
327
|
+
RequestOptions<unknown, TResponseStyle, ThrowOnError>,
|
|
328
|
+
'headers' | 'url'
|
|
329
|
+
> &
|
|
330
|
+
TData &
|
|
331
|
+
Pick<RequestOptions<unknown, TResponseStyle, ThrowOnError>, 'body'>
|
|
332
|
+
: OmitKeys<RequestOptions<unknown, TResponseStyle, ThrowOnError>, 'url'> &
|
|
333
|
+
TData;
|