@gcmdev/faxios 0.2.0 → 0.2.2

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 (186) hide show
  1. package/LICENSE +8 -0
  2. package/dist/index.d.ts +4 -3
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/adapters/fetch-helpers.d.ts +2 -1
  7. package/dist/lib/adapters/fetch-helpers.d.ts.map +1 -0
  8. package/dist/lib/adapters/fetch.d.ts +1 -0
  9. package/dist/lib/adapters/fetch.d.ts.map +1 -0
  10. package/dist/lib/adapters/fetch.js +86 -26
  11. package/dist/lib/adapters/fetch.js.map +1 -1
  12. package/dist/lib/cancel/CanceledError.d.ts +2 -1
  13. package/dist/lib/cancel/CanceledError.d.ts.map +1 -0
  14. package/dist/lib/cancel/isCancel.d.ts +1 -0
  15. package/dist/lib/cancel/isCancel.d.ts.map +1 -0
  16. package/dist/lib/core/Faxios.d.ts +4 -3
  17. package/dist/lib/core/Faxios.d.ts.map +1 -0
  18. package/dist/lib/core/Faxios.js +8 -4
  19. package/dist/lib/core/Faxios.js.map +1 -1
  20. package/dist/lib/core/FaxiosError.d.ts +3 -2
  21. package/dist/lib/core/FaxiosError.d.ts.map +1 -0
  22. package/dist/lib/core/FaxiosHeaders.d.ts +9 -8
  23. package/dist/lib/core/FaxiosHeaders.d.ts.map +1 -0
  24. package/dist/lib/core/buildFullPath.d.ts +1 -0
  25. package/dist/lib/core/buildFullPath.d.ts.map +1 -0
  26. package/dist/lib/core/define.d.ts +20 -3
  27. package/dist/lib/core/define.d.ts.map +1 -0
  28. package/dist/lib/core/define.js.map +1 -1
  29. package/dist/lib/core/dispatchRequest.d.ts +2 -1
  30. package/dist/lib/core/dispatchRequest.d.ts.map +1 -0
  31. package/dist/lib/core/mergeConfig.d.ts +3 -2
  32. package/dist/lib/core/mergeConfig.d.ts.map +1 -0
  33. package/dist/lib/core/mergeConfig.js +40 -2
  34. package/dist/lib/core/mergeConfig.js.map +1 -1
  35. package/dist/lib/core/prepareRequest.d.ts +1 -0
  36. package/dist/lib/core/prepareRequest.d.ts.map +1 -0
  37. package/dist/lib/core/route.d.ts +10 -1
  38. package/dist/lib/core/route.d.ts.map +1 -0
  39. package/dist/lib/core/route.js +2 -5
  40. package/dist/lib/core/route.js.map +1 -1
  41. package/dist/lib/core/settle.d.ts +1 -0
  42. package/dist/lib/core/settle.d.ts.map +1 -0
  43. package/dist/lib/core/transformData.d.ts +3 -2
  44. package/dist/lib/core/transformData.d.ts.map +1 -0
  45. package/dist/lib/core/validateSchema.d.ts +3 -2
  46. package/dist/lib/core/validateSchema.d.ts.map +1 -0
  47. package/dist/lib/defaults/index.d.ts +1 -0
  48. package/dist/lib/defaults/index.d.ts.map +1 -0
  49. package/dist/lib/defaults/transitional.d.ts +1 -0
  50. package/dist/lib/defaults/transitional.d.ts.map +1 -0
  51. package/dist/lib/env/data.d.ts +2 -1
  52. package/dist/lib/env/data.d.ts.map +1 -0
  53. package/dist/lib/env/data.js +1 -1
  54. package/dist/lib/faxios.d.ts +59 -38
  55. package/dist/lib/faxios.d.ts.map +1 -0
  56. package/dist/lib/faxios.js.map +1 -1
  57. package/dist/lib/helpers/FaxiosURLSearchParams.d.ts +1 -0
  58. package/dist/lib/helpers/FaxiosURLSearchParams.d.ts.map +1 -0
  59. package/dist/lib/helpers/HttpStatusCode.d.ts +1 -0
  60. package/dist/lib/helpers/HttpStatusCode.d.ts.map +1 -0
  61. package/dist/lib/helpers/buildURL.d.ts +1 -0
  62. package/dist/lib/helpers/buildURL.d.ts.map +1 -0
  63. package/dist/lib/helpers/cloneConfig.d.ts +1 -1
  64. package/dist/lib/helpers/cloneConfig.d.ts.map +1 -0
  65. package/dist/lib/helpers/cloneConfig.js +2 -2
  66. package/dist/lib/helpers/cloneConfig.js.map +1 -1
  67. package/dist/lib/helpers/combineURLs.d.ts +1 -0
  68. package/dist/lib/helpers/combineURLs.d.ts.map +1 -0
  69. package/dist/lib/helpers/composeSignals.d.ts +1 -0
  70. package/dist/lib/helpers/composeSignals.d.ts.map +1 -0
  71. package/dist/lib/helpers/cookies.d.ts +2 -1
  72. package/dist/lib/helpers/cookies.d.ts.map +1 -0
  73. package/dist/lib/helpers/estimateDataURLDecodedBytes.d.ts +1 -0
  74. package/dist/lib/helpers/estimateDataURLDecodedBytes.d.ts.map +1 -0
  75. package/dist/lib/helpers/formDataToJSON.d.ts +2 -1
  76. package/dist/lib/helpers/formDataToJSON.d.ts.map +1 -0
  77. package/dist/lib/helpers/formDataToJSON.js +1 -1
  78. package/dist/lib/helpers/formDataToJSON.js.map +1 -1
  79. package/dist/lib/helpers/isAbsoluteURL.d.ts +1 -0
  80. package/dist/lib/helpers/isAbsoluteURL.d.ts.map +1 -0
  81. package/dist/lib/helpers/isFaxiosError.d.ts +1 -0
  82. package/dist/lib/helpers/isFaxiosError.d.ts.map +1 -0
  83. package/dist/lib/helpers/isURLSameOrigin.d.ts +1 -0
  84. package/dist/lib/helpers/isURLSameOrigin.d.ts.map +1 -0
  85. package/dist/lib/helpers/parseHeaders.d.ts +2 -1
  86. package/dist/lib/helpers/parseHeaders.d.ts.map +1 -0
  87. package/dist/lib/helpers/progressEventReducer.d.ts +1 -0
  88. package/dist/lib/helpers/progressEventReducer.d.ts.map +1 -0
  89. package/dist/lib/helpers/sanitizeHeaderValue.d.ts +1 -0
  90. package/dist/lib/helpers/sanitizeHeaderValue.d.ts.map +1 -0
  91. package/dist/lib/helpers/speedometer.d.ts +1 -0
  92. package/dist/lib/helpers/speedometer.d.ts.map +1 -0
  93. package/dist/lib/helpers/substitutePathParams.d.ts +1 -0
  94. package/dist/lib/helpers/substitutePathParams.d.ts.map +1 -0
  95. package/dist/lib/helpers/substitutePathParams.js +11 -3
  96. package/dist/lib/helpers/substitutePathParams.js.map +1 -1
  97. package/dist/lib/helpers/throttle.d.ts +1 -0
  98. package/dist/lib/helpers/throttle.d.ts.map +1 -0
  99. package/dist/lib/helpers/toFormData.d.ts +1 -0
  100. package/dist/lib/helpers/toFormData.d.ts.map +1 -0
  101. package/dist/lib/helpers/toFormData.js +4 -2
  102. package/dist/lib/helpers/toFormData.js.map +1 -1
  103. package/dist/lib/helpers/toURLEncodedForm.d.ts +1 -0
  104. package/dist/lib/helpers/toURLEncodedForm.d.ts.map +1 -0
  105. package/dist/lib/helpers/trackStream.d.ts +1 -0
  106. package/dist/lib/helpers/trackStream.d.ts.map +1 -0
  107. package/dist/lib/helpers/validator.d.ts +2 -1
  108. package/dist/lib/helpers/validator.d.ts.map +1 -0
  109. package/dist/lib/platform.d.ts +1 -0
  110. package/dist/lib/platform.d.ts.map +1 -0
  111. package/dist/lib/plugins/attempt.d.ts +1 -0
  112. package/dist/lib/plugins/attempt.d.ts.map +1 -0
  113. package/dist/lib/plugins/authBearer.d.ts +10 -5
  114. package/dist/lib/plugins/authBearer.d.ts.map +1 -0
  115. package/dist/lib/plugins/authBearer.js +6 -0
  116. package/dist/lib/plugins/authBearer.js.map +1 -1
  117. package/dist/lib/plugins/definePlugin.d.ts +4 -3
  118. package/dist/lib/plugins/definePlugin.d.ts.map +1 -0
  119. package/dist/lib/plugins/retry.d.ts +24 -23
  120. package/dist/lib/plugins/retry.d.ts.map +1 -0
  121. package/dist/lib/plugins/timing.d.ts +9 -8
  122. package/dist/lib/plugins/timing.d.ts.map +1 -0
  123. package/dist/lib/types/standard-schema.d.ts +7 -6
  124. package/dist/lib/types/standard-schema.d.ts.map +1 -0
  125. package/dist/lib/types.d.ts +104 -92
  126. package/dist/lib/types.d.ts.map +1 -0
  127. package/dist/lib/utils.d.ts +5 -3
  128. package/dist/lib/utils.d.ts.map +1 -0
  129. package/dist/lib/utils.js +9 -2
  130. package/dist/lib/utils.js.map +1 -1
  131. package/package.json +8 -4
  132. package/skills/configure-requests/SKILL.md +53 -8
  133. package/skills/configure-requests/references/plugins.md +54 -6
  134. package/src/index.ts +57 -0
  135. package/src/lib/adapters/fetch-helpers.ts +167 -0
  136. package/src/lib/adapters/fetch.ts +871 -0
  137. package/src/lib/cancel/CanceledError.ts +23 -0
  138. package/src/lib/cancel/isCancel.ts +10 -0
  139. package/src/lib/core/Faxios.ts +517 -0
  140. package/src/lib/core/FaxiosError.ts +283 -0
  141. package/src/lib/core/FaxiosHeaders.ts +529 -0
  142. package/src/lib/core/buildFullPath.ts +51 -0
  143. package/src/lib/core/define.ts +127 -0
  144. package/src/lib/core/dispatchRequest.ts +171 -0
  145. package/src/lib/core/mergeConfig.ts +213 -0
  146. package/src/lib/core/prepareRequest.ts +155 -0
  147. package/src/lib/core/route.ts +65 -0
  148. package/src/lib/core/settle.ts +20 -0
  149. package/src/lib/core/transformData.ts +23 -0
  150. package/src/lib/core/validateSchema.ts +53 -0
  151. package/src/lib/defaults/index.ts +221 -0
  152. package/src/lib/defaults/transitional.ts +9 -0
  153. package/src/lib/env/data.ts +1 -0
  154. package/src/lib/faxios.ts +306 -0
  155. package/src/lib/helpers/FaxiosURLSearchParams.ts +52 -0
  156. package/src/lib/helpers/HttpStatusCode.ts +77 -0
  157. package/src/lib/helpers/buildURL.ts +77 -0
  158. package/src/lib/helpers/cloneConfig.ts +22 -0
  159. package/src/lib/helpers/combineURLs.ts +11 -0
  160. package/src/lib/helpers/composeSignals.ts +74 -0
  161. package/src/lib/helpers/cookies.ts +68 -0
  162. package/src/lib/helpers/deprecatedMethod.ts +32 -0
  163. package/src/lib/helpers/estimateDataURLDecodedBytes.ts +95 -0
  164. package/src/lib/helpers/formDataToJSON.ts +122 -0
  165. package/src/lib/helpers/isAbsoluteURL.ts +13 -0
  166. package/src/lib/helpers/isFaxiosError.ts +19 -0
  167. package/src/lib/helpers/isURLSameOrigin.ts +16 -0
  168. package/src/lib/helpers/parseHeaders.ts +76 -0
  169. package/src/lib/helpers/progressEventReducer.ts +57 -0
  170. package/src/lib/helpers/sanitizeHeaderValue.ts +61 -0
  171. package/src/lib/helpers/speedometer.ts +55 -0
  172. package/src/lib/helpers/substitutePathParams.ts +23 -0
  173. package/src/lib/helpers/throttle.ts +45 -0
  174. package/src/lib/helpers/toFormData.ts +298 -0
  175. package/src/lib/helpers/toURLEncodedForm.ts +14 -0
  176. package/src/lib/helpers/trackStream.ts +123 -0
  177. package/src/lib/helpers/validator.ts +114 -0
  178. package/src/lib/platform.ts +44 -0
  179. package/src/lib/plugins/attempt.ts +3 -0
  180. package/src/lib/plugins/authBearer.ts +129 -0
  181. package/src/lib/plugins/definePlugin.ts +34 -0
  182. package/src/lib/plugins/retry.ts +245 -0
  183. package/src/lib/plugins/timing.ts +76 -0
  184. package/src/lib/types/standard-schema.ts +58 -0
  185. package/src/lib/types.ts +496 -0
  186. package/src/lib/utils.ts +941 -0
