@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.
Files changed (131) hide show
  1. package/dist/index.d.ts +3 -3
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/adapters/fetch-helpers.d.ts +1 -1
  6. package/dist/lib/adapters/fetch-helpers.d.ts.map +1 -1
  7. package/dist/lib/adapters/fetch.d.ts +4 -1
  8. package/dist/lib/adapters/fetch.d.ts.map +1 -1
  9. package/dist/lib/adapters/fetch.js +210 -92
  10. package/dist/lib/adapters/fetch.js.map +1 -1
  11. package/dist/lib/cancel/CanceledError.d.ts +1 -1
  12. package/dist/lib/cancel/CanceledError.d.ts.map +1 -1
  13. package/dist/lib/core/Faxios.d.ts +3 -3
  14. package/dist/lib/core/Faxios.d.ts.map +1 -1
  15. package/dist/lib/core/Faxios.js +8 -4
  16. package/dist/lib/core/Faxios.js.map +1 -1
  17. package/dist/lib/core/FaxiosError.d.ts +2 -2
  18. package/dist/lib/core/FaxiosError.d.ts.map +1 -1
  19. package/dist/lib/core/FaxiosHeaders.d.ts +8 -8
  20. package/dist/lib/core/FaxiosHeaders.d.ts.map +1 -1
  21. package/dist/lib/core/FaxiosHeaders.js +31 -7
  22. package/dist/lib/core/FaxiosHeaders.js.map +1 -1
  23. package/dist/lib/core/define.d.ts +3 -3
  24. package/dist/lib/core/define.d.ts.map +1 -1
  25. package/dist/lib/core/dispatchRequest.d.ts +1 -1
  26. package/dist/lib/core/dispatchRequest.d.ts.map +1 -1
  27. package/dist/lib/core/dispatchRequest.js +6 -1
  28. package/dist/lib/core/dispatchRequest.js.map +1 -1
  29. package/dist/lib/core/mergeConfig.d.ts +2 -2
  30. package/dist/lib/core/mergeConfig.d.ts.map +1 -1
  31. package/dist/lib/core/mergeConfig.js +40 -2
  32. package/dist/lib/core/mergeConfig.js.map +1 -1
  33. package/dist/lib/core/route.d.ts +1 -1
  34. package/dist/lib/core/route.d.ts.map +1 -1
  35. package/dist/lib/core/route.js +2 -5
  36. package/dist/lib/core/route.js.map +1 -1
  37. package/dist/lib/core/transformData.d.ts +2 -2
  38. package/dist/lib/core/transformData.d.ts.map +1 -1
  39. package/dist/lib/core/validateSchema.d.ts +2 -2
  40. package/dist/lib/core/validateSchema.d.ts.map +1 -1
  41. package/dist/lib/env/data.d.ts +1 -1
  42. package/dist/lib/env/data.js +1 -1
  43. package/dist/lib/faxios.d.ts +50 -50
  44. package/dist/lib/faxios.d.ts.map +1 -1
  45. package/dist/lib/helpers/cloneConfig.d.ts +0 -1
  46. package/dist/lib/helpers/cloneConfig.d.ts.map +1 -1
  47. package/dist/lib/helpers/cloneConfig.js +2 -2
  48. package/dist/lib/helpers/cloneConfig.js.map +1 -1
  49. package/dist/lib/helpers/cookies.d.ts +1 -1
  50. package/dist/lib/helpers/cookies.d.ts.map +1 -1
  51. package/dist/lib/helpers/formDataToJSON.d.ts +1 -1
  52. package/dist/lib/helpers/formDataToJSON.d.ts.map +1 -1
  53. package/dist/lib/helpers/formDataToJSON.js +1 -1
  54. package/dist/lib/helpers/formDataToJSON.js.map +1 -1
  55. package/dist/lib/helpers/parseHeaders.d.ts +1 -1
  56. package/dist/lib/helpers/parseHeaders.d.ts.map +1 -1
  57. package/dist/lib/helpers/progressEventReducer.d.ts.map +1 -1
  58. package/dist/lib/helpers/progressEventReducer.js +14 -1
  59. package/dist/lib/helpers/progressEventReducer.js.map +1 -1
  60. package/dist/lib/helpers/substitutePathParams.d.ts.map +1 -1
  61. package/dist/lib/helpers/substitutePathParams.js +11 -3
  62. package/dist/lib/helpers/substitutePathParams.js.map +1 -1
  63. package/dist/lib/helpers/toFormData.d.ts.map +1 -1
  64. package/dist/lib/helpers/toFormData.js +16 -20
  65. package/dist/lib/helpers/toFormData.js.map +1 -1
  66. package/dist/lib/helpers/trackStream.d.ts.map +1 -1
  67. package/dist/lib/helpers/trackStream.js +27 -3
  68. package/dist/lib/helpers/trackStream.js.map +1 -1
  69. package/dist/lib/helpers/validator.d.ts +1 -1
  70. package/dist/lib/helpers/validator.d.ts.map +1 -1
  71. package/dist/lib/platform.d.ts.map +1 -1
  72. package/dist/lib/plugins/authBearer.d.ts +9 -5
  73. package/dist/lib/plugins/authBearer.d.ts.map +1 -1
  74. package/dist/lib/plugins/authBearer.js +6 -0
  75. package/dist/lib/plugins/authBearer.js.map +1 -1
  76. package/dist/lib/plugins/definePlugin.d.ts +3 -3
  77. package/dist/lib/plugins/definePlugin.d.ts.map +1 -1
  78. package/dist/lib/plugins/retry.d.ts +23 -23
  79. package/dist/lib/plugins/retry.d.ts.map +1 -1
  80. package/dist/lib/plugins/timing.d.ts +8 -8
  81. package/dist/lib/plugins/timing.d.ts.map +1 -1
  82. package/dist/lib/types/standard-schema.d.ts +6 -6
  83. package/dist/lib/types/standard-schema.d.ts.map +1 -1
  84. package/dist/lib/types.d.ts +106 -92
  85. package/dist/lib/types.d.ts.map +1 -1
  86. package/dist/lib/utils.d.ts +4 -3
  87. package/dist/lib/utils.d.ts.map +1 -1
  88. package/dist/lib/utils.js +18 -5
  89. package/dist/lib/utils.js.map +1 -1
  90. package/package.json +7 -4
  91. package/skills/configure-requests/SKILL.md +14 -8
  92. package/skills/configure-requests/references/axios-differences.md +1 -1
  93. package/skills/configure-requests/references/plugins.md +37 -6
  94. package/src/index.ts +15 -15
  95. package/src/lib/adapters/fetch-helpers.ts +3 -3
  96. package/src/lib/adapters/fetch.ts +263 -144
  97. package/src/lib/cancel/CanceledError.ts +1 -1
  98. package/src/lib/core/Faxios.ts +17 -13
  99. package/src/lib/core/FaxiosError.ts +3 -3
  100. package/src/lib/core/FaxiosHeaders.ts +50 -23
  101. package/src/lib/core/define.ts +7 -7
  102. package/src/lib/core/dispatchRequest.ts +8 -3
  103. package/src/lib/core/mergeConfig.ts +42 -4
  104. package/src/lib/core/prepareRequest.ts +1 -1
  105. package/src/lib/core/route.ts +3 -6
  106. package/src/lib/core/transformData.ts +2 -2
  107. package/src/lib/core/validateSchema.ts +4 -4
  108. package/src/lib/defaults/index.ts +1 -1
  109. package/src/lib/env/data.ts +1 -1
  110. package/src/lib/faxios.ts +55 -55
  111. package/src/lib/helpers/HttpStatusCode.ts +1 -1
  112. package/src/lib/helpers/cloneConfig.ts +2 -3
  113. package/src/lib/helpers/composeSignals.ts +4 -4
  114. package/src/lib/helpers/cookies.ts +3 -3
  115. package/src/lib/helpers/formDataToJSON.ts +4 -4
  116. package/src/lib/helpers/parseHeaders.ts +2 -2
  117. package/src/lib/helpers/progressEventReducer.ts +15 -2
  118. package/src/lib/helpers/sanitizeHeaderValue.ts +1 -1
  119. package/src/lib/helpers/substitutePathParams.ts +13 -3
  120. package/src/lib/helpers/throttle.ts +1 -1
  121. package/src/lib/helpers/toFormData.ts +26 -28
  122. package/src/lib/helpers/trackStream.ts +40 -12
  123. package/src/lib/helpers/validator.ts +3 -3
  124. package/src/lib/platform.ts +4 -4
  125. package/src/lib/plugins/authBearer.ts +14 -9
  126. package/src/lib/plugins/definePlugin.ts +3 -3
  127. package/src/lib/plugins/retry.ts +27 -27
  128. package/src/lib/plugins/timing.ts +5 -5
  129. package/src/lib/types/standard-schema.ts +6 -6
  130. package/src/lib/types.ts +139 -125
  131. package/src/lib/utils.ts +30 -15
