@gcmdev/faxios 0.2.1 → 0.2.3
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.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/adapters/fetch-helpers.d.ts +1 -1
- package/dist/lib/adapters/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/adapters/fetch.d.ts +4 -1
- package/dist/lib/adapters/fetch.d.ts.map +1 -1
- package/dist/lib/adapters/fetch.js +210 -92
- package/dist/lib/adapters/fetch.js.map +1 -1
- package/dist/lib/cancel/CanceledError.d.ts +1 -1
- package/dist/lib/cancel/CanceledError.d.ts.map +1 -1
- package/dist/lib/core/Faxios.d.ts +3 -3
- package/dist/lib/core/Faxios.d.ts.map +1 -1
- package/dist/lib/core/Faxios.js +8 -4
- package/dist/lib/core/Faxios.js.map +1 -1
- package/dist/lib/core/FaxiosError.d.ts +2 -2
- package/dist/lib/core/FaxiosError.d.ts.map +1 -1
- package/dist/lib/core/FaxiosHeaders.d.ts +8 -8
- package/dist/lib/core/FaxiosHeaders.d.ts.map +1 -1
- package/dist/lib/core/FaxiosHeaders.js +31 -7
- package/dist/lib/core/FaxiosHeaders.js.map +1 -1
- package/dist/lib/core/define.d.ts +3 -3
- package/dist/lib/core/define.d.ts.map +1 -1
- package/dist/lib/core/dispatchRequest.d.ts +1 -1
- package/dist/lib/core/dispatchRequest.d.ts.map +1 -1
- package/dist/lib/core/dispatchRequest.js +6 -1
- package/dist/lib/core/dispatchRequest.js.map +1 -1
- package/dist/lib/core/mergeConfig.d.ts +2 -2
- package/dist/lib/core/mergeConfig.d.ts.map +1 -1
- package/dist/lib/core/mergeConfig.js +40 -2
- package/dist/lib/core/mergeConfig.js.map +1 -1
- package/dist/lib/core/route.d.ts +1 -1
- package/dist/lib/core/route.d.ts.map +1 -1
- package/dist/lib/core/route.js +2 -5
- package/dist/lib/core/route.js.map +1 -1
- package/dist/lib/core/transformData.d.ts +2 -2
- package/dist/lib/core/transformData.d.ts.map +1 -1
- package/dist/lib/core/validateSchema.d.ts +2 -2
- package/dist/lib/core/validateSchema.d.ts.map +1 -1
- package/dist/lib/env/data.d.ts +1 -1
- package/dist/lib/env/data.js +1 -1
- package/dist/lib/faxios.d.ts +50 -50
- package/dist/lib/faxios.d.ts.map +1 -1
- package/dist/lib/helpers/cloneConfig.d.ts +0 -1
- package/dist/lib/helpers/cloneConfig.d.ts.map +1 -1
- package/dist/lib/helpers/cloneConfig.js +2 -2
- package/dist/lib/helpers/cloneConfig.js.map +1 -1
- package/dist/lib/helpers/cookies.d.ts +1 -1
- package/dist/lib/helpers/cookies.d.ts.map +1 -1
- package/dist/lib/helpers/formDataToJSON.d.ts +1 -1
- package/dist/lib/helpers/formDataToJSON.d.ts.map +1 -1
- package/dist/lib/helpers/formDataToJSON.js +1 -1
- package/dist/lib/helpers/formDataToJSON.js.map +1 -1
- package/dist/lib/helpers/parseHeaders.d.ts +1 -1
- package/dist/lib/helpers/parseHeaders.d.ts.map +1 -1
- package/dist/lib/helpers/progressEventReducer.d.ts.map +1 -1
- package/dist/lib/helpers/progressEventReducer.js +14 -1
- package/dist/lib/helpers/progressEventReducer.js.map +1 -1
- package/dist/lib/helpers/substitutePathParams.d.ts.map +1 -1
- package/dist/lib/helpers/substitutePathParams.js +11 -3
- package/dist/lib/helpers/substitutePathParams.js.map +1 -1
- package/dist/lib/helpers/toFormData.d.ts.map +1 -1
- package/dist/lib/helpers/toFormData.js +16 -20
- package/dist/lib/helpers/toFormData.js.map +1 -1
- package/dist/lib/helpers/trackStream.d.ts.map +1 -1
- package/dist/lib/helpers/trackStream.js +27 -3
- package/dist/lib/helpers/trackStream.js.map +1 -1
- package/dist/lib/helpers/validator.d.ts +1 -1
- package/dist/lib/helpers/validator.d.ts.map +1 -1
- package/dist/lib/platform.d.ts.map +1 -1
- package/dist/lib/plugins/authBearer.d.ts +9 -5
- package/dist/lib/plugins/authBearer.d.ts.map +1 -1
- package/dist/lib/plugins/authBearer.js +6 -0
- package/dist/lib/plugins/authBearer.js.map +1 -1
- package/dist/lib/plugins/definePlugin.d.ts +3 -3
- package/dist/lib/plugins/definePlugin.d.ts.map +1 -1
- package/dist/lib/plugins/retry.d.ts +23 -23
- package/dist/lib/plugins/retry.d.ts.map +1 -1
- package/dist/lib/plugins/timing.d.ts +8 -8
- package/dist/lib/plugins/timing.d.ts.map +1 -1
- package/dist/lib/types/standard-schema.d.ts +6 -6
- package/dist/lib/types/standard-schema.d.ts.map +1 -1
- package/dist/lib/types.d.ts +106 -92
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +4 -3
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +18 -5
- package/dist/lib/utils.js.map +1 -1
- package/package.json +7 -4
- package/skills/configure-requests/SKILL.md +14 -8
- package/skills/configure-requests/references/axios-differences.md +1 -1
- package/skills/configure-requests/references/plugins.md +37 -6
- package/src/index.ts +15 -15
- package/src/lib/adapters/fetch-helpers.ts +3 -3
- package/src/lib/adapters/fetch.ts +263 -144
- package/src/lib/cancel/CanceledError.ts +1 -1
- package/src/lib/core/Faxios.ts +17 -13
- package/src/lib/core/FaxiosError.ts +3 -3
- package/src/lib/core/FaxiosHeaders.ts +50 -23
- package/src/lib/core/define.ts +7 -7
- package/src/lib/core/dispatchRequest.ts +8 -3
- package/src/lib/core/mergeConfig.ts +42 -4
- package/src/lib/core/prepareRequest.ts +1 -1
- package/src/lib/core/route.ts +3 -6
- package/src/lib/core/transformData.ts +2 -2
- package/src/lib/core/validateSchema.ts +4 -4
- package/src/lib/defaults/index.ts +1 -1
- package/src/lib/env/data.ts +1 -1
- package/src/lib/faxios.ts +55 -55
- package/src/lib/helpers/HttpStatusCode.ts +1 -1
- package/src/lib/helpers/cloneConfig.ts +2 -3
- package/src/lib/helpers/composeSignals.ts +4 -4
- package/src/lib/helpers/cookies.ts +3 -3
- package/src/lib/helpers/formDataToJSON.ts +4 -4
- package/src/lib/helpers/parseHeaders.ts +2 -2
- package/src/lib/helpers/progressEventReducer.ts +15 -2
- package/src/lib/helpers/sanitizeHeaderValue.ts +1 -1
- package/src/lib/helpers/substitutePathParams.ts +13 -3
- package/src/lib/helpers/throttle.ts +1 -1
- package/src/lib/helpers/toFormData.ts +26 -28
- package/src/lib/helpers/trackStream.ts +40 -12
- package/src/lib/helpers/validator.ts +3 -3
- package/src/lib/platform.ts +4 -4
- package/src/lib/plugins/authBearer.ts +14 -9
- package/src/lib/plugins/definePlugin.ts +3 -3
- package/src/lib/plugins/retry.ts +27 -27
- package/src/lib/plugins/timing.ts +5 -5
- package/src/lib/types/standard-schema.ts +6 -6
- package/src/lib/types.ts +139 -125
- package/src/lib/utils.ts +30 -15
package/src/lib/faxios.ts
CHANGED
|
@@ -15,8 +15,8 @@ import formDataToJSON from "./helpers/formDataToJSON.js";
|
|
|
15
15
|
import HttpStatusCode from "./helpers/HttpStatusCode.js";
|
|
16
16
|
import isFaxiosError from "./helpers/isFaxiosError.js";
|
|
17
17
|
import toFormData from "./helpers/toFormData.js";
|
|
18
|
+
import type { CreateFaxiosDefaults, FaxiosDefaults, FaxiosHeaderValue, FaxiosMiddleware, FaxiosPluginArgument, FaxiosRequestConfig, FaxiosResponse, HeadersDefaults, Method, SchemaConfig, StringLiteralsOrString } from "./types.js";
|
|
18
19
|
import type { StandardSchemaV1 } from "./types/standard-schema.js";
|
|
19
|
-
import type { Method, StringLiteralsOrString, CreateFaxiosDefaults, FaxiosDefaults, FaxiosHeaderValue, FaxiosMiddleware, FaxiosPluginArgument, FaxiosRequestConfig, HeadersDefaults, FaxiosResponse, SchemaConfig } from "./types.js";
|
|
20
20
|
import utils from "./utils.js";
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -91,11 +91,11 @@ type ProvidedCapabilities<TProv> = [TProv] extends [null | undefined] ? {} : TPr
|
|
|
91
91
|
// use() reads capability names with Object.keys() and skips the keys that could pollute a prototype,
|
|
92
92
|
// so the registry only holds string names. A symbol, number or dangerous key would be typed on
|
|
93
93
|
// ctx.capabilities without matching a registered name, and nothing could satisfy a requirement for one.
|
|
94
|
-
type UnsupportedCapabilityKeys<TCaps> = Extract<keyof TCaps,
|
|
94
|
+
type UnsupportedCapabilityKeys<TCaps> = Extract<keyof TCaps, "__proto__" | "constructor" | "prototype" | number | symbol>;
|
|
95
95
|
|
|
96
|
-
type RejectUnsupportedCapabilityKeys<TReq, TProv> = [UnsupportedCapabilityKeys<
|
|
96
|
+
type RejectUnsupportedCapabilityKeys<TReq, TProv> = [UnsupportedCapabilityKeys<TProv> | UnsupportedCapabilityKeys<TReq>] extends [never]
|
|
97
97
|
? unknown
|
|
98
|
-
: { "faxios: capability names must be strings other than __proto__, constructor and prototype": UnsupportedCapabilityKeys<
|
|
98
|
+
: { "faxios: capability names must be strings other than __proto__, constructor and prototype": UnsupportedCapabilityKeys<TProv> | UnsupportedCapabilityKeys<TReq>; };
|
|
99
99
|
|
|
100
100
|
// Nothing sets a plugin option for the caller, so a required one would be typed as present in the
|
|
101
101
|
// plugin's middleware while every request that omits it leaves it undefined.
|
|
@@ -130,23 +130,6 @@ type CheckPlugin<THave, TReq, TProv, TOpt> = RequireCapabilities<THave, TReq>
|
|
|
130
130
|
// without narrowing first.
|
|
131
131
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- see above
|
|
132
132
|
export type FaxiosInstance<TOpts = {}, TCaps = {}> = {
|
|
133
|
-
/**
|
|
134
|
-
* Register middleware or a plugin and return this instance, typed with the plugin's request
|
|
135
|
-
* options and capabilities added. A plugin whose required capabilities aren't installed yet, or
|
|
136
|
-
* that provides a capability another installed plugin already provides, is a type error.
|
|
137
|
-
*/
|
|
138
|
-
use: <TReq = unknown, TProv = unknown, TOpt = unknown>(
|
|
139
|
-
middleware: FaxiosMiddleware<TOpts, TCaps> | (FaxiosPluginArgument<TReq, TProv, TOpt> & CheckPlugin<TCaps, TReq, TProv, TOpt>)
|
|
140
|
-
) => FaxiosInstance<TOpts & TOpt, TCaps & ProvidedCapabilities<TProv>>;
|
|
141
|
-
/**
|
|
142
|
-
* Remove middleware or a plugin registered with use(), by reference. In-flight requests are
|
|
143
|
-
* unaffected. The instance type is not narrowed: request options and capabilities the ejected
|
|
144
|
-
* plugin added stay in its type.
|
|
145
|
-
*/
|
|
146
|
-
// A method, so its parameter is checked bivariantly: middleware typed for this instance's
|
|
147
|
-
// options and capabilities is accepted.
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/method-signature-style -- see above
|
|
149
|
-
eject<TReq = unknown, TProv = unknown, TOpt = unknown>(middleware: FaxiosMiddleware<TOpt> | FaxiosPluginArgument<TReq, TProv, TOpt>): void;
|
|
150
133
|
/**
|
|
151
134
|
* Define a typed endpoint for `method` and `url` (with optional `{key}` placeholders). `config`
|
|
152
135
|
* holds request defaults and the `pathParamsSchema`, `paramsSchema`, `requestSchema` and
|
|
@@ -165,6 +148,15 @@ export type FaxiosInstance<TOpts = {}, TCaps = {}> = {
|
|
|
165
148
|
url: string,
|
|
166
149
|
config?: DefineConfig<PP, P, D, R> & TOpts
|
|
167
150
|
) => DefinedEndpoint<PP, P, D, R, TOpts>;
|
|
151
|
+
/**
|
|
152
|
+
* Remove middleware or a plugin registered with use(), by reference. In-flight requests are
|
|
153
|
+
* unaffected. The instance type is not narrowed: request options and capabilities the ejected
|
|
154
|
+
* plugin added stay in its type.
|
|
155
|
+
*/
|
|
156
|
+
// A method, so its parameter is checked bivariantly: middleware typed for this instance's
|
|
157
|
+
// options and capabilities is accepted.
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/method-signature-style -- see above
|
|
159
|
+
eject<TReq = unknown, TProv = unknown, TOpt = unknown>(middleware: FaxiosMiddleware<TOpt> | FaxiosPluginArgument<TReq, TProv, TOpt>): void;
|
|
168
160
|
/**
|
|
169
161
|
* Group endpoints that share `url` and `config`. Returns one endpoint factory per method (`get`,
|
|
170
162
|
* `post`, `put`, `patch`, `delete`, `head`, `options`; no `query`), each taking `paramsSchema`,
|
|
@@ -176,22 +168,38 @@ export type FaxiosInstance<TOpts = {}, TCaps = {}> = {
|
|
|
176
168
|
url: string,
|
|
177
169
|
config?: RouteConfig<PP> & TOpts
|
|
178
170
|
) => RouteBuilder<PP, TOpts>;
|
|
171
|
+
/**
|
|
172
|
+
* Register middleware or a plugin and return this instance, typed with the plugin's request
|
|
173
|
+
* options and capabilities added. A plugin whose required capabilities aren't installed yet, or
|
|
174
|
+
* that provides a capability another installed plugin already provides, is a type error.
|
|
175
|
+
*/
|
|
176
|
+
use: <TReq = unknown, TProv = unknown, TOpt = unknown>(
|
|
177
|
+
middleware: FaxiosMiddleware<TOpts, TCaps> | (FaxiosPluginArgument<TReq, TProv, TOpt> & CheckPlugin<TCaps, TReq, TProv, TOpt>)
|
|
178
|
+
) => FaxiosInstance<TOpts & TOpt, TCaps & ProvidedCapabilities<TProv>>;
|
|
179
179
|
<O, D = unknown>(config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
180
180
|
<O, D = unknown>(url: string, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
181
181
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(config: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
182
182
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
create: (instanceConfig?: CreateFaxiosDefaults) => FaxiosInstance;
|
|
184
|
+
// `common` plus one header group per method; a key set directly on
|
|
185
|
+
// `headers` applies to every method.
|
|
186
|
+
defaults: Omit<FaxiosDefaults, "headers"> & {
|
|
187
|
+
headers: HeadersDefaults & { [key: string]: FaxiosHeaderValue | undefined; };
|
|
188
|
+
} & Partial<TOpts>;
|
|
189
|
+
delete: {
|
|
188
190
|
<O, D = unknown>(url: string, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
189
191
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
190
192
|
};
|
|
191
|
-
|
|
193
|
+
get: {
|
|
192
194
|
<O, D = unknown>(url: string, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
193
195
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
194
196
|
};
|
|
197
|
+
/**
|
|
198
|
+
* Build the URL for `config` without sending a request. Applies `baseURL`, `params` and
|
|
199
|
+
* `paramsSerializer`, but does not substitute `pathParams` or run schemas, so `{key}`
|
|
200
|
+
* placeholders come back as written.
|
|
201
|
+
*/
|
|
202
|
+
getUri: (config?: FaxiosRequestConfig & TOpts) => string;
|
|
195
203
|
head: {
|
|
196
204
|
<O, D = unknown>(url: string, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
197
205
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
@@ -200,23 +208,23 @@ export type FaxiosInstance<TOpts = {}, TCaps = {}> = {
|
|
|
200
208
|
<O, D = unknown>(url: string, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
201
209
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
202
210
|
};
|
|
203
|
-
|
|
211
|
+
patch: {
|
|
204
212
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
205
213
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
206
214
|
};
|
|
207
|
-
|
|
215
|
+
patchForm: {
|
|
208
216
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
209
217
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
210
218
|
};
|
|
211
|
-
|
|
219
|
+
post: {
|
|
212
220
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
213
221
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
214
222
|
};
|
|
215
|
-
|
|
223
|
+
postForm: {
|
|
216
224
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
217
225
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
218
226
|
};
|
|
219
|
-
|
|
227
|
+
put: {
|
|
220
228
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
221
229
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
222
230
|
};
|
|
@@ -224,41 +232,33 @@ export type FaxiosInstance<TOpts = {}, TCaps = {}> = {
|
|
|
224
232
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
225
233
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
226
234
|
};
|
|
227
|
-
|
|
235
|
+
query: {
|
|
228
236
|
<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
229
237
|
<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
230
238
|
};
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
} & Partial<TOpts>;
|
|
236
|
-
/**
|
|
237
|
-
* Build the URL for `config` without sending a request. Applies `baseURL`, `params` and
|
|
238
|
-
* `paramsSerializer`, but does not substitute `pathParams` or run schemas, so `{key}`
|
|
239
|
-
* placeholders come back as written.
|
|
240
|
-
*/
|
|
241
|
-
getUri: (config?: FaxiosRequestConfig & TOpts) => string;
|
|
242
|
-
create: (instanceConfig?: CreateFaxiosDefaults) => FaxiosInstance;
|
|
239
|
+
request: {
|
|
240
|
+
<O, D = unknown>(config: SchemaConfig<O, D> & TOpts): Promise<FaxiosResponse<O, D>>;
|
|
241
|
+
<T = unknown, R = FaxiosResponse<T>, D = unknown>(config: FaxiosRequestConfig<D> & TOpts): Promise<R>;
|
|
242
|
+
};
|
|
243
243
|
};
|
|
244
244
|
|
|
245
245
|
/** The default export: an instance plus the static helpers only it carries. */
|
|
246
246
|
export type FaxiosStatic = FaxiosInstance & {
|
|
247
|
-
|
|
247
|
+
all: (promises: Array<Promise<unknown>>) => Promise<Array<unknown>>;
|
|
248
|
+
Cancel: typeof CanceledError;
|
|
248
249
|
CanceledError: typeof CanceledError;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
toFormData: typeof toFormData;
|
|
250
|
+
default: FaxiosStatic;
|
|
251
|
+
Faxios: typeof Faxios;
|
|
252
252
|
FaxiosError: typeof FaxiosError;
|
|
253
|
-
Cancel: typeof CanceledError;
|
|
254
|
-
all: (promises: Array<Promise<unknown>>) => Promise<Array<unknown>>;
|
|
255
|
-
spread: (fn: (...args: Array<unknown>) => unknown) => (arr: Array<unknown>) => unknown;
|
|
256
|
-
isFaxiosError: typeof isFaxiosError;
|
|
257
|
-
mergeConfig: typeof mergeConfig;
|
|
258
253
|
FaxiosHeaders: typeof FaxiosHeaders;
|
|
259
254
|
formToJSON: (thing: unknown) => unknown;
|
|
260
255
|
HttpStatusCode: typeof HttpStatusCode;
|
|
261
|
-
|
|
256
|
+
isCancel: typeof isCancel;
|
|
257
|
+
isFaxiosError: typeof isFaxiosError;
|
|
258
|
+
mergeConfig: typeof mergeConfig;
|
|
259
|
+
spread: (fn: (...args: Array<unknown>) => unknown) => (arr: Array<unknown>) => unknown;
|
|
260
|
+
toFormData: typeof toFormData;
|
|
261
|
+
VERSION: typeof VERSION;
|
|
262
262
|
};
|
|
263
263
|
|
|
264
264
|
// Create the default instance to be exported; the statics are attached below.
|
|
@@ -71,7 +71,7 @@ const HttpStatusCode = {
|
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
Object.entries(HttpStatusCode).forEach(([ key, value ]) => {
|
|
74
|
-
(HttpStatusCode as Record<
|
|
74
|
+
(HttpStatusCode as Record<number | string, number | string>)[value] = key;
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
export default HttpStatusCode;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { FaxiosRequestConfig } from "../types.js";
|
|
2
|
-
|
|
3
|
-
export const DANGEROUS_KEYS = new Set([ "__proto__", "constructor", "prototype" ]);
|
|
2
|
+
import utils from "../utils.js";
|
|
4
3
|
|
|
5
4
|
// ponytail: null-proto shallow clone; replaces mergeConfig({}, config) which ran the full
|
|
6
5
|
// two-config merge machinery just to get a defensive copy. Security invariants preserved:
|
|
@@ -15,7 +14,7 @@ export default function cloneConfig<T extends FaxiosRequestConfig>(src: T): T &
|
|
|
15
14
|
enumerable: false,
|
|
16
15
|
}));
|
|
17
16
|
for (const key of Object.keys(src)) {
|
|
18
|
-
if (!
|
|
17
|
+
if (!utils.isDangerousKey(key)) {
|
|
19
18
|
(dst as Record<string, unknown>)[key] = (src as Record<string, unknown>)[key];
|
|
20
19
|
}
|
|
21
20
|
}
|
|
@@ -5,11 +5,11 @@ import utils from "../utils.js";
|
|
|
5
5
|
type AbortHandler = (this: AbortSignal & { reason?: unknown; }, reason: unknown) => void;
|
|
6
6
|
type EventListenerFn = (event: unknown) => void;
|
|
7
7
|
type SignalLike = {
|
|
8
|
-
unsubscribe?: (() => void) | ((handler: AbortHandler) => void);
|
|
9
|
-
addEventListener: (type: string, listener: EventListenerFn) => void;
|
|
10
|
-
removeEventListener: (type: string, listener: EventListenerFn) => void;
|
|
11
8
|
aborted: boolean;
|
|
9
|
+
addEventListener: (type: string, listener: EventListenerFn) => void;
|
|
12
10
|
reason?: unknown;
|
|
11
|
+
removeEventListener: (type: string, listener: EventListenerFn) => void;
|
|
12
|
+
unsubscribe?: (() => void) | ((handler: AbortHandler) => void);
|
|
13
13
|
};
|
|
14
14
|
export type ExtendedAbortSignal = AbortSignal & { unsubscribe?: (() => void) | ((handler: AbortHandler) => void); };
|
|
15
15
|
|
|
@@ -35,7 +35,7 @@ const composeSignals = (signals: Array<unknown> | null | undefined, timeout?: nu
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
let timer: ReturnType<typeof setTimeout>
|
|
38
|
+
let timer: null | ReturnType<typeof setTimeout> =
|
|
39
39
|
timeout
|
|
40
40
|
? setTimeout(() => {
|
|
41
41
|
timer = null;
|
|
@@ -2,9 +2,9 @@ import platform from "../platform.js";
|
|
|
2
2
|
import utils from "../utils.js";
|
|
3
3
|
|
|
4
4
|
type CookieManager = {
|
|
5
|
-
|
|
6
|
-
read: (name: string) => string | null;
|
|
5
|
+
read: (name: string) => null | string;
|
|
7
6
|
remove: (name: string) => void;
|
|
7
|
+
write: (name: string, value: string, expires?: number, path?: string, domain?: string, secure?: boolean, sameSite?: string) => void;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
const _globalThis = globalThis as { document?: { cookie?: string; }; };
|
|
@@ -36,7 +36,7 @@ export default platform.hasStandardBrowserEnv
|
|
|
36
36
|
_globalThis.document.cookie = cookie.join("; ");
|
|
37
37
|
},
|
|
38
38
|
|
|
39
|
-
read(name: string):
|
|
39
|
+
read(name: string): null | string {
|
|
40
40
|
if (!_globalThis.document) return null;
|
|
41
41
|
// Match name=value by splitting on the semicolon separator instead of building a
|
|
42
42
|
// RegExp from `name` — interpolating an unescaped string into a RegExp would let
|
|
@@ -29,7 +29,7 @@ function parsePropPath(name: string): Array<string> {
|
|
|
29
29
|
// foo x y z
|
|
30
30
|
const path: Array<string> = [];
|
|
31
31
|
const pattern = /\w+|\[(\w*)]/g;
|
|
32
|
-
let match:
|
|
32
|
+
let match: null | RegExpExecArray;
|
|
33
33
|
|
|
34
34
|
while ((match = pattern.exec(name)) !== null) {
|
|
35
35
|
throwIfDepthExceeded(path.length);
|
|
@@ -66,13 +66,13 @@ function arrayToObject(arr: Array<unknown>): Record<string, unknown> {
|
|
|
66
66
|
*
|
|
67
67
|
* @returns {Object<string, any> | null} The converted object.
|
|
68
68
|
*/
|
|
69
|
-
function formDataToJSON(formData: unknown): Record<string, unknown>
|
|
69
|
+
function formDataToJSON(formData: unknown): null | Record<string, unknown> {
|
|
70
70
|
function buildPath(path: Array<string>, value: unknown, target: Record<string, unknown>, index: number): boolean {
|
|
71
71
|
throwIfDepthExceeded(index);
|
|
72
72
|
|
|
73
|
-
let name:
|
|
73
|
+
let name: number | string = path[index++]!;
|
|
74
74
|
|
|
75
|
-
if (name
|
|
75
|
+
if (utils.isDangerousKey(name)) return true;
|
|
76
76
|
|
|
77
77
|
const isNumericKey = Number.isFinite(+name);
|
|
78
78
|
const isLast = index >= path.length;
|
|
@@ -38,8 +38,8 @@ const ignoreDuplicateOf = utils.toObjectSet([
|
|
|
38
38
|
*
|
|
39
39
|
* @returns {Object} Headers parsed into an object
|
|
40
40
|
*/
|
|
41
|
-
export default (rawHeaders: string): Record<string, string |
|
|
42
|
-
const parsed: Record<string, string |
|
|
41
|
+
export default (rawHeaders: string): Record<string, Array<string> | string> => {
|
|
42
|
+
const parsed: Record<string, Array<string> | string> = {};
|
|
43
43
|
let key: string;
|
|
44
44
|
let val: string;
|
|
45
45
|
let i: number;
|
|
@@ -11,7 +11,7 @@ export const progressEventReducer = (listener: (data: FaxiosProgressEvent) => vo
|
|
|
11
11
|
if (!e || typeof (e as Record<string, unknown>).loaded !== "number") {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
const ev = e as { loaded: number; total?: number;
|
|
14
|
+
const ev = e as { lengthComputable?: boolean; loaded: number; total?: number; };
|
|
15
15
|
const rawLoaded = ev.loaded;
|
|
16
16
|
const total = ev.lengthComputable ? ev.total : undefined;
|
|
17
17
|
const loaded = total != null ? Math.min(rawLoaded, total) : rawLoaded;
|
|
@@ -51,7 +51,20 @@ export const progressEventDecorator = (total: number | undefined, throttled: Ret
|
|
|
51
51
|
];
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
+
// Progress listeners are caller code: any error they throw (or a promise they
|
|
55
|
+
// reject) is caught and ignored so it can't become an uncaught exception or
|
|
56
|
+
// change how the request settles.
|
|
54
57
|
export const asyncDecorator =
|
|
55
58
|
(fn: (...args: Array<unknown>) => unknown) =>
|
|
56
59
|
(...args: Array<unknown>) =>
|
|
57
|
-
utils.asap(() =>
|
|
60
|
+
utils.asap(() => {
|
|
61
|
+
try {
|
|
62
|
+
const result = fn(...args);
|
|
63
|
+
if (utils.isThenable(result)) {
|
|
64
|
+
(result as PromiseLike<unknown>).then(undefined, () => {});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Ignored by design: see the onUploadProgress/onDownloadProgress docs.
|
|
69
|
+
}
|
|
70
|
+
});
|
|
@@ -36,7 +36,7 @@ const INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp("[\\u0000-\\u0008\\u000a-\
|
|
|
36
36
|
const INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp("[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+", "g");
|
|
37
37
|
|
|
38
38
|
// eslint-disable-next-line sonarjs/function-return-type
|
|
39
|
-
function sanitizeValue(value: unknown, invalidChars: RegExp): string |
|
|
39
|
+
function sanitizeValue(value: unknown, invalidChars: RegExp): Array<string> | string {
|
|
40
40
|
if (utils.isArray(value)) {
|
|
41
41
|
return (value as Array<unknown>).map(item => sanitizeValue(item, invalidChars) as string);
|
|
42
42
|
}
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
+
import FaxiosError from "../core/FaxiosError.js";
|
|
2
|
+
|
|
3
|
+
// `.` and `..` (raw or percent-encoded) would become a dot segment that the URL parser resolves,
|
|
4
|
+
// moving the request to another path.
|
|
5
|
+
const DOT_SEGMENT = /^(?:\.|%2e){1,2}$/i;
|
|
6
|
+
|
|
1
7
|
/** Expects raw (unencoded) param values — applies encodeURIComponent here. */
|
|
2
8
|
export function substitutePathParams(url: string, params: Record<string, unknown>): string {
|
|
3
9
|
return url.replace(/\{([^{}]+)\}/g, (_match, key: string) => {
|
|
4
10
|
if (!Object.prototype.hasOwnProperty.call(params, key)) {
|
|
5
|
-
throw new
|
|
11
|
+
throw new FaxiosError(`Path param "${key}" not found in pathParams`, FaxiosError.ERR_BAD_OPTION_VALUE);
|
|
6
12
|
}
|
|
7
13
|
const val = params[key];
|
|
8
14
|
if (val == null) {
|
|
9
|
-
throw new
|
|
15
|
+
throw new FaxiosError(`Path param "${key}" is null or undefined`, FaxiosError.ERR_BAD_OPTION_VALUE);
|
|
10
16
|
}
|
|
11
|
-
|
|
17
|
+
const str = String(val);
|
|
18
|
+
if (DOT_SEGMENT.test(str)) {
|
|
19
|
+
throw new FaxiosError(`Path param "${key}" must not be "." or ".." (or a percent-encoded form)`, FaxiosError.ERR_BAD_OPTION_VALUE);
|
|
20
|
+
}
|
|
21
|
+
return encodeURIComponent(str);
|
|
12
22
|
});
|
|
13
23
|
}
|
|
@@ -8,7 +8,7 @@ function throttle(fn: (...args: Array<unknown>) => void, freq: number): [(...arg
|
|
|
8
8
|
let timestamp = 0;
|
|
9
9
|
const threshold = 1000 / freq;
|
|
10
10
|
let lastArgs: Array<unknown> | null = null;
|
|
11
|
-
let timer: ReturnType<typeof setTimeout>
|
|
11
|
+
let timer: null | ReturnType<typeof setTimeout> = null;
|
|
12
12
|
|
|
13
13
|
const invoke = (args: Array<unknown>, now: number = Date.now()) => {
|
|
14
14
|
timestamp = now;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import FaxiosError from "../core/FaxiosError.js";
|
|
4
4
|
// temporary hotfix to avoid circular references until FaxiosURLSearchParams is refactored
|
|
5
|
-
import type { GenericFormData, SerializerVisitor
|
|
5
|
+
import type { FormDataVisitorHelpers, GenericFormData, SerializerVisitor } from "../types.js";
|
|
6
6
|
import utils from "../utils.js";
|
|
7
7
|
|
|
8
8
|
// Default nesting limit shared with the inverse transform (formDataToJSON) so
|
|
@@ -40,11 +40,11 @@ function removeBrackets(key: string): string {
|
|
|
40
40
|
*
|
|
41
41
|
* @returns {string} The path to the current key.
|
|
42
42
|
*/
|
|
43
|
-
function renderKey(path: Array<
|
|
43
|
+
function renderKey(path: Array<number | string> | null | undefined, key: number | string, dots: unknown): string {
|
|
44
44
|
if (!path) return String(key);
|
|
45
45
|
return path
|
|
46
46
|
.concat(key)
|
|
47
|
-
.map(function each(token:
|
|
47
|
+
.map(function each(token: number | string, i: number) {
|
|
48
48
|
token = removeBrackets(String(token));
|
|
49
49
|
return !dots && i ? "[" + token + "]" : token;
|
|
50
50
|
})
|
|
@@ -91,7 +91,7 @@ const predicates = utils.toFlatObject(utils, {}, null as unknown as false, funct
|
|
|
91
91
|
*/
|
|
92
92
|
function toFormData(obj: unknown, formData?: GenericFormData | null, options?: Record<string, unknown>): GenericFormData {
|
|
93
93
|
if (!utils.isObject(obj)) {
|
|
94
|
-
throw new
|
|
94
|
+
throw new FaxiosError("target must be an object", FaxiosError.ERR_BAD_REQUEST);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
const FormDataCtor = (globalThis as Record<string, unknown>)["FormData"] as (new () => GenericFormData) | undefined;
|
|
@@ -100,13 +100,15 @@ function toFormData(obj: unknown, formData?: GenericFormData | null, options?: R
|
|
|
100
100
|
formData = new FormDataCtor();
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
// Null-prototype destination: `visitor`, `maxDepth` and `Blob` are read below, and a polluted
|
|
104
|
+
// Object.prototype must not supply them.
|
|
103
105
|
options = utils.toFlatObject(
|
|
104
106
|
options,
|
|
105
|
-
{
|
|
107
|
+
Object.assign(Object.create(null) as Record<string, unknown>, {
|
|
106
108
|
metaTokens: true,
|
|
107
109
|
dots: false,
|
|
108
110
|
indexes: false,
|
|
109
|
-
},
|
|
111
|
+
}),
|
|
110
112
|
false,
|
|
111
113
|
function defined(option: string, source: unknown) {
|
|
112
114
|
return !utils.isUndefined((source as Record<string, unknown>)[option]);
|
|
@@ -118,16 +120,16 @@ function toFormData(obj: unknown, formData?: GenericFormData | null, options?: R
|
|
|
118
120
|
const visitor = (options["visitor"] || defaultVisitor) as SerializerVisitor;
|
|
119
121
|
const dots = options["dots"];
|
|
120
122
|
const indexes = options["indexes"];
|
|
121
|
-
const _Blob = options["Blob"] || (
|
|
123
|
+
const _Blob = (options["Blob"] || (globalThis as Record<string, unknown>)["Blob"]) as (new (parts: Array<unknown>) => unknown) | undefined;
|
|
122
124
|
const maxDepth =
|
|
123
125
|
options["maxDepth"] === undefined
|
|
124
126
|
? DEFAULT_FORM_DATA_MAX_DEPTH
|
|
125
127
|
: (options["maxDepth"] as number);
|
|
126
|
-
const useBlob = _Blob && utils.isSpecCompliantForm(formData);
|
|
128
|
+
const useBlob = typeof _Blob === "function" && utils.isSpecCompliantForm(formData);
|
|
127
129
|
const stack: Array<unknown> = [];
|
|
128
130
|
|
|
129
131
|
if (!utils.isFunction(visitor)) {
|
|
130
|
-
throw new
|
|
132
|
+
throw new FaxiosError("visitor must be a function", FaxiosError.ERR_BAD_OPTION_VALUE);
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
function convertValue(value: unknown): unknown {
|
|
@@ -141,16 +143,15 @@ function toFormData(obj: unknown, formData?: GenericFormData | null, options?: R
|
|
|
141
143
|
return String(value);
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
if (!useBlob && utils.isBlob(value)) {
|
|
145
|
-
throw new FaxiosError(
|
|
146
|
+
if (!useBlob && (utils.isBlob(value) || utils.isArrayBuffer(value) || utils.isTypedArray(value))) {
|
|
147
|
+
throw new FaxiosError(
|
|
148
|
+
"Binary FormData values need a spec-compliant FormData and a Blob constructor (set the `Blob` option)",
|
|
149
|
+
FaxiosError.ERR_NOT_SUPPORT
|
|
150
|
+
);
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {
|
|
149
|
-
|
|
150
|
-
if (useBlob && typeof BlobCtor === "function") {
|
|
151
|
-
return new BlobCtor([ value ]);
|
|
152
|
-
}
|
|
153
|
-
throw new FaxiosError("Blob is required for binary FormData values in this environment", FaxiosError.ERR_NOT_SUPPORT);
|
|
154
|
+
return new (_Blob as new (parts: Array<unknown>) => unknown)([ value ]);
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
return value;
|
|
@@ -201,7 +202,7 @@ function toFormData(obj: unknown, formData?: GenericFormData | null, options?: R
|
|
|
201
202
|
*
|
|
202
203
|
* @returns {boolean} return true to visit the each prop of the value recursively
|
|
203
204
|
*/
|
|
204
|
-
function defaultVisitor(this: GenericFormData, value: unknown, key:
|
|
205
|
+
function defaultVisitor(this: GenericFormData, value: unknown, key: number | string, path: Array<number | string> | null, _helpers?: FormDataVisitorHelpers): boolean {
|
|
205
206
|
let arr: unknown = value;
|
|
206
207
|
|
|
207
208
|
if (utils.isReactNative(formData) && utils.isReactNativeBlob(value)) {
|
|
@@ -248,19 +249,20 @@ function toFormData(obj: unknown, formData?: GenericFormData | null, options?: R
|
|
|
248
249
|
return false;
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
const exposedHelpers: FormDataVisitorHelpers =
|
|
252
|
-
|
|
252
|
+
const exposedHelpers: FormDataVisitorHelpers = {
|
|
253
|
+
...predicates,
|
|
254
|
+
defaultVisitor,
|
|
253
255
|
convertValue,
|
|
254
256
|
isVisitable,
|
|
255
|
-
}
|
|
257
|
+
};
|
|
256
258
|
|
|
257
|
-
function build(value: unknown, path?: Array<
|
|
259
|
+
function build(value: unknown, path?: Array<number | string>, depth = 0): void {
|
|
258
260
|
if (utils.isUndefined(value)) return;
|
|
259
261
|
|
|
260
262
|
throwIfMaxDepthExceeded(depth);
|
|
261
263
|
|
|
262
264
|
if (stack.indexOf(value) !== -1) {
|
|
263
|
-
throw new
|
|
265
|
+
throw new FaxiosError("Circular reference detected in " + (path ?? []).join("."), FaxiosError.ERR_BAD_REQUEST);
|
|
264
266
|
}
|
|
265
267
|
|
|
266
268
|
stack.push(value);
|
|
@@ -271,23 +273,19 @@ function toFormData(obj: unknown, formData?: GenericFormData | null, options?: R
|
|
|
271
273
|
visitor.call(
|
|
272
274
|
formData as GenericFormData,
|
|
273
275
|
el,
|
|
274
|
-
utils.isString(key) ? (key as string).trim() : key as
|
|
276
|
+
utils.isString(key) ? (key as string).trim() : key as number | string,
|
|
275
277
|
path ?? null,
|
|
276
278
|
exposedHelpers
|
|
277
279
|
);
|
|
278
280
|
|
|
279
281
|
if (result === true) {
|
|
280
|
-
build(el, path ? path.concat(key as
|
|
282
|
+
build(el, path ? path.concat(key as number | string) : [ key as number | string ], depth + 1);
|
|
281
283
|
}
|
|
282
284
|
});
|
|
283
285
|
|
|
284
286
|
stack.pop();
|
|
285
287
|
}
|
|
286
288
|
|
|
287
|
-
if (!utils.isObject(obj)) {
|
|
288
|
-
throw new TypeError("data must be an object");
|
|
289
|
-
}
|
|
290
|
-
|
|
291
289
|
build(obj);
|
|
292
290
|
|
|
293
291
|
return formData;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import FaxiosError from "../core/FaxiosError.js";
|
|
2
|
+
import utils from "../utils.js";
|
|
3
|
+
|
|
1
4
|
type ReadableStreamController = {
|
|
2
|
-
enqueue: (chunk: Uint8Array) => void;
|
|
3
5
|
close: () => void;
|
|
6
|
+
enqueue: (chunk: Uint8Array) => void;
|
|
4
7
|
};
|
|
5
8
|
|
|
6
9
|
type ReadableStreamSource = {
|
|
7
|
-
pull?: (controller: ReadableStreamController) => Promise<void>;
|
|
8
10
|
cancel?: (reason?: unknown) => Promise<unknown>;
|
|
11
|
+
pull?: (controller: ReadableStreamController) => Promise<void>;
|
|
9
12
|
};
|
|
10
13
|
|
|
11
14
|
type ReadableStreamInit = {
|
|
@@ -16,9 +19,31 @@ type ReadableStreamCtor = new (source: ReadableStreamSource, init?: ReadableStre
|
|
|
16
19
|
|
|
17
20
|
const ReadableStreamGlobal = (globalThis as Record<string, unknown>)["ReadableStream"] as ReadableStreamCtor | undefined;
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
const textEncoder = typeof TextEncoder === "function" ? new TextEncoder() : undefined;
|
|
23
|
+
|
|
24
|
+
// View the chunk's bytes without copying them. Strings are UTF-8 encoded; anything else is not
|
|
25
|
+
// a byte chunk and is rejected rather than silently converted.
|
|
26
|
+
const toBytes = (chunk: unknown): Uint8Array => {
|
|
27
|
+
if (chunk instanceof Uint8Array) {
|
|
28
|
+
return chunk;
|
|
29
|
+
}
|
|
30
|
+
if (utils.isArrayBufferView(chunk)) {
|
|
31
|
+
const view = chunk as ArrayBufferView;
|
|
32
|
+
return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
33
|
+
}
|
|
34
|
+
if (utils.isArrayBuffer(chunk)) {
|
|
35
|
+
return new Uint8Array(chunk as ArrayBuffer);
|
|
36
|
+
}
|
|
37
|
+
if (utils.isString(chunk) && textEncoder) {
|
|
38
|
+
return textEncoder.encode(chunk as string);
|
|
39
|
+
}
|
|
40
|
+
throw new FaxiosError(
|
|
41
|
+
"Stream chunk must be a Uint8Array, another ArrayBufferView, an ArrayBuffer or a string, got " + utils.kindOf(chunk),
|
|
42
|
+
FaxiosError.ERR_BAD_REQUEST
|
|
43
|
+
);
|
|
44
|
+
};
|
|
20
45
|
|
|
21
|
-
const streamChunk = function* (chunk:
|
|
46
|
+
const streamChunk = function* (chunk: Uint8Array, chunkSize?: number): Generator<Uint8Array> {
|
|
22
47
|
const len = chunk.byteLength;
|
|
23
48
|
|
|
24
49
|
if (!chunkSize || len < chunkSize) {
|
|
@@ -31,31 +56,31 @@ const streamChunk = function* (chunk: ByteChunk, chunkSize?: number): Generator<
|
|
|
31
56
|
|
|
32
57
|
while (pos < len) {
|
|
33
58
|
end = pos + chunkSize;
|
|
34
|
-
yield chunk.
|
|
59
|
+
yield chunk.subarray(pos, end);
|
|
35
60
|
pos = end;
|
|
36
61
|
}
|
|
37
62
|
};
|
|
38
63
|
|
|
39
|
-
const readBytes = async function* (iterable:
|
|
64
|
+
const readBytes = async function* (iterable: unknown, chunkSize?: number): AsyncGenerator<Uint8Array> {
|
|
40
65
|
for await (const chunk of readStream(iterable)) {
|
|
41
|
-
yield* streamChunk(chunk, chunkSize);
|
|
66
|
+
yield* streamChunk(toBytes(chunk), chunkSize);
|
|
42
67
|
}
|
|
43
68
|
};
|
|
44
69
|
|
|
45
70
|
type ReaderLike = {
|
|
46
|
-
read: () => Promise<{ done: boolean; value: ByteChunk; }>;
|
|
47
71
|
cancel: () => Promise<void>;
|
|
72
|
+
read: () => Promise<{ done: boolean; value: unknown; }>;
|
|
48
73
|
};
|
|
49
74
|
|
|
50
75
|
type StreamLike = {
|
|
51
|
-
[Symbol.asyncIterator]?: () => AsyncIterator<
|
|
76
|
+
[Symbol.asyncIterator]?: () => AsyncIterator<unknown>;
|
|
52
77
|
getReader?: () => ReaderLike;
|
|
53
78
|
};
|
|
54
79
|
|
|
55
|
-
const readStream = async function* (stream: unknown): AsyncGenerator<
|
|
80
|
+
const readStream = async function* (stream: unknown): AsyncGenerator<unknown> {
|
|
56
81
|
const s = stream as StreamLike;
|
|
57
82
|
if (s[Symbol.asyncIterator]) {
|
|
58
|
-
yield* s as AsyncIterable<
|
|
83
|
+
yield* s as AsyncIterable<unknown>;
|
|
59
84
|
return;
|
|
60
85
|
}
|
|
61
86
|
|
|
@@ -104,9 +129,12 @@ export const trackStream = (stream: unknown, chunkSize: number | undefined, onPr
|
|
|
104
129
|
const loadedBytes = (bytes += len);
|
|
105
130
|
onProgress(loadedBytes);
|
|
106
131
|
}
|
|
107
|
-
controller.enqueue(
|
|
132
|
+
controller.enqueue(value);
|
|
108
133
|
}
|
|
109
134
|
catch (err) {
|
|
135
|
+
// Cancel the source so its lock and connection are released. The original error wins
|
|
136
|
+
// over a failure to cancel.
|
|
137
|
+
await iterator.return(undefined).catch(() => {});
|
|
110
138
|
_onFinish(err);
|
|
111
139
|
throw err;
|
|
112
140
|
}
|