@@ -0,0 +1,77 @@
1
+ const HttpStatusCode = {
2
+ Continue: 100,
3
+ SwitchingProtocols: 101,
4
+ Processing: 102,
5
+ EarlyHints: 103,
6
+ Ok: 200,
7
+ Created: 201,
8
+ Accepted: 202,
9
+ NonAuthoritativeInformation: 203,
10
+ NoContent: 204,
11
+ ResetContent: 205,
12
+ PartialContent: 206,
13
+ MultiStatus: 207,
14
+ AlreadyReported: 208,
15
+ ImUsed: 226,
16
+ MultipleChoices: 300,
17
+ MovedPermanently: 301,
18
+ Found: 302,
19
+ SeeOther: 303,
20
+ NotModified: 304,
21
+ UseProxy: 305,
22
+ Unused: 306,
23
+ TemporaryRedirect: 307,
24
+ PermanentRedirect: 308,
25
+ BadRequest: 400,
26
+ Unauthorized: 401,
27
+ PaymentRequired: 402,
28
+ Forbidden: 403,
29
+ NotFound: 404,
30
+ MethodNotAllowed: 405,
31
+ NotAcceptable: 406,
32
+ ProxyAuthenticationRequired: 407,
33
+ RequestTimeout: 408,
34
+ Conflict: 409,
35
+ Gone: 410,
36
+ LengthRequired: 411,
37
+ PreconditionFailed: 412,
38
+ PayloadTooLarge: 413,
39
+ UriTooLong: 414,
40
+ UnsupportedMediaType: 415,
41
+ RangeNotSatisfiable: 416,
42
+ ExpectationFailed: 417,
43
+ ImATeapot: 418,
44
+ MisdirectedRequest: 421,
45
+ UnprocessableEntity: 422,
46
+ Locked: 423,
47
+ FailedDependency: 424,
48
+ TooEarly: 425,
49
+ UpgradeRequired: 426,
50
+ PreconditionRequired: 428,
51
+ TooManyRequests: 429,
52
+ RequestHeaderFieldsTooLarge: 431,
53
+ UnavailableForLegalReasons: 451,
54
+ InternalServerError: 500,
55
+ NotImplemented: 501,
56
+ BadGateway: 502,
57
+ ServiceUnavailable: 503,
58
+ GatewayTimeout: 504,
59
+ HttpVersionNotSupported: 505,
60
+ VariantAlsoNegotiates: 506,
61
+ InsufficientStorage: 507,
62
+ LoopDetected: 508,
63
+ NotExtended: 510,
64
+ NetworkAuthenticationRequired: 511,
65
+ WebServerIsDown: 521,
66
+ ConnectionTimedOut: 522,
67
+ OriginIsUnreachable: 523,
68
+ TimeoutOccurred: 524,
69
+ SslHandshakeFailed: 525,
70
+ InvalidSslCertificate: 526,
71
+ };
72
+
73
+ Object.entries(HttpStatusCode).forEach(([ key, value ]) => {
74
+ (HttpStatusCode as Record<number | string, number | string>)[value] = key;
75
+ });
76
+
77
+ export default HttpStatusCode;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ import type { ParamEncoder } from "../types.js";
4
+ import utils from "../utils.js";
5
+ import FaxiosURLSearchParams from "./FaxiosURLSearchParams.js";
6
+
7
+ /**
8
+ * It replaces URL-encoded forms of `:`, `$`, `,`, and spaces with
9
+ * their plain counterparts (`:`, `$`, `,`, `+`).
10
+ *
11
+ * @param {string} val The value to be encoded.
12
+ *
13
+ * @returns {string} The encoded value.
14
+ */
15
+ export function encode(val: string): string {
16
+ return encodeURIComponent(val)
17
+ .replace(/%3A/gi, ":")
18
+ .replace(/%24/g, "$")
19
+ .replace(/%2C/gi, ",")
20
+ .replace(/%20/g, "+");
21
+ }
22
+
23
+ // The request path validates `paramsSerializer.encode` as a function; this
24
+ // guard narrows the untyped option to ParamEncoder without asserting it.
25
+ function isParamEncoder(value: unknown): value is ParamEncoder {
26
+ return typeof value === "function";
27
+ }
28
+
29
+ /**
30
+ * Build a URL by appending params to the end
31
+ *
32
+ * @param {string} url The base of the url (e.g., http://www.google.com)
33
+ * @param {object} [params] The params to be appended
34
+ * @param {?(object|Function)} options
35
+ *
36
+ * @returns {string} The formatted url
37
+ */
38
+ export default function buildURL(url: string, params?: unknown, options?: unknown): string {
39
+ if (!params) {
40
+ return url;
41
+ }
42
+
43
+ const _options = utils.isFunction(options)
44
+ ? {
45
+ serialize: options,
46
+ }
47
+ : options;
48
+
49
+ // Read serializer options pollution-safely: own properties and methods on a
50
+ // class/template prototype are honored, but values injected onto a polluted
51
+ // Object.prototype are ignored.
52
+ const customEncode = utils.getSafeProp(_options, "encode");
53
+ const _encode: ParamEncoder = isParamEncoder(customEncode) ? customEncode : encode;
54
+ const serializeFn = utils.getSafeProp(_options, "serialize") as ((params: unknown, options: unknown) => string) | undefined;
55
+
56
+ let serializedParams: string | undefined;
57
+
58
+ if (serializeFn) {
59
+ serializedParams = serializeFn(params, _options);
60
+ }
61
+ else {
62
+ serializedParams = utils.isURLSearchParams(params)
63
+ ? (params as { toString: () => string; }).toString()
64
+ : new FaxiosURLSearchParams(params, _options).toString(_encode);
65
+ }
66
+
67
+ if (serializedParams) {
68
+ const hashmarkIndex = url.indexOf("#");
69
+
70
+ if (hashmarkIndex !== -1) {
71
+ url = url.slice(0, hashmarkIndex);
72
+ }
73
+ url += (url.indexOf("?") === -1 ? "?" : "&") + serializedParams;
74
+ }
75
+
76
+ return url;
77
+ }
@@ -0,0 +1,22 @@
1
+ import type { FaxiosRequestConfig } from "../types.js";
2
+ import utils from "../utils.js";
3
+
4
+ // ponytail: null-proto shallow clone; replaces mergeConfig({}, config) which ran the full
5
+ // two-config merge machinery just to get a defensive copy. Security invariants preserved:
6
+ // null-proto so fetch.ts destructuring can't inherit Object.prototype gadgets, and
7
+ // dangerous keys filtered to block prototype-pollution write paths.
8
+ export default function cloneConfig<T extends FaxiosRequestConfig>(src: T): T & Record<string, unknown> {
9
+ const dst = Object.create(null) as T & Record<string, unknown>;
10
+ Object.defineProperty(dst, "hasOwnProperty", Object.assign(Object.create(null) as PropertyDescriptor, {
11
+ value: Object.prototype.hasOwnProperty,
12
+ writable: true,
13
+ configurable: true,
14
+ enumerable: false,
15
+ }));
16
+ for (const key of Object.keys(src)) {
17
+ if (!utils.isDangerousKey(key)) {
18
+ (dst as Record<string, unknown>)[key] = (src as Record<string, unknown>)[key];
19
+ }
20
+ }
21
+ return dst;
22
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ export default function combineURLs(baseURL: string, relativeURL?: string): string {
4
+ if (!relativeURL) return baseURL;
5
+ // Scan indices, slice once — no regex (ReDoS risk on 100k-slash inputs in browser engines)
6
+ let i = baseURL.length - 1;
7
+ while (i >= 0 && baseURL.charCodeAt(i) === 47) i--;
8
+ let j = 0;
9
+ while (j < relativeURL.length && relativeURL.charCodeAt(j) === 47) j++;
10
+ return baseURL.slice(0, i + 1) + "/" + relativeURL.slice(j);
11
+ }
@@ -0,0 +1,74 @@
1
+ import CanceledError from "../cancel/CanceledError.js";
2
+ import FaxiosError from "../core/FaxiosError.js";
3
+ import utils from "../utils.js";
4
+
5
+ type AbortHandler = (this: AbortSignal & { reason?: unknown; }, reason: unknown) => void;
6
+ type EventListenerFn = (event: unknown) => void;
7
+ type SignalLike = {
8
+ aborted: boolean;
9
+ addEventListener: (type: string, listener: EventListenerFn) => void;
10
+ reason?: unknown;
11
+ removeEventListener: (type: string, listener: EventListenerFn) => void;
12
+ unsubscribe?: (() => void) | ((handler: AbortHandler) => void);
13
+ };
14
+ export type ExtendedAbortSignal = AbortSignal & { unsubscribe?: (() => void) | ((handler: AbortHandler) => void); };
15
+
16
+ const composeSignals = (signals: Array<unknown> | null | undefined, timeout?: number, timeoutMessage?: string): ExtendedAbortSignal | undefined => {
17
+ let activeSignals: Array<SignalLike> | null = signals ? (signals.filter(Boolean) as Array<SignalLike>) : [];
18
+
19
+ if (!timeout && !activeSignals.length) {
20
+ return;
21
+ }
22
+
23
+ const controller = new AbortController();
24
+
25
+ let aborted = false;
26
+
27
+ const onabort: AbortHandler = function (this: AbortSignal & { reason?: unknown; }, reason: unknown) {
28
+ if (!aborted) {
29
+ aborted = true;
30
+ unsubscribe();
31
+ const err = reason instanceof Error ? reason : this.reason;
32
+ const errMsg = err instanceof Error ? err.message : (err as string | undefined);
33
+ const abortErr = err instanceof FaxiosError ? err : new CanceledError(errMsg, undefined, undefined);
34
+ controller.abort(abortErr);
35
+ }
36
+ };
37
+
38
+ let timer: null | ReturnType<typeof setTimeout> =
39
+ timeout
40
+ ? setTimeout(() => {
41
+ timer = null;
42
+ onabort.call(controller.signal, new FaxiosError(timeoutMessage || `timeout of ${timeout}ms exceeded`, FaxiosError.ETIMEDOUT));
43
+ }, timeout)
44
+ : null;
45
+
46
+ const unsubscribe = () => {
47
+ if (!activeSignals) { return; }
48
+ if (timer) { clearTimeout(timer); }
49
+ timer = null;
50
+ activeSignals.forEach(signal => {
51
+ signal.unsubscribe
52
+ ? (signal.unsubscribe)(onabort)
53
+ : signal.removeEventListener("abort", onabort);
54
+ });
55
+ activeSignals = null;
56
+ };
57
+
58
+ // An already-aborted input never fires "abort" again, so propagate it now.
59
+ for (const signal of activeSignals) {
60
+ if (signal.aborted) {
61
+ onabort.call(signal as unknown as AbortSignal, signal.reason);
62
+ break;
63
+ }
64
+ signal.addEventListener("abort", onabort);
65
+ }
66
+
67
+ const { signal } = controller;
68
+
69
+ (signal as ExtendedAbortSignal).unsubscribe = () => utils.asap(unsubscribe);
70
+
71
+ return signal;
72
+ };
73
+
74
+ export default composeSignals;
@@ -0,0 +1,68 @@
1
+ import platform from "../platform.js";
2
+ import utils from "../utils.js";
3
+
4
+ type CookieManager = {
5
+ read: (name: string) => null | string;
6
+ remove: (name: string) => void;
7
+ write: (name: string, value: string, expires?: number, path?: string, domain?: string, secure?: boolean, sameSite?: string) => void;
8
+ };
9
+
10
+ const _globalThis = globalThis as { document?: { cookie?: string; }; };
11
+
12
+ export default platform.hasStandardBrowserEnv
13
+ ? // Standard browser envs support document.cookie
14
+ {
15
+ write(name: string, value: string, expires?: number, path?: string, domain?: string, secure?: boolean, sameSite?: string) {
16
+ if (!_globalThis.document) return;
17
+
18
+ const cookie = [ `${name}=${encodeURIComponent(value)}` ];
19
+
20
+ if (utils.isNumber(expires)) {
21
+ cookie.push(`expires=${new Date(expires!).toUTCString()}`);
22
+ }
23
+ if (utils.isString(path)) {
24
+ cookie.push(`path=${path}`);
25
+ }
26
+ if (utils.isString(domain)) {
27
+ cookie.push(`domain=${domain}`);
28
+ }
29
+ if (secure === true) {
30
+ cookie.push("secure");
31
+ }
32
+ if (utils.isString(sameSite)) {
33
+ cookie.push(`SameSite=${sameSite}`);
34
+ }
35
+
36
+ _globalThis.document.cookie = cookie.join("; ");
37
+ },
38
+
39
+ read(name: string): null | string {
40
+ if (!_globalThis.document) return null;
41
+ // Match name=value by splitting on the semicolon separator instead of building a
42
+ // RegExp from `name` — interpolating an unescaped string into a RegExp would let
43
+ // metacharacters (e.g. `.+?` in an attacker-influenced cookie name) cause ReDoS or
44
+ // match the wrong cookie. Browsers may serialize cookie pairs as either ";" or
45
+ // "; ", so ignore optional whitespace before each cookie name.
46
+ const cookies = (_globalThis.document.cookie ?? "").split(";");
47
+ for (let i = 0; i < cookies.length; i++) {
48
+ const cookie = cookies[i]!.replace(/^\s+/, "");
49
+ const eq = cookie.indexOf("=");
50
+ if (eq !== -1 && cookie.slice(0, eq) === name) {
51
+ return decodeURIComponent(cookie.slice(eq + 1));
52
+ }
53
+ }
54
+ return null;
55
+ },
56
+
57
+ remove(name: string) {
58
+ this.write(name, "", Date.now() - 86400000, "/");
59
+ },
60
+ } satisfies CookieManager
61
+ : // Non-standard browser env (web workers, react-native) lack needed support.
62
+ {
63
+ write() {},
64
+ read(): null {
65
+ return null;
66
+ },
67
+ remove() {},
68
+ } satisfies CookieManager;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ /*eslint no-console:0*/
4
+
5
+ /**
6
+ * Supply a warning to the developer that a method they are using
7
+ * has been deprecated.
8
+ *
9
+ * @param {string} method The name of the deprecated method
10
+ * @param {string} [instead] The alternate method to use if applicable
11
+ * @param {string} [docs] The documentation URL to get further details
12
+ *
13
+ * @returns {void}
14
+ */
15
+ export default function deprecatedMethod(method: string, instead?: string, docs?: string) {
16
+ try {
17
+ console.warn(
18
+ "DEPRECATED method `" +
19
+ method +
20
+ "`." +
21
+ (instead ? " Use `" + instead + "` instead." : "") +
22
+ " This method will be removed in a future release."
23
+ );
24
+
25
+ if (docs) {
26
+ console.warn("For more information about usage see " + docs);
27
+ }
28
+ }
29
+ catch {
30
+ /* Ignore */
31
+ }
32
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Estimate decoded byte length of a data:// URL *without* allocating large buffers.
3
+ * - For base64: compute exact decoded size using length and padding;
4
+ * handle %XX at the character-count level (no string allocation).
5
+ * - For non-base64: compute the exact percent-decoded UTF-8 byte length.
6
+ *
7
+ * @param {string} url
8
+ * @returns {number}
9
+ */
10
+ const isHexDigit = (charCode: number) =>
11
+ (charCode >= 48 && charCode <= 57) ||
12
+ (charCode >= 65 && charCode <= 70) ||
13
+ (charCode >= 97 && charCode <= 102);
14
+
15
+ const isPercentEncodedByte = (str: string, i: number, len: number) =>
16
+ i + 2 < len &&
17
+ isHexDigit(str.charCodeAt(i + 1)) &&
18
+ isHexDigit(str.charCodeAt(i + 2));
19
+
20
+ function countBase64Padding(body: string, len: number): number {
21
+ let pad = 0;
22
+ let i = len;
23
+ while (pad < 2 && i > 0) {
24
+ if (body.charCodeAt(i - 1) === 61 /* '=' */) {
25
+ pad++;
26
+ i--;
27
+ }
28
+ else if (i >= 3 && body.charCodeAt(i - 3) === 37 /* '%' */ && body.charCodeAt(i - 2) === 51 /* '3' */ &&
29
+ (body.charCodeAt(i - 1) === 68 || body.charCodeAt(i - 1) === 100) /* 'D'|'d' */) {
30
+ pad++;
31
+ i -= 3;
32
+ }
33
+ else {
34
+ break;
35
+ }
36
+ }
37
+ return pad;
38
+ }
39
+
40
+ function estimateBase64DecodedBytes(body: string): number {
41
+ let effectiveLen = body.length;
42
+ const len = body.length;
43
+
44
+ for (let i = 0; i < len; i++) {
45
+ if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
46
+ const a = body.charCodeAt(i + 1);
47
+ const b = body.charCodeAt(i + 2);
48
+ if (isHexDigit(a) && isHexDigit(b)) {
49
+ effectiveLen -= 2;
50
+ i += 2;
51
+ }
52
+ }
53
+ }
54
+
55
+ const pad = countBase64Padding(body, len);
56
+ const bytes = Math.floor(effectiveLen / 4) * 3 - pad;
57
+ return bytes > 0 ? bytes : 0;
58
+ }
59
+
60
+ // Returns [utf8Bytes, extraCharsToSkip]
61
+ function utf8CharBytes(body: string, i: number, len: number): [number, number] {
62
+ const c = body.charCodeAt(i);
63
+ if (c === 37 /* '%' */ && isPercentEncodedByte(body, i, len)) return [ 1, 2 ];
64
+ if (c < 0x80) return [ 1, 0 ];
65
+ if (c < 0x800) return [ 2, 0 ];
66
+ if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
67
+ const next = body.charCodeAt(i + 1);
68
+ if (next >= 0xdc00 && next <= 0xdfff) return [ 4, 1 ];
69
+ }
70
+ return [ 3, 0 ];
71
+ }
72
+
73
+ // Compute UTF-8 byte length directly from UTF-16 code units without allocating
74
+ // a byte buffer (TextEncoder.encode would defeat the DoS guard on large bodies).
75
+ function estimateUtf8BodyBytes(body: string): number {
76
+ let bytes = 0;
77
+ for (let i = 0, len = body.length; i < len; i++) {
78
+ const [ b, skip ] = utf8CharBytes(body, i, len);
79
+ bytes += b;
80
+ i += skip;
81
+ }
82
+ return bytes;
83
+ }
84
+
85
+ export default function estimateDataURLDecodedBytes(url: string): number {
86
+ if (!url || typeof url !== "string") return 0;
87
+ if (!url.startsWith("data:")) return 0;
88
+
89
+ const comma = url.indexOf(",");
90
+ if (comma < 0) return 0;
91
+
92
+ const meta = url.slice(5, comma);
93
+ const body = url.slice(comma + 1);
94
+ return /;base64/i.test(meta) ? estimateBase64DecodedBytes(body) : estimateUtf8BodyBytes(body);
95
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ import FaxiosError from "../core/FaxiosError.js";
4
+ import utils from "../utils.js";
5
+ import { DEFAULT_FORM_DATA_MAX_DEPTH } from "./toFormData.js";
6
+
7
+ const MAX_DEPTH = DEFAULT_FORM_DATA_MAX_DEPTH;
8
+
9
+ function throwIfDepthExceeded(index: number): void {
10
+ if (index > MAX_DEPTH) {
11
+ throw new FaxiosError(
12
+ "FormData field is too deeply nested (" + index + " levels). Max depth: " + MAX_DEPTH,
13
+ FaxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
14
+ );
15
+ }
16
+ }
17
+
18
+ /**
19
+ * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
20
+ *
21
+ * @param {string} name - The name of the property to get.
22
+ *
23
+ * @returns An array of strings.
24
+ */
25
+ function parsePropPath(name: string): Array<string> {
26
+ // foo[x][y][z]
27
+ // foo.x.y.z
28
+ // foo-x-y-z
29
+ // foo x y z
30
+ const path: Array<string> = [];
31
+ const pattern = /\w+|\[(\w*)]/g;
32
+ let match: null | RegExpExecArray;
33
+
34
+ while ((match = pattern.exec(name)) !== null) {
35
+ throwIfDepthExceeded(path.length);
36
+ path.push(match[0] === "[]" ? "" : (match[1] ?? match[0]));
37
+ }
38
+
39
+ return path;
40
+ }
41
+
42
+ /**
43
+ * Convert an array to an object.
44
+ *
45
+ * @param {Array<any>} arr - The array to convert to an object.
46
+ *
47
+ * @returns An object with the same keys and values as the array.
48
+ */
49
+ function arrayToObject(arr: Array<unknown>): Record<string, unknown> {
50
+ const obj: Record<string, unknown> = {};
51
+ const keys = Object.keys(arr);
52
+ let i: number;
53
+ const len = keys.length;
54
+ let key: string;
55
+ for (i = 0; i < len; i++) {
56
+ key = keys[i]!;
57
+ obj[key] = (arr as unknown as Record<string, unknown>)[key];
58
+ }
59
+ return obj;
60
+ }
61
+
62
+ /**
63
+ * It takes a FormData object and returns a JavaScript object
64
+ *
65
+ * @param {string} formData The FormData object to convert to JSON.
66
+ *
67
+ * @returns {Object<string, any> | null} The converted object.
68
+ */
69
+ function formDataToJSON(formData: unknown): null | Record<string, unknown> {
70
+ function buildPath(path: Array<string>, value: unknown, target: Record<string, unknown>, index: number): boolean {
71
+ throwIfDepthExceeded(index);
72
+
73
+ let name: number | string = path[index++]!;
74
+
75
+ if (utils.isDangerousKey(name)) return true;
76
+
77
+ const isNumericKey = Number.isFinite(+name);
78
+ const isLast = index >= path.length;
79
+ name = !name && utils.isArray(target) ? (target as Array<unknown>).length : name;
80
+
81
+ const key = String(name);
82
+
83
+ if (isLast) {
84
+ if (utils.hasOwnProp(target, key)) {
85
+ target[key] = utils.isArray(target[key])
86
+ ? (target[key] as Array<unknown>).concat(value)
87
+ : [ target[key], value ];
88
+ }
89
+ else {
90
+ target[key] = value;
91
+ }
92
+
93
+ return !isNumericKey;
94
+ }
95
+
96
+ if (!utils.hasOwnProp(target, key) || !utils.isObject(target[key])) {
97
+ target[key] = [];
98
+ }
99
+
100
+ const result = buildPath(path, value, target[key] as Record<string, unknown>, index);
101
+
102
+ if (result && utils.isArray(target[key])) {
103
+ target[key] = arrayToObject(target[key] as Array<unknown>);
104
+ }
105
+
106
+ return !isNumericKey;
107
+ }
108
+
109
+ if (utils.isFormData(formData) && utils.isFunction((formData as { entries?: unknown; }).entries)) {
110
+ const obj: Record<string, unknown> = {};
111
+
112
+ utils.forEachEntry(formData, (name: unknown, value: unknown) => {
113
+ buildPath(parsePropPath(name as string), value, obj, 0);
114
+ });
115
+
116
+ return obj;
117
+ }
118
+
119
+ return null;
120
+ }
121
+
122
+ export default formDataToJSON;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ // ponytail: protocol-relative URLs (//) intentionally not supported — HTTPS-era fork
4
+ export default function isAbsoluteURL(url: unknown): boolean {
5
+ if (typeof url !== "string") return false;
6
+ try {
7
+ new URL(url);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ import type FaxiosError from "../core/FaxiosError.js";
4
+ import utils from "../utils.js";
5
+
6
+ /**
7
+ * Determines whether the payload is an error thrown by Faxios.
8
+ *
9
+ * Checks the `isFaxiosError` brand, not `instanceof`, so errors from another
10
+ * copy of faxios still match. `T` and `D` type `response.data` and
11
+ * `config.data`; they are not checked at runtime.
12
+ *
13
+ * @param {*} payload The value to test
14
+ *
15
+ * @returns {boolean} True if the payload is an error thrown by Faxios, otherwise false
16
+ */
17
+ export default function isFaxiosError<T = unknown, D = unknown>(payload: unknown): payload is FaxiosError<T, D> {
18
+ return utils.isObject(payload) && (payload as Record<string, unknown>).isFaxiosError === true;
19
+ }
@@ -0,0 +1,16 @@
1
+ import platform from "../platform.js";
2
+
3
+ export default platform.hasStandardBrowserEnv
4
+ ? ((origin, isMSIE) => (url: string) => {
5
+ const _url = new URL(url, platform.origin);
6
+
7
+ return (
8
+ origin.protocol === _url.protocol &&
9
+ origin.host === _url.host &&
10
+ (isMSIE || origin.port === _url.port)
11
+ );
12
+ })(
13
+ new URL(platform.origin),
14
+ !!(/(msie|trident)/i.test(platform.navigator?.userAgent ?? ""))
15
+ )
16
+ : () => true;