package/src/lib/types.ts CHANGED
@@ -10,30 +10,30 @@ export type StringLiteralsOrString<Literals extends string> =
10
10
  | (string & {});
11
11
 
12
12
  export type FaxiosHeaderValue =
13
- | string
14
13
  | Array<string>
15
- | number
16
14
  | boolean
17
- | null;
15
+ | null
16
+ | number
17
+ | string;
18
18
 
19
19
  export interface RawFaxiosHeaders {
20
20
  [key: string]: FaxiosHeaderValue;
21
21
  }
22
22
 
23
23
  type UppercaseMethod =
24
- | "GET"
25
24
  | "DELETE"
25
+ | "GET"
26
26
  | "HEAD"
27
+ | "LINK"
27
28
  | "OPTIONS"
28
- | "POST"
29
- | "PUT"
30
29
  | "PATCH"
30
+ | "POST"
31
31
  | "PURGE"
32
- | "LINK"
33
- | "UNLINK"
34
- | "QUERY";
32
+ | "PUT"
33
+ | "QUERY"
34
+ | "UNLINK";
35
35
 
36
- export type Method = UppercaseMethod | Lowercase<UppercaseMethod>;
36
+ export type Method = Lowercase<UppercaseMethod> | UppercaseMethod;
37
37
 
38
38
  type CommonRequestHeadersList =
39
39
  | "Accept"
