@hey-api/openapi-ts 0.91.0 → 0.92.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 +7 -7
- package/dist/clients/angular/client.ts +23 -49
- package/dist/clients/angular/types.ts +11 -34
- package/dist/clients/angular/utils.ts +6 -22
- package/dist/clients/axios/client.ts +16 -27
- package/dist/clients/axios/types.ts +17 -54
- package/dist/clients/axios/utils.ts +3 -8
- package/dist/clients/core/auth.ts +1 -2
- package/dist/clients/core/bodySerializer.ts +5 -21
- package/dist/clients/core/params.ts +3 -10
- package/dist/clients/core/pathSerializer.ts +4 -14
- package/dist/clients/core/queryKeySerializer.ts +6 -25
- package/dist/clients/core/serverSentEvents.ts +8 -31
- package/dist/clients/core/types.ts +4 -18
- package/dist/clients/core/utils.ts +1 -4
- package/dist/clients/fetch/client.ts +25 -48
- package/dist/clients/fetch/types.ts +12 -40
- package/dist/clients/fetch/utils.ts +6 -22
- package/dist/clients/ky/client.ts +27 -58
- package/dist/clients/ky/types.ts +14 -45
- package/dist/clients/ky/utils.ts +6 -22
- package/dist/clients/next/client.ts +30 -47
- package/dist/clients/next/types.ts +13 -47
- package/dist/clients/next/utils.ts +8 -31
- package/dist/clients/nuxt/client.ts +18 -37
- package/dist/clients/nuxt/types.ts +12 -31
- package/dist/clients/nuxt/utils.ts +5 -17
- package/dist/clients/ofetch/client.ts +34 -60
- package/dist/clients/ofetch/types.ts +13 -44
- package/dist/clients/ofetch/utils.ts +20 -58
- package/dist/index.d.mts +289 -452
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{init-kvO44gnv.mjs → init-DlaW5Djq.mjs} +355 -86
- package/dist/init-DlaW5Djq.mjs.map +1 -0
- package/dist/internal.mjs +1 -1
- package/dist/run.mjs +3 -3
- package/dist/run.mjs.map +1 -1
- package/dist/{src-Dmlg6WRV.mjs → src-BYA2YioO.mjs} +5 -8
- package/dist/src-BYA2YioO.mjs.map +1 -0
- package/dist/types-Ba27ofyy.d.mts.map +1 -1
- package/package.json +36 -37
- package/dist/init-kvO44gnv.mjs.map +0 -1
- package/dist/src-Dmlg6WRV.mjs.map +0 -1
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
interface SerializeOptions<T>
|
|
2
|
-
extends SerializePrimitiveOptions,
|
|
3
|
-
SerializerOptions<T> {}
|
|
1
|
+
interface SerializeOptions<T> extends SerializePrimitiveOptions, SerializerOptions<T> {}
|
|
4
2
|
|
|
5
3
|
interface SerializePrimitiveOptions {
|
|
6
4
|
allowReserved?: boolean;
|
|
@@ -103,9 +101,7 @@ export const serializeArrayParam = ({
|
|
|
103
101
|
});
|
|
104
102
|
})
|
|
105
103
|
.join(separator);
|
|
106
|
-
return style === 'label' || style === 'matrix'
|
|
107
|
-
? separator + joinedValues
|
|
108
|
-
: joinedValues;
|
|
104
|
+
return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
|
|
109
105
|
};
|
|
110
106
|
|
|
111
107
|
export const serializePrimitiveParam = ({
|
|
@@ -144,11 +140,7 @@ export const serializeObjectParam = ({
|
|
|
144
140
|
if (style !== 'deepObject' && !explode) {
|
|
145
141
|
let values: string[] = [];
|
|
146
142
|
Object.entries(value).forEach(([key, v]) => {
|
|
147
|
-
values = [
|
|
148
|
-
...values,
|
|
149
|
-
key,
|
|
150
|
-
allowReserved ? (v as string) : encodeURIComponent(v as string),
|
|
151
|
-
];
|
|
143
|
+
values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)];
|
|
152
144
|
});
|
|
153
145
|
const joinedValues = values.join(',');
|
|
154
146
|
switch (style) {
|
|
@@ -173,7 +165,5 @@ export const serializeObjectParam = ({
|
|
|
173
165
|
}),
|
|
174
166
|
)
|
|
175
167
|
.join(separator);
|
|
176
|
-
return style === 'label' || style === 'matrix'
|
|
177
|
-
? separator + joinedValues
|
|
178
|
-
: joinedValues;
|
|
168
|
+
return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues;
|
|
179
169
|
};
|
|
@@ -13,11 +13,7 @@ export type JsonValue =
|
|
|
13
13
|
* Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes.
|
|
14
14
|
*/
|
|
15
15
|
export const queryKeyJsonReplacer = (_key: string, value: unknown) => {
|
|
16
|
-
if (
|
|
17
|
-
value === undefined ||
|
|
18
|
-
typeof value === 'function' ||
|
|
19
|
-
typeof value === 'symbol'
|
|
20
|
-
) {
|
|
16
|
+
if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
|
|
21
17
|
return undefined;
|
|
22
18
|
}
|
|
23
19
|
if (typeof value === 'bigint') {
|
|
@@ -59,9 +55,7 @@ const isPlainObject = (value: unknown): value is Record<string, unknown> => {
|
|
|
59
55
|
* Turns URLSearchParams into a sorted JSON object for deterministic keys.
|
|
60
56
|
*/
|
|
61
57
|
const serializeSearchParams = (params: URLSearchParams): JsonValue => {
|
|
62
|
-
const entries = Array.from(params.entries()).sort(([a], [b]) =>
|
|
63
|
-
a.localeCompare(b),
|
|
64
|
-
);
|
|
58
|
+
const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b));
|
|
65
59
|
const result: Record<string, JsonValue> = {};
|
|
66
60
|
|
|
67
61
|
for (const [key, value] of entries) {
|
|
@@ -84,26 +78,16 @@ const serializeSearchParams = (params: URLSearchParams): JsonValue => {
|
|
|
84
78
|
/**
|
|
85
79
|
* Normalizes any accepted value into a JSON-friendly shape for query keys.
|
|
86
80
|
*/
|
|
87
|
-
export const serializeQueryKeyValue = (
|
|
88
|
-
value: unknown,
|
|
89
|
-
): JsonValue | undefined => {
|
|
81
|
+
export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => {
|
|
90
82
|
if (value === null) {
|
|
91
83
|
return null;
|
|
92
84
|
}
|
|
93
85
|
|
|
94
|
-
if (
|
|
95
|
-
typeof value === 'string' ||
|
|
96
|
-
typeof value === 'number' ||
|
|
97
|
-
typeof value === 'boolean'
|
|
98
|
-
) {
|
|
86
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
99
87
|
return value;
|
|
100
88
|
}
|
|
101
89
|
|
|
102
|
-
if (
|
|
103
|
-
value === undefined ||
|
|
104
|
-
typeof value === 'function' ||
|
|
105
|
-
typeof value === 'symbol'
|
|
106
|
-
) {
|
|
90
|
+
if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
|
|
107
91
|
return undefined;
|
|
108
92
|
}
|
|
109
93
|
|
|
@@ -119,10 +103,7 @@ export const serializeQueryKeyValue = (
|
|
|
119
103
|
return stringifyToJsonValue(value);
|
|
120
104
|
}
|
|
121
105
|
|
|
122
|
-
if (
|
|
123
|
-
typeof URLSearchParams !== 'undefined' &&
|
|
124
|
-
value instanceof URLSearchParams
|
|
125
|
-
) {
|
|
106
|
+
if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) {
|
|
126
107
|
return serializeSearchParams(value);
|
|
127
108
|
}
|
|
128
109
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { Config } from './types';
|
|
2
2
|
|
|
3
|
-
export type ServerSentEventsOptions<TData = unknown> = Omit<
|
|
4
|
-
RequestInit,
|
|
5
|
-
'method'
|
|
6
|
-
> &
|
|
3
|
+
export type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> &
|
|
7
4
|
Pick<Config, 'method' | 'responseTransformer' | 'responseValidator'> & {
|
|
8
5
|
/**
|
|
9
6
|
* Fetch API implementation. You can use this option to provide a custom
|
|
@@ -72,11 +69,7 @@ export interface StreamEvent<TData = unknown> {
|
|
|
72
69
|
retry?: number;
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
export type ServerSentEventsResult<
|
|
76
|
-
TData = unknown,
|
|
77
|
-
TReturn = void,
|
|
78
|
-
TNext = unknown,
|
|
79
|
-
> = {
|
|
72
|
+
export type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
|
|
80
73
|
stream: AsyncGenerator<
|
|
81
74
|
TData extends Record<string, unknown> ? TData[keyof TData] : TData,
|
|
82
75
|
TReturn,
|
|
@@ -99,9 +92,7 @@ export const createSseClient = <TData = unknown>({
|
|
|
99
92
|
}: ServerSentEventsOptions): ServerSentEventsResult<TData> => {
|
|
100
93
|
let lastEventId: string | undefined;
|
|
101
94
|
|
|
102
|
-
const sleep =
|
|
103
|
-
sseSleepFn ??
|
|
104
|
-
((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
95
|
+
const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
105
96
|
|
|
106
97
|
const createStream = async function* () {
|
|
107
98
|
let retryDelay: number = sseDefaultRetryDelay ?? 3000;
|
|
@@ -139,16 +130,11 @@ export const createSseClient = <TData = unknown>({
|
|
|
139
130
|
const _fetch = options.fetch ?? globalThis.fetch;
|
|
140
131
|
const response = await _fetch(request);
|
|
141
132
|
|
|
142
|
-
if (!response.ok)
|
|
143
|
-
throw new Error(
|
|
144
|
-
`SSE failed: ${response.status} ${response.statusText}`,
|
|
145
|
-
);
|
|
133
|
+
if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
|
|
146
134
|
|
|
147
135
|
if (!response.body) throw new Error('No body in SSE response');
|
|
148
136
|
|
|
149
|
-
const reader = response.body
|
|
150
|
-
.pipeThrough(new TextDecoderStream())
|
|
151
|
-
.getReader();
|
|
137
|
+
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
152
138
|
|
|
153
139
|
let buffer = '';
|
|
154
140
|
|
|
@@ -186,10 +172,7 @@ export const createSseClient = <TData = unknown>({
|
|
|
186
172
|
} else if (line.startsWith('id:')) {
|
|
187
173
|
lastEventId = line.replace(/^id:\s*/, '');
|
|
188
174
|
} else if (line.startsWith('retry:')) {
|
|
189
|
-
const parsed = Number.parseInt(
|
|
190
|
-
line.replace(/^retry:\s*/, ''),
|
|
191
|
-
10,
|
|
192
|
-
);
|
|
175
|
+
const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10);
|
|
193
176
|
if (!Number.isNaN(parsed)) {
|
|
194
177
|
retryDelay = parsed;
|
|
195
178
|
}
|
|
@@ -241,18 +224,12 @@ export const createSseClient = <TData = unknown>({
|
|
|
241
224
|
// connection failed or aborted; retry after delay
|
|
242
225
|
onSseError?.(error);
|
|
243
226
|
|
|
244
|
-
if (
|
|
245
|
-
sseMaxRetryAttempts !== undefined &&
|
|
246
|
-
attempt >= sseMaxRetryAttempts
|
|
247
|
-
) {
|
|
227
|
+
if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) {
|
|
248
228
|
break; // stop after firing error
|
|
249
229
|
}
|
|
250
230
|
|
|
251
231
|
// exponential backoff: double retry each attempt, cap at 30s
|
|
252
|
-
const backoff = Math.min(
|
|
253
|
-
retryDelay * 2 ** (attempt - 1),
|
|
254
|
-
sseMaxRetryDelay ?? 30000,
|
|
255
|
-
);
|
|
232
|
+
const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000);
|
|
256
233
|
await sleep(backoff);
|
|
257
234
|
}
|
|
258
235
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type { Auth, AuthToken } from './auth';
|
|
2
|
-
import type {
|
|
3
|
-
BodySerializer,
|
|
4
|
-
QuerySerializer,
|
|
5
|
-
QuerySerializerOptions,
|
|
6
|
-
} from './bodySerializer';
|
|
2
|
+
import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer';
|
|
7
3
|
|
|
8
4
|
export type HttpMethod =
|
|
9
5
|
| 'connect'
|
|
@@ -32,9 +28,7 @@ export type Client<
|
|
|
32
28
|
setConfig: (config: Config) => Config;
|
|
33
29
|
} & {
|
|
34
30
|
[K in HttpMethod]: MethodFn;
|
|
35
|
-
} & ([SseFn] extends [never]
|
|
36
|
-
? { sse?: never }
|
|
37
|
-
: { sse: { [K in HttpMethod]: SseFn } });
|
|
31
|
+
} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } });
|
|
38
32
|
|
|
39
33
|
export interface Config {
|
|
40
34
|
/**
|
|
@@ -57,13 +51,7 @@ export interface Config {
|
|
|
57
51
|
| RequestInit['headers']
|
|
58
52
|
| Record<
|
|
59
53
|
string,
|
|
60
|
-
| string
|
|
61
|
-
| number
|
|
62
|
-
| boolean
|
|
63
|
-
| (string | number | boolean)[]
|
|
64
|
-
| null
|
|
65
|
-
| undefined
|
|
66
|
-
| unknown
|
|
54
|
+
string | number | boolean | (string | number | boolean)[] | null | undefined | unknown
|
|
67
55
|
>;
|
|
68
56
|
/**
|
|
69
57
|
* The request method.
|
|
@@ -110,7 +98,5 @@ type IsExactlyNeverOrNeverUndefined<T> = [T] extends [never]
|
|
|
110
98
|
: false;
|
|
111
99
|
|
|
112
100
|
export type OmitNever<T extends Record<string, unknown>> = {
|
|
113
|
-
[K in keyof T as IsExactlyNeverOrNeverUndefined<T[K]> extends true
|
|
114
|
-
? never
|
|
115
|
-
: K]: T[K];
|
|
101
|
+
[K in keyof T as IsExactlyNeverOrNeverUndefined<T[K]> extends true ? never : K]: T[K];
|
|
116
102
|
};
|
|
@@ -42,10 +42,7 @@ export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (Array.isArray(value)) {
|
|
45
|
-
url = url.replace(
|
|
46
|
-
match,
|
|
47
|
-
serializeArrayParam({ explode, name, style, value }),
|
|
48
|
-
);
|
|
45
|
+
url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
|
|
49
46
|
continue;
|
|
50
47
|
}
|
|
51
48
|
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { createSseClient } from '../core/serverSentEvents';
|
|
2
2
|
import type { HttpMethod } from '../core/types';
|
|
3
3
|
import { getValidRequestBody } from '../core/utils';
|
|
4
|
-
import type {
|
|
5
|
-
Client,
|
|
6
|
-
Config,
|
|
7
|
-
RequestOptions,
|
|
8
|
-
ResolvedRequestOptions,
|
|
9
|
-
} from './types';
|
|
4
|
+
import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types';
|
|
10
5
|
import {
|
|
11
6
|
buildUrl,
|
|
12
7
|
createConfig,
|
|
@@ -32,12 +27,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
32
27
|
return getConfig();
|
|
33
28
|
};
|
|
34
29
|
|
|
35
|
-
const interceptors = createInterceptors<
|
|
36
|
-
Request,
|
|
37
|
-
Response,
|
|
38
|
-
unknown,
|
|
39
|
-
ResolvedRequestOptions
|
|
40
|
-
>();
|
|
30
|
+
const interceptors = createInterceptors<Request, Response, unknown, ResolvedRequestOptions>();
|
|
41
31
|
|
|
42
32
|
const beforeRequest = async (options: RequestOptions) => {
|
|
43
33
|
const opts = {
|
|
@@ -103,12 +93,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
103
93
|
|
|
104
94
|
for (const fn of interceptors.error.fns) {
|
|
105
95
|
if (fn) {
|
|
106
|
-
finalError = (await fn(
|
|
107
|
-
error,
|
|
108
|
-
undefined as any,
|
|
109
|
-
request,
|
|
110
|
-
opts,
|
|
111
|
-
)) as unknown;
|
|
96
|
+
finalError = (await fn(error, undefined as any, request, opts)) as unknown;
|
|
112
97
|
}
|
|
113
98
|
}
|
|
114
99
|
|
|
@@ -145,10 +130,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
145
130
|
? getParseAs(response.headers.get('Content-Type'))
|
|
146
131
|
: opts.parseAs) ?? 'json';
|
|
147
132
|
|
|
148
|
-
if (
|
|
149
|
-
response.status === 204 ||
|
|
150
|
-
response.headers.get('Content-Length') === '0'
|
|
151
|
-
) {
|
|
133
|
+
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
|
|
152
134
|
let emptyData: any;
|
|
153
135
|
switch (parseAs) {
|
|
154
136
|
case 'arrayBuffer':
|
|
@@ -250,34 +232,29 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
250
232
|
};
|
|
251
233
|
};
|
|
252
234
|
|
|
253
|
-
const makeMethodFn =
|
|
254
|
-
(
|
|
255
|
-
request({ ...options, method });
|
|
235
|
+
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
|
|
236
|
+
request({ ...options, method });
|
|
256
237
|
|
|
257
|
-
const makeSseFn =
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
request = await fn(request, opts);
|
|
270
|
-
}
|
|
238
|
+
const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
|
|
239
|
+
const { opts, url } = await beforeRequest(options);
|
|
240
|
+
return createSseClient({
|
|
241
|
+
...opts,
|
|
242
|
+
body: opts.body as BodyInit | null | undefined,
|
|
243
|
+
headers: opts.headers as unknown as Record<string, string>,
|
|
244
|
+
method,
|
|
245
|
+
onRequest: async (url, init) => {
|
|
246
|
+
let request = new Request(url, init);
|
|
247
|
+
for (const fn of interceptors.request.fns) {
|
|
248
|
+
if (fn) {
|
|
249
|
+
request = await fn(request, opts);
|
|
271
250
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
});
|
|
280
|
-
};
|
|
251
|
+
}
|
|
252
|
+
return request;
|
|
253
|
+
},
|
|
254
|
+
serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined,
|
|
255
|
+
url,
|
|
256
|
+
});
|
|
257
|
+
};
|
|
281
258
|
|
|
282
259
|
return {
|
|
283
260
|
buildUrl,
|
|
@@ -3,17 +3,13 @@ import type {
|
|
|
3
3
|
ServerSentEventsOptions,
|
|
4
4
|
ServerSentEventsResult,
|
|
5
5
|
} from '../core/serverSentEvents';
|
|
6
|
-
import type {
|
|
7
|
-
Client as CoreClient,
|
|
8
|
-
Config as CoreConfig,
|
|
9
|
-
} from '../core/types';
|
|
6
|
+
import type { Client as CoreClient, Config as CoreConfig } from '../core/types';
|
|
10
7
|
import type { Middleware } from './utils';
|
|
11
8
|
|
|
12
9
|
export type ResponseStyle = 'data' | 'fields';
|
|
13
10
|
|
|
14
11
|
export interface Config<T extends ClientOptions = ClientOptions>
|
|
15
|
-
extends Omit<RequestInit, 'body' | 'headers' | 'method'>,
|
|
16
|
-
CoreConfig {
|
|
12
|
+
extends Omit<RequestInit, 'body' | 'headers' | 'method'>, CoreConfig {
|
|
17
13
|
/**
|
|
18
14
|
* Base URL for all requests made by this client.
|
|
19
15
|
*/
|
|
@@ -40,14 +36,7 @@ export interface Config<T extends ClientOptions = ClientOptions>
|
|
|
40
36
|
*
|
|
41
37
|
* @default 'auto'
|
|
42
38
|
*/
|
|
43
|
-
parseAs?:
|
|
44
|
-
| 'arrayBuffer'
|
|
45
|
-
| 'auto'
|
|
46
|
-
| 'blob'
|
|
47
|
-
| 'formData'
|
|
48
|
-
| 'json'
|
|
49
|
-
| 'stream'
|
|
50
|
-
| 'text';
|
|
39
|
+
parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text';
|
|
51
40
|
/**
|
|
52
41
|
* Should we return only data or multiple fields (data, error, response, etc.)?
|
|
53
42
|
*
|
|
@@ -67,7 +56,9 @@ export interface RequestOptions<
|
|
|
67
56
|
TResponseStyle extends ResponseStyle = 'fields',
|
|
68
57
|
ThrowOnError extends boolean = boolean,
|
|
69
58
|
Url extends string = string,
|
|
70
|
-
>
|
|
59
|
+
>
|
|
60
|
+
extends
|
|
61
|
+
Config<{
|
|
71
62
|
responseStyle: TResponseStyle;
|
|
72
63
|
throwOnError: ThrowOnError;
|
|
73
64
|
}>,
|
|
@@ -114,32 +105,22 @@ export type RequestResult<
|
|
|
114
105
|
? TData[keyof TData]
|
|
115
106
|
: TData
|
|
116
107
|
: {
|
|
117
|
-
data: TData extends Record<string, unknown>
|
|
118
|
-
? TData[keyof TData]
|
|
119
|
-
: TData;
|
|
108
|
+
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
|
|
120
109
|
request: Request;
|
|
121
110
|
response: Response;
|
|
122
111
|
}
|
|
123
112
|
>
|
|
124
113
|
: Promise<
|
|
125
114
|
TResponseStyle extends 'data'
|
|
126
|
-
?
|
|
127
|
-
| (TData extends Record<string, unknown>
|
|
128
|
-
? TData[keyof TData]
|
|
129
|
-
: TData)
|
|
130
|
-
| undefined
|
|
115
|
+
? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined
|
|
131
116
|
: (
|
|
132
117
|
| {
|
|
133
|
-
data: TData extends Record<string, unknown>
|
|
134
|
-
? TData[keyof TData]
|
|
135
|
-
: TData;
|
|
118
|
+
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
|
|
136
119
|
error: undefined;
|
|
137
120
|
}
|
|
138
121
|
| {
|
|
139
122
|
data: undefined;
|
|
140
|
-
error: TError extends Record<string, unknown>
|
|
141
|
-
? TError[keyof TError]
|
|
142
|
-
: TError;
|
|
123
|
+
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
|
|
143
124
|
}
|
|
144
125
|
) & {
|
|
145
126
|
request: Request;
|
|
@@ -178,10 +159,7 @@ type RequestFn = <
|
|
|
178
159
|
TResponseStyle extends ResponseStyle = 'fields',
|
|
179
160
|
>(
|
|
180
161
|
options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> &
|
|
181
|
-
Pick<
|
|
182
|
-
Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>,
|
|
183
|
-
'method'
|
|
184
|
-
>,
|
|
162
|
+
Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>,
|
|
185
163
|
) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
|
|
186
164
|
|
|
187
165
|
type BuildUrlFn = <
|
|
@@ -195,13 +173,7 @@ type BuildUrlFn = <
|
|
|
195
173
|
options: TData & Options<TData>,
|
|
196
174
|
) => string;
|
|
197
175
|
|
|
198
|
-
export type Client = CoreClient<
|
|
199
|
-
RequestFn,
|
|
200
|
-
Config,
|
|
201
|
-
MethodFn,
|
|
202
|
-
BuildUrlFn,
|
|
203
|
-
SseFn
|
|
204
|
-
> & {
|
|
176
|
+
export type Client = CoreClient<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
|
|
205
177
|
interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
|
|
206
178
|
};
|
|
207
179
|
|
|
@@ -63,9 +63,7 @@ export const createQuerySerializer = <T = unknown>({
|
|
|
63
63
|
/**
|
|
64
64
|
* Infers parseAs value from provided Content-Type header.
|
|
65
65
|
*/
|
|
66
|
-
export const getParseAs = (
|
|
67
|
-
contentType: string | null,
|
|
68
|
-
): Exclude<Config['parseAs'], 'auto'> => {
|
|
66
|
+
export const getParseAs = (contentType: string | null): Exclude<Config['parseAs'], 'auto'> => {
|
|
69
67
|
if (!contentType) {
|
|
70
68
|
// If no Content-Type header is provided, the best we can do is return the raw response body,
|
|
71
69
|
// which is effectively the same as the 'stream' option.
|
|
@@ -78,10 +76,7 @@ export const getParseAs = (
|
|
|
78
76
|
return;
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
if (
|
|
82
|
-
cleanContent.startsWith('application/json') ||
|
|
83
|
-
cleanContent.endsWith('+json')
|
|
84
|
-
) {
|
|
79
|
+
if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) {
|
|
85
80
|
return 'json';
|
|
86
81
|
}
|
|
87
82
|
|
|
@@ -90,9 +85,7 @@ export const getParseAs = (
|
|
|
90
85
|
}
|
|
91
86
|
|
|
92
87
|
if (
|
|
93
|
-
['application/', 'audio/', 'image/', 'video/'].some((type) =>
|
|
94
|
-
cleanContent.startsWith(type),
|
|
95
|
-
)
|
|
88
|
+
['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type))
|
|
96
89
|
) {
|
|
97
90
|
return 'blob';
|
|
98
91
|
}
|
|
@@ -199,10 +192,7 @@ export const mergeHeaders = (
|
|
|
199
192
|
continue;
|
|
200
193
|
}
|
|
201
194
|
|
|
202
|
-
const iterator =
|
|
203
|
-
header instanceof Headers
|
|
204
|
-
? headersEntries(header)
|
|
205
|
-
: Object.entries(header);
|
|
195
|
+
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
206
196
|
|
|
207
197
|
for (const [key, value] of iterator) {
|
|
208
198
|
if (value === null) {
|
|
@@ -231,10 +221,7 @@ type ErrInterceptor<Err, Res, Req, Options> = (
|
|
|
231
221
|
options: Options,
|
|
232
222
|
) => Err | Promise<Err>;
|
|
233
223
|
|
|
234
|
-
type ReqInterceptor<Req, Options> = (
|
|
235
|
-
request: Req,
|
|
236
|
-
options: Options,
|
|
237
|
-
) => Req | Promise<Req>;
|
|
224
|
+
type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
|
|
238
225
|
|
|
239
226
|
type ResInterceptor<Res, Req, Options> = (
|
|
240
227
|
response: Res,
|
|
@@ -268,10 +255,7 @@ class Interceptors<Interceptor> {
|
|
|
268
255
|
return this.fns.indexOf(id);
|
|
269
256
|
}
|
|
270
257
|
|
|
271
|
-
update(
|
|
272
|
-
id: number | Interceptor,
|
|
273
|
-
fn: Interceptor,
|
|
274
|
-
): number | Interceptor | false {
|
|
258
|
+
update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false {
|
|
275
259
|
const index = this.getInterceptorIndex(id);
|
|
276
260
|
if (this.fns[index]) {
|
|
277
261
|
this.fns[index] = fn;
|
|
@@ -4,13 +4,7 @@ import ky from 'ky';
|
|
|
4
4
|
import { createSseClient } from '../core/serverSentEvents';
|
|
5
5
|
import type { HttpMethod } from '../core/types';
|
|
6
6
|
import { getValidRequestBody } from '../core/utils';
|
|
7
|
-
import type {
|
|
8
|
-
Client,
|
|
9
|
-
Config,
|
|
10
|
-
RequestOptions,
|
|
11
|
-
ResolvedRequestOptions,
|
|
12
|
-
RetryOptions,
|
|
13
|
-
} from './types';
|
|
7
|
+
import type { Client, Config, RequestOptions, ResolvedRequestOptions, RetryOptions } from './types';
|
|
14
8
|
import type { Middleware } from './utils';
|
|
15
9
|
import {
|
|
16
10
|
buildUrl,
|
|
@@ -32,12 +26,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
32
26
|
return getConfig();
|
|
33
27
|
};
|
|
34
28
|
|
|
35
|
-
const interceptors = createInterceptors<
|
|
36
|
-
Request,
|
|
37
|
-
Response,
|
|
38
|
-
unknown,
|
|
39
|
-
ResolvedRequestOptions
|
|
40
|
-
>();
|
|
29
|
+
const interceptors = createInterceptors<Request, Response, unknown, ResolvedRequestOptions>();
|
|
41
30
|
|
|
42
31
|
const beforeRequest = async (options: RequestOptions) => {
|
|
43
32
|
const opts = {
|
|
@@ -76,12 +65,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
76
65
|
response: Response,
|
|
77
66
|
request: Request,
|
|
78
67
|
opts: ResolvedRequestOptions,
|
|
79
|
-
interceptorsMiddleware: Middleware<
|
|
80
|
-
Request,
|
|
81
|
-
Response,
|
|
82
|
-
unknown,
|
|
83
|
-
ResolvedRequestOptions
|
|
84
|
-
>,
|
|
68
|
+
interceptorsMiddleware: Middleware<Request, Response, unknown, ResolvedRequestOptions>,
|
|
85
69
|
) => {
|
|
86
70
|
const result = {
|
|
87
71
|
request,
|
|
@@ -151,14 +135,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
151
135
|
kyOptions.retry = {
|
|
152
136
|
limit: retryOpts.limit ?? 2,
|
|
153
137
|
methods: retryOpts.methods as Array<
|
|
154
|
-
| '
|
|
155
|
-
| 'post'
|
|
156
|
-
| 'put'
|
|
157
|
-
| 'patch'
|
|
158
|
-
| 'head'
|
|
159
|
-
| 'delete'
|
|
160
|
-
| 'options'
|
|
161
|
-
| 'trace'
|
|
138
|
+
'get' | 'post' | 'put' | 'patch' | 'head' | 'delete' | 'options' | 'trace'
|
|
162
139
|
>,
|
|
163
140
|
statusCodes: retryOpts.statusCodes,
|
|
164
141
|
};
|
|
@@ -214,10 +191,7 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
214
191
|
? getParseAs(response.headers.get('Content-Type'))
|
|
215
192
|
: opts.parseAs) ?? 'json';
|
|
216
193
|
|
|
217
|
-
if (
|
|
218
|
-
response.status === 204 ||
|
|
219
|
-
response.headers.get('Content-Length') === '0'
|
|
220
|
-
) {
|
|
194
|
+
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
|
|
221
195
|
let emptyData: any;
|
|
222
196
|
switch (parseAs) {
|
|
223
197
|
case 'arrayBuffer':
|
|
@@ -289,35 +263,30 @@ export const createClient = (config: Config = {}): Client => {
|
|
|
289
263
|
return parseErrorResponse(response, request, opts, interceptors);
|
|
290
264
|
};
|
|
291
265
|
|
|
292
|
-
const makeMethodFn =
|
|
293
|
-
(
|
|
294
|
-
request({ ...options, method });
|
|
266
|
+
const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>
|
|
267
|
+
request({ ...options, method });
|
|
295
268
|
|
|
296
|
-
const makeSseFn =
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
request = await fn(request, opts);
|
|
310
|
-
}
|
|
269
|
+
const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {
|
|
270
|
+
const { opts, url } = await beforeRequest(options);
|
|
271
|
+
return createSseClient({
|
|
272
|
+
...opts,
|
|
273
|
+
body: opts.body as BodyInit | null | undefined,
|
|
274
|
+
fetch: globalThis.fetch,
|
|
275
|
+
headers: opts.headers as unknown as Record<string, string>,
|
|
276
|
+
method,
|
|
277
|
+
onRequest: async (url, init) => {
|
|
278
|
+
let request = new Request(url, init);
|
|
279
|
+
for (const fn of interceptors.request.fns) {
|
|
280
|
+
if (fn) {
|
|
281
|
+
request = await fn(request, opts);
|
|
311
282
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
});
|
|
320
|
-
};
|
|
283
|
+
}
|
|
284
|
+
return request;
|
|
285
|
+
},
|
|
286
|
+
serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined,
|
|
287
|
+
url,
|
|
288
|
+
});
|
|
289
|
+
};
|
|
321
290
|
|
|
322
291
|
return {
|
|
323
292
|
buildUrl,
|