@@ -51,21 +51,21 @@ type CommonRequestHeadersList =
51
51
  | "X-Requested-With";
52
52
 
53
53
  type ContentType =
54
+ | Exclude<FaxiosHeaderValue, string>
54
55
  | StringLiteralsOrString<
55
- | "text/html"
56
- | "text/plain"
57
- | "multipart/form-data"
56
+ | "application/graphql-response+json"
58
57
  | "application/json"
59
- | "application/x-www-form-urlencoded"
58
+ | "application/json-patch+json"
59
+ | "application/ld+json"
60
+ | "application/merge-patch+json"
60
61
  | "application/octet-stream"
61
62
  | "application/problem+json"
62
- | "application/ld+json"
63
+ | "application/x-www-form-urlencoded"
64
+ | "multipart/form-data"
63
65
  | "text/event-stream"
64
- | "application/graphql-response+json"
65
- | "application/merge-patch+json"
66
- | "application/json-patch+json"
67
- >
68
- | Exclude<FaxiosHeaderValue, string>;
66
+ | "text/html"
67
+ | "text/plain"
68
+ >;
69
69
 
70
70
  /**
71
71
  * A header bag: header names mapped to header values. Any header name is
@@ -86,42 +86,42 @@ export type ResponseType =
86
86
  | "arraybuffer"
87
87
  | "blob"
88
88
  | "document"
89
+ | "formdata"
89
90
  | "json"
90
- | "text"
91
+ | "response"
91
92
  | "stream"
92
- | "formdata"
93
- | "response";
93
+ | "text";
94
94
 
95
95
  type UppercaseResponseEncoding =
96
- | "ASCII"
97
96
  | "ANSI"
98
- | "BINARY"
97
+ | "ASCII"
99
98
  | "BASE64"
100
99
  | "BASE64URL"
100
+ | "BINARY"
101
101
  | "HEX"
102
102
  | "LATIN1"
103
- | "UCS-2"
104
103
  | "UCS2"
105
- | "UTF-8"
104
+ | "UCS-2"
106
105
  | "UTF8"
107
- | "UTF16LE";
106
+ | "UTF16LE"
107
+ | "UTF-8";
108
108
 
109
109
  export type responseEncoding =
110
- | UppercaseResponseEncoding
111
- | Lowercase<UppercaseResponseEncoding>;
110
+ | Lowercase<UppercaseResponseEncoding>
111
+ | UppercaseResponseEncoding;
112
112
 
113
113
  export interface TransitionalOptions {
114
- silentJSONParsing?: boolean;
115
- forcedJSONParsing?: boolean;
116
- clarifyTimeoutError?: boolean;
117
114
  advertiseZstdAcceptEncoding?: boolean;
115
+ clarifyTimeoutError?: boolean;
116
+ forcedJSONParsing?: boolean;
117
+ silentJSONParsing?: boolean;
118
118
  validateStatusUndefinedResolves?: boolean;
119
119
  }
120
120
 
121
121
  export interface GenericAbortSignal {
122
122
  readonly aborted: boolean;
123
- onabort?: ((event: Event) => void) | null;
124
123
  addEventListener?: (...args: Array<unknown>) => unknown;
124
+ onabort?: ((event: Event) => void) | null;
125
125
  removeEventListener?: (...args: Array<unknown>) => unknown;
126
126
  }
127
127
 
@@ -130,14 +130,14 @@ export interface GenericFormData {
130
130
  }
131
131
 
132
132
  export interface GenericHTMLFormElement {
133
- name: string;
134
133
  method: string;
134
+ name: string;
135
135
  submit: () => void;
136
136
  }
137
137
 
138
138
  export interface FormDataVisitorHelpers {
139
- defaultVisitor: SerializerVisitor;
140
139
  convertValue: (value: unknown) => unknown;
140
+ defaultVisitor: SerializerVisitor;
141
141
  isVisitable: (value: unknown) => boolean;
142
142
  }
143
143
 
@@ -145,19 +145,21 @@ export interface SerializerVisitor {
145
145
  (
146
146
  this: GenericFormData,
147
147
  value: unknown,
148
- key: string | number,
149
- path: null | Array<string | number>,
148
+ key: number | string,
149
+ path: Array<number | string> | null,
150
150
  helpers: FormDataVisitorHelpers,
151
151
  ): boolean;
152
152
  }
153
153
 
154
154
  export interface SerializerOptions {
155
- visitor?: SerializerVisitor;
155
+ /** FormData only: Blob constructor used to wrap `ArrayBuffer` and typed-array values. Defaults to `globalThis.Blob`. */
156
+ Blob?: new (parts: Array<BlobPart>) => Blob;
156
157
  dots?: boolean;
157
- metaTokens?: boolean;
158
158
  indexes?: boolean | null;
159
159
  /** Maximum nesting depth to serialize; deeper objects throw `ERR_FORM_DATA_DEPTH_EXCEEDED`. `Infinity` disables the check. */
160
160
  maxDepth?: number;
161
+ metaTokens?: boolean;
162
+ visitor?: SerializerVisitor;
161
163
  }
162
164
 
163
165
  // tslint:disable-next-line
@@ -180,59 +182,59 @@ type BrowserProgressEvent = unknown;
180
182
  type Milliseconds = number;
181
183
 
182
184
  export interface FaxiosProgressEvent {
183
- loaded: number;
184
- total?: number;
185
- progress?: number;
186
185
  bytes: number;
187
- rate?: number;
188
- estimated?: number;
189
- upload?: boolean;
190
186
  download?: boolean;
187
+ estimated?: number;
191
188
  event?: BrowserProgressEvent;
192
189
  lengthComputable: boolean;
190
+ loaded: number;
191
+ progress?: number;
192
+ rate?: number;
193
+ total?: number;
194
+ upload?: boolean;
193
195
  }
194
196
 
195
197
  export interface FaxiosBasicCredentials {
196
- username: string;
197
198
  password: string;
199
+ username: string;
198
200
  }
199
201
 
200
202
  // forward-declared; implemented in core/FaxiosHeaders.ts
201
203
  // Using a structural type that matches FaxiosHeaders class methods
202
204
  type HeaderMatcher =
203
- | string
205
+ | ((value: string, name: string) => boolean)
204
206
  | RegExp
205
- | ((value: string, name: string) => boolean);
207
+ | string;
206
208
 
207
- type HeaderGetResult = string | Array<string> | Record<string, string> | RegExpExecArray | true | null | undefined;
209
+ type HeaderGetResult = Array<string> | null | Record<string, string> | RegExpExecArray | string | true | undefined;
208
210
 
209
211
  export type FaxiosRequestHeaders = Record<string, FaxiosHeaderValue> & {
210
- set: (header: string | Record<string, unknown>, value?: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
211
- get: (header: string, parser?: boolean | RegExp) => HeaderGetResult;
212
- has: (header: string, matcher?: HeaderMatcher) => boolean;
213
- delete: (header: string | Array<string>, matcher?: HeaderMatcher) => boolean;
214
212
  clear: (matcher?: HeaderMatcher) => boolean;
215
- normalize: (format?: boolean) => FaxiosRequestHeaders;
216
213
  concat: (...targets: Array<unknown>) => FaxiosRequestHeaders;
217
- getContentType: (matcher?: HeaderMatcher) => HeaderGetResult;
218
- setContentType: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
219
- hasContentType: (matcher?: HeaderMatcher) => boolean;
220
- getContentLength: (matcher?: HeaderMatcher) => HeaderGetResult;
221
- setContentLength: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
222
- hasContentLength: (matcher?: HeaderMatcher) => boolean;
214
+ delete: (header: Array<string> | string, matcher?: HeaderMatcher) => boolean;
215
+ get: (header: string, parser?: boolean | RegExp) => HeaderGetResult;
223
216
  getAccept: (matcher?: HeaderMatcher) => HeaderGetResult;
224
- setAccept: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
225
- hasAccept: (matcher?: HeaderMatcher) => boolean;
226
217
  getAcceptEncoding: (matcher?: HeaderMatcher) => HeaderGetResult;
227
- setAcceptEncoding: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
228
- hasAcceptEncoding: (matcher?: HeaderMatcher) => boolean;
218
+ getAuthorization: (matcher?: HeaderMatcher) => HeaderGetResult;
219
+ getContentLength: (matcher?: HeaderMatcher) => HeaderGetResult;
220
+ getContentType: (matcher?: HeaderMatcher) => HeaderGetResult;
229
221
  getUserAgent: (matcher?: HeaderMatcher) => HeaderGetResult;
230
- setUserAgent: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
222
+ has: (header: string, matcher?: HeaderMatcher) => boolean;
223
+ hasAccept: (matcher?: HeaderMatcher) => boolean;
224
+ hasAcceptEncoding: (matcher?: HeaderMatcher) => boolean;
225
+ hasAuthorization: (matcher?: HeaderMatcher) => boolean;
226
+ hasContentLength: (matcher?: HeaderMatcher) => boolean;
227
+ hasContentType: (matcher?: HeaderMatcher) => boolean;
231
228
  hasUserAgent: (matcher?: HeaderMatcher) => boolean;
232
-
233
- getAuthorization: (matcher?: HeaderMatcher) => HeaderGetResult;
229
+ normalize: (format?: boolean) => FaxiosRequestHeaders;
230
+ set: (header: Record<string, unknown> | string, value?: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
231
+ setAccept: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
232
+ setAcceptEncoding: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
234
233
  setAuthorization: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
235
- hasAuthorization: (matcher?: HeaderMatcher) => boolean;
234
+
235
+ setContentLength: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
236
+ setContentType: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
237
+ setUserAgent: (value: FaxiosHeaderValue, rewrite?: boolean) => FaxiosRequestHeaders;
236
238
  toJSON: (asStrings?: boolean) => Record<string, FaxiosHeaderValue>;
237
239
  };
238
240
 
@@ -254,63 +256,54 @@ export interface FaxiosResponseTransformer {
254
256
  }
255
257
 
256
258
  export interface FaxiosRequestConfig<D = unknown> {
257
- url?: string;
258
- method?: StringLiteralsOrString<Method>;
259
- baseURL?: string;
260
259
  allowAbsoluteUrls?: boolean;
261
- transformRequest?: FaxiosRequestTransformer | Array<FaxiosRequestTransformer>;
262
- transformResponse?:
263
- | FaxiosResponseTransformer
264
- | Array<FaxiosResponseTransformer>;
265
- headers?: FaxiosConfigHeaders;
266
- params?: Record<string, unknown> | URLSearchParams;
267
- paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer;
268
- data?: D;
269
- timeout?: Milliseconds;
270
- timeoutErrorMessage?: string;
271
- withCredentials?: boolean;
272
260
  auth?: FaxiosBasicCredentials;
273
- responseType?: ResponseType;
274
- responseEncoding?: StringLiteralsOrString<responseEncoding>;
275
- xsrfCookieName?: string;
276
- xsrfHeaderName?: string;
277
- onUploadProgress?: (progressEvent: FaxiosProgressEvent) => void;
278
- onDownloadProgress?: (progressEvent: FaxiosProgressEvent) => void;
279
- maxContentLength?: number;
280
- validateStatus?: ((status: number) => boolean) | null;
281
- maxBodyLength?: number;
282
- transitional?: TransitionalOptions;
283
- signal?: AbortSignal | GenericAbortSignal;
261
+ baseURL?: string;
262
+ data?: D;
284
263
  env?: {
285
- /** Constructed with no arguments to serialize `multipart/form-data` payloads; `null` falls back to the global `FormData`. */
286
- FormData?: (new () => object) | null;
287
264
  fetch?: (
288
- input: string | URL | Request,
265
+ input: Request | string | URL,
289
266
  init?: RequestInit
290
267
  ) => Promise<Response>;
268
+ /** Constructed with no arguments to serialize `multipart/form-data` payloads; `null` falls back to the global `FormData`. */
269
+ FormData?: (new () => object) | null;
291
270
  /** `null` disables the constructor, e.g. when a custom `fetch` is incompatible with the global one. */
292
271
  Request?: (new (
293
- input: string | URL | Request,
272
+ input: Request | string | URL,
294
273
  init?: RequestInit,
295
274
  ) => unknown) | null;
296
275
  Response?: (new (...args: Array<unknown>) => unknown) | null;
297
276
  };
277
+ fetchOptions?: Record<string, unknown>;
278
+ formDataHeaderPolicy?: "content-only" | "legacy";
298
279
  formSerializer?: FormSerializerOptions;
299
- withXSRFToken?:
300
- | boolean
301
- | ((config: InternalFaxiosRequestConfig) => boolean | undefined);
280
+ headers?: FaxiosConfigHeaders;
281
+ maxBodyLength?: number;
282
+ maxContentLength?: number;
283
+ method?: StringLiteralsOrString<Method>;
284
+ /**
285
+ * Called with download progress. For a content-encoded response (any `Content-Encoding`
286
+ * other than `identity`) `total` is `undefined` and `lengthComputable` is `false`.
287
+ * An error thrown (or a rejected promise returned) by the callback is caught and ignored;
288
+ * the request settles normally.
289
+ */
290
+ onDownloadProgress?: (progressEvent: FaxiosProgressEvent) => void;
291
+ /**
292
+ * Called with upload progress where faxios can stream the request body, which today is
293
+ * Node.js. It is not called in browsers or web workers (see #209).
294
+ * An error thrown (or a rejected promise returned) by the callback is caught and ignored;
295
+ * the request settles normally.
296
+ */
297
+ onUploadProgress?: (progressEvent: FaxiosProgressEvent) => void;
298
+ params?: Record<string, unknown> | URLSearchParams;
299
+ paramsSchema?: StandardSchemaV1;
300
+ paramsSerializer?: CustomParamsSerializer | ParamsSerializerOptions;
302
301
  parseReviver?: (
303
302
  this: unknown,
304
303
  key: string,
305
304
  value: unknown,
306
305
  context?: { source?: string; }
307
306
  ) => unknown;
308
- fetchOptions?: Record<string, unknown>;
309
- formDataHeaderPolicy?: "legacy" | "content-only";
310
- redact?: Array<string>;
311
- responseSchema?: StandardSchemaV1;
312
- requestSchema?: StandardSchemaV1;
313
- paramsSchema?: StandardSchemaV1;
314
307
  /**
315
308
  * Values for `{key}` placeholders in `url` (braces, not `:key`). Only own properties count.
316
309
  * Each value goes through `String()` then `encodeURIComponent`. A placeholder whose key is
@@ -324,6 +317,27 @@ export interface FaxiosRequestConfig<D = unknown> {
324
317
  * A validation failure, or output that isn't a plain object, rejects with `ERR_BAD_PATH_PARAMS_SCHEMA`.
325
318
  */
326
319
  pathParamsSchema?: StandardSchemaV1<unknown, Record<string, unknown>>;
320
+ redact?: Array<string>;
321
+ requestSchema?: StandardSchemaV1;
322
+ responseEncoding?: StringLiteralsOrString<responseEncoding>;
323
+ responseSchema?: StandardSchemaV1;
324
+ responseType?: ResponseType;
325
+ signal?: AbortSignal | GenericAbortSignal;
326
+ timeout?: Milliseconds;
327
+ timeoutErrorMessage?: string;
328
+ transformRequest?: Array<FaxiosRequestTransformer> | FaxiosRequestTransformer;
329
+ transformResponse?:
330
+ | Array<FaxiosResponseTransformer>
331
+ | FaxiosResponseTransformer;
332
+ transitional?: TransitionalOptions;
333
+ url?: string;
334
+ validateStatus?: ((status: number) => boolean) | null;
335
+ withCredentials?: boolean;
336
+ withXSRFToken?:
337
+ | ((config: InternalFaxiosRequestConfig) => boolean | undefined)
338
+ | boolean;
339
+ xsrfCookieName?: string;
340
+ xsrfHeaderName?: string;
327
341
  }
328
342
 
329
343
  export type SchemaConfig<O, D = unknown> = FaxiosRequestConfig<D> & { responseSchema: StandardSchemaV1<unknown, O>; };
@@ -358,12 +372,12 @@ export interface FaxiosResponseHeadersLike {
358
372
  }
359
373
 
360
374
  export interface FaxiosResponse<T = unknown, D = unknown> {
375
+ config: InternalFaxiosRequestConfig<D>;
361
376
  data: T;
377
+ headers: FaxiosResponseHeadersLike;
378
+ request?: null | Request;
362
379
  status: number;
363
380
  statusText: string;
364
- headers: FaxiosResponseHeadersLike;
365
- config: InternalFaxiosRequestConfig<D>;
366
- request?: Request | null;
367
381
  }
368
382
 
369
383
  export type FaxiosPromise<T = unknown> = Promise<FaxiosResponse<T>>;
@@ -373,14 +387,14 @@ export interface HeadersDefaults {
373
387
  delete: RawFaxiosRequestHeaders;
374
388
  get: RawFaxiosRequestHeaders;
375
389
  head: RawFaxiosRequestHeaders;
376
- post: RawFaxiosRequestHeaders;
377
- put: RawFaxiosRequestHeaders;
378
- patch: RawFaxiosRequestHeaders;
390
+ link?: RawFaxiosRequestHeaders;
379
391
  options?: RawFaxiosRequestHeaders;
392
+ patch: RawFaxiosRequestHeaders;
393
+ post: RawFaxiosRequestHeaders;
380
394
  purge?: RawFaxiosRequestHeaders;
381
- link?: RawFaxiosRequestHeaders;
382
- unlink?: RawFaxiosRequestHeaders;
395
+ put: RawFaxiosRequestHeaders;
383
396
  query?: RawFaxiosRequestHeaders;
397
+ unlink?: RawFaxiosRequestHeaders;
384
398
  }
385
399
 
386
400
  export interface FaxiosDefaults<D = unknown> extends Omit<
@@ -397,9 +411,9 @@ export interface FaxiosDefaults<D = unknown> extends Omit<
397
411
  * `FaxiosHeaders` instance.
398
412
  */
399
413
  export type FaxiosConfigHeaders =
400
- | RawFaxiosRequestHeaders
414
+ | FaxiosHeadersInstance
401
415
  | Partial<HeadersDefaults>
402
- | FaxiosHeadersInstance;
416
+ | RawFaxiosRequestHeaders;
403
417
 
404
418
  /** Config accepted by `create()`; identical to a request config. */
405
419
  export type CreateFaxiosDefaults<D = unknown> = FaxiosRequestConfig<D>;
@@ -409,7 +423,7 @@ export type CreateFaxiosDefaults<D = unknown> = FaxiosRequestConfig<D>;
409
423
  // next middleware would read it back expecting set()/get().
410
424
  interface ContextHeaders {
411
425
  get headers(): FaxiosRequestHeaders;
412
- set headers(value: FaxiosRequestHeaders | FaxiosHeadersInstance);
426
+ set headers(value: FaxiosHeadersInstance | FaxiosRequestHeaders);
413
427
  }
414
428
 
415
429
  /**
@@ -419,12 +433,12 @@ interface ContextHeaders {
419
433
  // `{}` defaults match a FaxiosInstance with no plugins, so a plain `FaxiosMiddleware` installs on one.
420
434
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- see above
421
435
  export interface FaxiosContext<TOptions = {}, TCapabilities = {}> {
436
+ /** Values provided by installed plugins, shared by every request of the instance. */
437
+ capabilities: TCapabilities;
422
438
  /** The merged request config. `headers` is a `FaxiosHeaders` instance. */
423
439
  config: Omit<InternalFaxiosRequestConfig, "headers"> & ContextHeaders & TOptions;
424
440
  /** Null-prototype scratch space shared by middleware for this request only. */
425
441
  state: Record<PropertyKey, unknown>;
426
- /** Values provided by installed plugins, shared by every request of the instance. */
427
- capabilities: TCapabilities;
428
442
  }
429
443
 
430
444
  /**
@@ -452,9 +466,9 @@ export type FaxiosMiddleware<TOptions = {}, TCapabilities = {}> = (
452
466
  * the request options it adds to every config-taking member.
453
467
  */
454
468
  export interface FaxiosPluginSpec {
455
- requires?: unknown;
456
- provides?: unknown;
457
469
  options?: unknown;
470
+ provides?: unknown;
471
+ requires?: unknown;
458
472
  }
459
473
 
460
474
  // A slot the spec leaves out is `unknown`: nothing required, provided or added.
@@ -469,13 +483,13 @@ type OnlyPluginSlots<TSpec> = { [K in Exclude<keyof TSpec, keyof FaxiosPluginSpe
469
483
  * and `TOptions` through this.
470
484
  */
471
485
  export interface FaxiosPluginBase<TRequires = unknown, TProvides = unknown, TOptions = unknown> {
472
- name: string;
473
486
  middleware: FaxiosMiddleware<TOptions, TRequires & TProvides>;
487
+ name: string;
474
488
  /** Internal, type-only marker that carries the type parameters for inference. Never set it. */
475
489
  readonly "~plugin"?: {
476
- readonly requires: TRequires;
477
- readonly provides: TProvides;
478
490
  readonly options: TOptions;
491
+ readonly provides: TProvides;
492
+ readonly requires: TRequires;
479
493
  };
480
494
  }
481
495
 
package/src/lib/utils.ts CHANGED
@@ -8,6 +8,13 @@ const { iterator, toStringTag } = Symbol;
8
8
 
9
9
  const hasOwnProperty = (obj: unknown, prop: PropertyKey) => Object.hasOwn(obj as object, prop);
10
10
 
11
+ /**
12
+ * The one dangerous-key check: `__proto__`, `constructor` and `prototype` are skipped wherever
13
+ * config, route or form data keys are materialized into objects, to block prototype-pollution writes.
14
+ */
15
+ const isDangerousKey = (key: PropertyKey): boolean =>
16
+ key === "__proto__" || key === "constructor" || key === "prototype";
17
+
11
18
  /**
12
19
  * Walk the prototype chain (excluding the shared Object.prototype) looking for
13
20
  * an own `prop`. This distinguishes genuine own/inherited members — including
@@ -21,7 +28,7 @@ const hasOwnProperty = (obj: unknown, prop: PropertyKey) => Object.hasOwn(obj as
21
28
  * @returns {boolean} True when `prop` is owned below Object.prototype
22
29
  */
23
30
  const hasOwnInPrototypeChain = (thing: unknown, prop: PropertyKey): boolean => {
24
- let obj: object | null = thing != null && typeof thing === "object" ? thing : null;
31
+ let obj: null | object = thing != null && typeof thing === "object" ? thing : null;
25
32
  if (obj === null) return false;
26
33
  const seen: Array<object> = [];
27
34
 
@@ -34,7 +41,7 @@ const hasOwnInPrototypeChain = (thing: unknown, prop: PropertyKey): boolean => {
34
41
  if (hasOwnProperty(obj, prop)) {
35
42
  return true;
36
43
  }
37
- obj = getPrototypeOf(obj) as object | null;
44
+ obj = getPrototypeOf(obj) as null | object;
38
45
  }
39
46
  return false;
40
47
  };
@@ -390,7 +397,7 @@ function forEach(obj: unknown, fn: (value: unknown, key: unknown, obj: unknown)
390
397
  * @param {string} key - The key to find (case-insensitive).
391
398
  * @returns {?string} The actual key name if found, otherwise null.
392
399
  */
393
- function findKey(obj: unknown, key: string): string | null {
400
+ function findKey(obj: unknown, key: string): null | string {
394
401
  if (isBuffer(obj)) {
395
402
  return null;
396
403
  }
@@ -411,8 +418,8 @@ function findKey(obj: unknown, key: string): string | null {
411
418
  type GlobalWithEvents = typeof globalThis & {
412
419
  addEventListener?: (type: string, listener: (event: Record<string, unknown>) => void, capture?: boolean) => void;
413
420
  postMessage?: (message: unknown, targetOrigin: string) => void;
414
- setImmediate?: (cb: () => void) => void;
415
421
  process?: { nextTick?: (cb: () => void) => void; };
422
+ setImmediate?: (cb: () => void) => void;
416
423
  };
417
424
  const _global = globalThis as GlobalWithEvents;
418
425
 
@@ -437,20 +444,23 @@ const isContextDefined = (context: unknown) => !isUndefined(context) && context
437
444
  * @returns {Object} Result of all merge properties
438
445
  */
439
446
  function merge(this: unknown, ...objs: Array<unknown>): Record<string, unknown> {
440
- const ctx = (isContextDefined(this) && this) as { caseless?: unknown; skipUndefined?: unknown; } | false;
447
+ const ctx = (isContextDefined(this) && this) as false | { caseless?: unknown; skipUndefined?: unknown; };
441
448
  const caseless = ctx && ctx.caseless;
442
449
  const skipUndefined = ctx && ctx.skipUndefined;
443
450
  const result: Record<string | symbol, unknown> = {};
451
+ // Caseless mode: lowercased key -> the key already written to `result`. Only assignValue
452
+ // writes to `result`, so this index is complete.
453
+ const caselessKeys = new Map<string, string>();
444
454
  const assignValue = (val: unknown, key: unknown) => {
445
455
  const keyStr = key as string | symbol;
446
456
  // Skip dangerous property names to prevent prototype pollution
447
- if (keyStr === "__proto__" || keyStr === "constructor" || keyStr === "prototype") {
457
+ if (isDangerousKey(keyStr)) {
448
458
  return;
449
459
  }
450
460
 
451
- // findKey lowercases the key, so caseless lookup only applies to strings —
452
- // symbol keys are identity-matched.
453
- const targetKey: string | symbol = (caseless && typeof keyStr === "string" ? (findKey(result, keyStr) ?? (keyStr)) : (keyStr));
461
+ // Caseless lookup only applies to strings — symbol keys are identity-matched.
462
+ const lowerKey = caseless && typeof keyStr === "string" ? keyStr.toLowerCase() : undefined;
463
+ const targetKey: string | symbol = (lowerKey === undefined ? keyStr : (caselessKeys.get(lowerKey) ?? keyStr));
454
464
  // Read via own-prop only — a bare `result[targetKey]` walks the prototype
455
465
  // chain, so a polluted Object.prototype value could surface here and get
456
466
  // copied into the merged result.
@@ -467,6 +477,9 @@ function merge(this: unknown, ...objs: Array<unknown>): Record<string, unknown>
467
477
  else if (!skipUndefined || !isUndefined(val)) {
468
478
  result[targetKey] = val;
469
479
  }
480
+ if (lowerKey !== undefined && hasOwnProperty(result, targetKey)) {
481
+ caselessKeys.set(lowerKey, targetKey as string);
482
+ }
470
483
  };
471
484
 
472
485
  for (let i = 0, l = objs.length; i < l; i++) {
@@ -556,7 +569,8 @@ const toFlatObject = (sourceObj: unknown, destObj?: Record<string, unknown>, fil
556
569
  let props: Array<string>;
557
570
  let i: number;
558
571
  let prop: string | undefined;
559
- const merged: Record<string, boolean> = {};
572
+ // Null prototype: a polluted Object.prototype[prop] must not mark an own prop as already copied.
573
+ const merged: Record<string, boolean> = Object.create(null);
560
574
 
561
575
  const dest: Record<string, unknown> = destObj ?? {};
562
576
 
@@ -596,7 +610,7 @@ const toArray = (thing?: unknown): Array<unknown> | null => {
596
610
  * @returns {Array}
597
611
  */
598
612
 
599
- const isTypedArray = ((TypedArray: false | (abstract new (...args: Array<unknown>) => unknown)) =>
613
+ const isTypedArray = ((TypedArray: (abstract new (...args: Array<unknown>) => unknown) | false) =>
600
614
 
601
615
  (thing: unknown) => TypedArray && thing instanceof TypedArray
602
616
  )(typeof Uint8Array !== "undefined" && getPrototypeOf(Uint8Array) as abstract new (...args: Array<unknown>) => unknown);
@@ -616,7 +630,7 @@ const forEachEntry = (obj: unknown, fn: (key: unknown, value: unknown) => void)
616
630
  * @returns {Array<boolean>}
617
631
  */
618
632
  const matchAll = (regExp: RegExp, str: string) => {
619
- let matches: RegExpExecArray | null;
633
+ let matches: null | RegExpExecArray;
620
634
  const arr: Array<RegExpExecArray> = [];
621
635
 
622
636
  while ((matches = regExp.exec(str)) !== null) {
@@ -644,7 +658,7 @@ const { propertyIsEnumerable } = Object.prototype;
644
658
  */
645
659
  const isRegExp = kindOfTest("RegExp");
646
660
 
647
- const reduceDescriptors = (obj: object, reducer: (descriptor: PropertyDescriptor, name: string, obj: object) => PropertyDescriptor | false | undefined) => {
661
+ const reduceDescriptors = (obj: object, reducer: (descriptor: PropertyDescriptor, name: string, obj: object) => false | PropertyDescriptor | undefined) => {
648
662
  const descriptors = Object.getOwnPropertyDescriptors(obj);
649
663
  const reducedDescriptors: PropertyDescriptorMap = {};
650
664
 
@@ -665,7 +679,7 @@ const reduceDescriptors = (obj: object, reducer: (descriptor: PropertyDescriptor
665
679
 
666
680
  const freezeMethods = (obj: object) => {
667
681
  // eslint-disable-next-line sonarjs/function-return-type
668
- reduceDescriptors(obj, (descriptor, name): PropertyDescriptor | false => {
682
+ reduceDescriptors(obj, (descriptor, name): false | PropertyDescriptor => {
669
683
  // skip restricted props in strict mode
670
684
  if (isFunction(obj) && [ "arguments", "caller", "callee" ].includes(name)) {
671
685
  return false;
@@ -759,7 +773,7 @@ const toJSONObject = (obj: unknown): unknown => {
759
773
  if (!("toJSON" in source)) {
760
774
  // add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
761
775
  visited.add(source);
762
- const target: Record<string | number, unknown> = isArray(source) ? ([] as Record<number, unknown>) : {};
776
+ const target: Record<number | string, unknown> = isArray(source) ? ([] as Record<number, unknown>) : {};
763
777
 
764
778
  forEach(source, (value, key) => {
765
779
  const reducedValue = visit(value);
@@ -910,6 +924,7 @@ export default {
910
924
  isHTMLForm,
911
925
  hasOwnProperty,
912
926
  hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
927
+ isDangerousKey,
913
928
  hasOwnInPrototypeChain,
914
929
  getSafeProp,
915
930
  reduceDescriptors,