@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,23 @@
1
+ "use strict";
2
+
3
+ import FaxiosError from "../core/FaxiosError.js";
4
+ import type { FaxiosRequestConfig, InternalFaxiosRequestConfig } from "../types.js";
5
+
6
+ class CanceledError extends FaxiosError {
7
+ /**
8
+ * A `CanceledError` is an object that is thrown when an operation is canceled.
9
+ *
10
+ * @param {string=} message The message.
11
+ * @param {Object=} config The config.
12
+ * @param {Object=} request The request.
13
+ *
14
+ * @returns {CanceledError} The created error.
15
+ */
16
+ constructor(message?: null | string, config?: FaxiosRequestConfig, request?: unknown) {
17
+ super(message == null ? "canceled" : message, FaxiosError.ERR_CANCELED, config as InternalFaxiosRequestConfig, request);
18
+ this.name = "CanceledError";
19
+ (this as unknown as Record<string, unknown>)["__CANCEL__"] = true;
20
+ }
21
+ }
22
+
23
+ export default CanceledError;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ import type CanceledError from "./CanceledError.js";
4
+
5
+ // Checks the `__CANCEL__` flag CanceledError sets, not `instanceof`, so
6
+ // cancellations from another copy of faxios still match. The flag is a plain
7
+ // writable property, so any object carrying it is narrowed.
8
+ export default function isCancel(value: unknown): value is CanceledError {
9
+ return !!(value && (value as Record<string, unknown>).__CANCEL__);
10
+ }
@@ -0,0 +1,517 @@
1
+ "use strict";
2
+
3
+ import CanceledError from "../cancel/CanceledError.js";
4
+ import buildURL from "../helpers/buildURL.js";
5
+ import cloneConfig from "../helpers/cloneConfig.js";
6
+ import validator from "../helpers/validator.js";
7
+ import type { ValidatorFn } from "../helpers/validator.js";
8
+ import type {
9
+ FaxiosContext,
10
+ FaxiosMiddleware,
11
+ FaxiosNext,
12
+ FaxiosPluginArgument,
13
+ FaxiosRequestConfig,
14
+ FaxiosRequestHeaders,
15
+ FaxiosResponse,
16
+ GenericAbortSignal,
17
+ HeadersDefaults,
18
+ InternalFaxiosRequestConfig,
19
+ Method,
20
+ SchemaConfig,
21
+ StringLiteralsOrString
22
+ } from "../types.js";
23
+ import type { StandardSchemaV1 } from "../types/standard-schema.js";
24
+ import utils from "../utils.js";
25
+ import buildFullPath from "./buildFullPath.js";
26
+ import { createDefinedEndpoint } from "./define.js";
27
+ import type { DefineConfig, DefinedEndpoint } from "./define.js";
28
+ import dispatchRequest from "./dispatchRequest.js";
29
+ import FaxiosError from "./FaxiosError.js";
30
+ import FaxiosHeaders from "./FaxiosHeaders.js";
31
+ import mergeConfig from "./mergeConfig.js";
32
+ import type { RouteBuilder, RouteConfig } from "./route.js";
33
+ import { createRouteBuilder } from "./route.js";
34
+
35
+ type TransitionalFn = (
36
+ validator: false | undefined | ValidatorFn,
37
+ version?: string,
38
+ message?: string
39
+ ) => ValidatorFn;
40
+ type SpellingFn = (correctSpelling: string) => ValidatorFn;
41
+ const validators = validator.validators as Record<
42
+ string,
43
+ undefined | ValidatorFn
44
+ > & {
45
+ spelling?: SpellingFn;
46
+ transitional?: TransitionalFn;
47
+ };
48
+
49
+ // Every method header group declared on HeadersDefaults. `satisfies` keeps this
50
+ // list exhaustive, so a group the types accept can never reach the wire.
51
+ const METHOD_HEADER_GROUPS = Object.keys({
52
+ common: true,
53
+ delete: true,
54
+ get: true,
55
+ head: true,
56
+ options: true,
57
+ post: true,
58
+ put: true,
59
+ patch: true,
60
+ purge: true,
61
+ link: true,
62
+ unlink: true,
63
+ query: true,
64
+ } satisfies Record<keyof HeadersDefaults, true>) as Array<keyof HeadersDefaults>;
65
+
66
+ function patchErrorStack(err: Error): void {
67
+ let dummy: { stack?: string; } = {};
68
+ // captureStackTrace is V8-only (Node, Chromium); fall back elsewhere.
69
+ const captureStackTrace = (Error as { captureStackTrace?: (target: object) => void; }).captureStackTrace;
70
+ if (captureStackTrace) {
71
+ captureStackTrace(dummy);
72
+ }
73
+ else {
74
+ dummy = new Error();
75
+ }
76
+
77
+ const rawStack = dummy.stack ?? "";
78
+ const firstNewline = rawStack.indexOf("\n");
79
+ // slice off the Error: ... line
80
+ const stack = firstNewline === -1 ? "" : rawStack.slice(firstNewline + 1);
81
+
82
+ try {
83
+ if (!err.stack) {
84
+ err.stack = stack;
85
+ // match without the 2 top stack lines
86
+ }
87
+ else if (stack) {
88
+ const firstNewlineIndex = stack.indexOf("\n");
89
+ const secondNewlineIndex =
90
+ firstNewlineIndex === -1
91
+ ? -1
92
+ : stack.indexOf("\n", firstNewlineIndex + 1);
93
+ const stackWithoutTwoTopLines =
94
+ secondNewlineIndex === -1
95
+ ? ""
96
+ : stack.slice(secondNewlineIndex + 1);
97
+
98
+ if (!String(err.stack).endsWith(stackWithoutTwoTopLines)) {
99
+ err.stack += "\n" + stack;
100
+ }
101
+ }
102
+ }
103
+ catch {
104
+ // ignore the case where "stack" is an un-writable property
105
+ }
106
+ }
107
+
108
+ function normalizeParamsSerializer(config: FaxiosRequestConfig): void {
109
+ const { paramsSerializer } = config;
110
+ if (paramsSerializer == null) return;
111
+
112
+ if (utils.isFunction(paramsSerializer)) {
113
+ config.paramsSerializer = {
114
+ serialize: paramsSerializer as (
115
+ params: Record<string, unknown>
116
+ ) => string,
117
+ };
118
+ }
119
+ else {
120
+ validator.assertOptions(
121
+ paramsSerializer,
122
+ {
123
+ encode: validators.function!,
124
+ serialize: validators.function!,
125
+ },
126
+ true
127
+ );
128
+ }
129
+ }
130
+
131
+ function resolveAllowAbsoluteUrls(
132
+ config: FaxiosRequestConfig,
133
+ defaults: FaxiosRequestConfig
134
+ ): void {
135
+ if (config.allowAbsoluteUrls === undefined) {
136
+ // Own reads only: instance defaults may be a plain object (the default instance's are).
137
+ const allowAbsoluteUrls = utils.hasOwnProp(defaults, "allowAbsoluteUrls") ? defaults.allowAbsoluteUrls : undefined;
138
+ const baseURL = utils.hasOwnProp(defaults, "baseURL") ? defaults.baseURL : undefined;
139
+ config.allowAbsoluteUrls = allowAbsoluteUrls ?? !baseURL;
140
+ }
141
+ }
142
+
143
+ // The registry is untyped: each entry was checked against its instance's options and capabilities
144
+ // when use() accepted it, and the runtime only forwards contexts between entries.
145
+ type AnyContextMiddleware = FaxiosMiddleware<unknown, unknown>;
146
+ type AnyContextNext = FaxiosNext<unknown, unknown>;
147
+
148
+ type MiddlewareEntry = {
149
+ provided: Array<string>;
150
+ // The value passed to use(), kept only for eject()'s identity check.
151
+ ref: unknown;
152
+ run: AnyContextMiddleware;
153
+ };
154
+
155
+ function composeMiddleware(entries: ReadonlyArray<MiddlewareEntry>, dispatch: AnyContextNext): AnyContextNext {
156
+ // Plain closures, no async wrapper: a middleware that calls next() before awaiting reaches the
157
+ // adapter in the same tick, exactly as a request without middleware does.
158
+ return entries.reduceRight<AnyContextNext>((next, entry) => ctx => entry.run(ctx, next), dispatch);
159
+ }
160
+
161
+ // Each dispatch works on its own copy, so dispatch's in-place writes (path-param substitution,
162
+ // transformRequest, schema output, header normalization) never reach ctx.config, and a middleware
163
+ // that calls next() again starts from the same input.
164
+ function copyForDispatch(config: InternalFaxiosRequestConfig): InternalFaxiosRequestConfig {
165
+ const copy = cloneConfig(config);
166
+ copy.headers = new FaxiosHeaders(config.headers) as unknown as FaxiosRequestHeaders;
167
+ return copy;
168
+ }
169
+
170
+ // Middleware is caller code that may await anything, so the caller's abort settles the request
171
+ // right away instead of waiting for it. Dispatch still checks the signal before the adapter call,
172
+ // so nothing is sent after an abort either way. An already-aborted request runs no middleware.
173
+ function settleOnAbort(
174
+ run: () => Promise<FaxiosResponse>,
175
+ signal: AbortSignal | GenericAbortSignal,
176
+ config: InternalFaxiosRequestConfig
177
+ ): Promise<FaxiosResponse> {
178
+ if (signal.aborted) return Promise.reject(new CanceledError(null, config));
179
+ const { addEventListener: add, removeEventListener: remove } = signal;
180
+ if (typeof add !== "function") return run();
181
+ return new Promise((resolve, reject) => {
182
+ const stop = () => remove?.call(signal, "abort", onAbort);
183
+ function onAbort() {
184
+ stop();
185
+ reject(new CanceledError(null, config));
186
+ }
187
+ // Listen before running: middleware may abort the signal before its first await.
188
+ add.call(signal, "abort", onAbort);
189
+ // The executor calls run() right away and turns a synchronous throw into a rejection, which
190
+ // Promise.resolve(run()) wouldn't, and .then(run) would delay dispatch by a tick.
191
+ // eslint-disable-next-line sonarjs/prefer-promise-shorthand -- see above
192
+ const pending = new Promise<FaxiosResponse>(_resolve => {
193
+ _resolve(run());
194
+ });
195
+ // Once the abort has settled the request, this result has nowhere to go; the handlers below
196
+ // still consume it, so it never becomes an unhandled rejection.
197
+ pending.finally(stop).then(resolve)
198
+ .catch(reject);
199
+ });
200
+ }
201
+
202
+ // Middleware registration isn't a Faxios member: the callable instance from create() reaches it
203
+ // through these, and its FaxiosInstance["use"] is the one place plugins are typed and checked.
204
+ // The registry itself is untyped, so the class has nothing to type-check against.
205
+ let useMiddleware!: (faxios: Faxios, middleware: AnyContextMiddleware | FaxiosPluginArgument) => void;
206
+ let ejectMiddleware!: (faxios: Faxios, middleware: unknown) => void;
207
+
208
+ /**
209
+ * Create a new instance of Faxios
210
+ *
211
+ * @param {Object} instanceConfig The default config for the instance
212
+ *
213
+ * @return {Faxios} A new instance of Faxios
214
+ */
215
+ class Faxios {
216
+ defaults: FaxiosRequestConfig;
217
+ #middleware: ReadonlyArray<MiddlewareEntry> = [];
218
+ // Middleware and capabilities are replaced, never mutated, on use()/eject(): a request keeps the
219
+ // snapshot it started with, and composes nothing per call.
220
+ #composed: AnyContextNext | null = null;
221
+ #capabilities: Record<string, unknown> = Object.create(null);
222
+
223
+ constructor(instanceConfig?: FaxiosRequestConfig) {
224
+ this.defaults = instanceConfig || {};
225
+ }
226
+
227
+ static {
228
+ useMiddleware = (faxios, middleware) => {
229
+ faxios.#use(middleware);
230
+ };
231
+ ejectMiddleware = (faxios, middleware) => {
232
+ faxios.#eject(middleware);
233
+ };
234
+ }
235
+
236
+ // Middleware runs in registration order before dispatch and in reverse order after it.
237
+ #use(middleware: AnyContextMiddleware | FaxiosPluginArgument): void {
238
+ const plugin = typeof middleware === "function" ? null : middleware;
239
+ // Plugins are caller objects: only their own fields count, so a polluted Object.prototype
240
+ // can't supply middleware or capabilities (THREATMODEL T-R4b).
241
+ const own = <K extends keyof FaxiosPluginArgument>(key: K) =>
242
+ (plugin && utils.hasOwnProp(plugin, key) ? plugin[key] : undefined);
243
+ const run = plugin ? own("middleware") : middleware;
244
+ if (typeof run !== "function") {
245
+ throw new FaxiosError("use() expects a middleware function or a plugin with a middleware function", FaxiosError.ERR_BAD_OPTION_VALUE);
246
+ }
247
+ const name = own("name");
248
+ if (plugin && (typeof name !== "string" || name === "")) {
249
+ throw new FaxiosError("use() expects a plugin's own name to be a non-empty string", FaxiosError.ERR_BAD_OPTION_VALUE);
250
+ }
251
+ const provides = own("provides");
252
+ const provided = provides == null ? [] : this.#addCapabilities(String(name), provides);
253
+ this.#setMiddleware([ ...this.#middleware, { ref: middleware, run, provided }]);
254
+ }
255
+
256
+ // Removes middleware or a plugin registered with use(), by reference. In-flight requests keep
257
+ // the snapshot they started with.
258
+ #eject(middleware: unknown): void {
259
+ const index = this.#middleware.findIndex(entry => entry.ref === middleware);
260
+ if (index === -1) return;
261
+ const capabilities = Object.assign(Object.create(null) as Record<string, unknown>, this.#capabilities);
262
+ for (const key of this.#middleware[index]!.provided) {
263
+ delete capabilities[key];
264
+ }
265
+ this.#capabilities = capabilities;
266
+ this.#setMiddleware(this.#middleware.filter((_, i) => i !== index));
267
+ }
268
+
269
+ #setMiddleware(entries: ReadonlyArray<MiddlewareEntry>): void {
270
+ this.#middleware = entries;
271
+ this.#composed = entries.length === 0
272
+ ? null
273
+ : composeMiddleware(entries, ctx => dispatchRequest(copyForDispatch(ctx.config)));
274
+ }
275
+
276
+ #addCapabilities(pluginName: string, provides: unknown): Array<string> {
277
+ const source = provides as Record<string, unknown>;
278
+ const keys = Object.keys(source).filter(key => !utils.isDangerousKey(key));
279
+ for (const key of keys) {
280
+ if (utils.hasOwnProp(this.#capabilities, key)) {
281
+ throw new FaxiosError(`Plugin "${pluginName}" provides capability "${key}", which another plugin already provides`, FaxiosError.ERR_BAD_OPTION);
282
+ }
283
+ }
284
+ this.#capabilities = Object.assign(Object.create(null) as Record<string, unknown>, this.#capabilities);
285
+ for (const key of keys) {
286
+ this.#capabilities[key] = source[key];
287
+ }
288
+ return keys;
289
+ }
290
+
291
+ /**
292
+ * Dispatch a request
293
+ *
294
+ * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)
295
+ * @param {?Object} config
296
+ *
297
+ * @returns {Promise} The Promise to be fulfilled
298
+ */
299
+
300
+ async request<O, D = unknown>(config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
301
+ async request<T = unknown, R = FaxiosResponse<T>, D = unknown>(configOrUrl: FaxiosRequestConfig<D> | string, config?: FaxiosRequestConfig<D>): Promise<R>;
302
+ async request(
303
+ configOrUrl: FaxiosRequestConfig | string,
304
+ config?: FaxiosRequestConfig
305
+ ) {
306
+ try {
307
+ return await this.#request(configOrUrl, config);
308
+ }
309
+ catch (err) {
310
+ if (err instanceof Error) {
311
+ patchErrorStack(err);
312
+ }
313
+
314
+ throw err;
315
+ }
316
+ }
317
+
318
+ async #request(
319
+ configOrUrl: FaxiosRequestConfig | string,
320
+ config?: FaxiosRequestConfig
321
+ ): Promise<unknown> {
322
+ /*eslint no-param-reassign:0*/
323
+ // Allow for faxios('example/url'[, config]) a la fetch API
324
+ if (typeof configOrUrl === "string") {
325
+ config = config || {};
326
+ config.url = configOrUrl;
327
+ }
328
+ else {
329
+ config = configOrUrl;
330
+ }
331
+
332
+ config = mergeConfig(this.defaults, config);
333
+
334
+ const { transitional, headers } = config;
335
+
336
+ if (transitional !== undefined) {
337
+ validator.assertOptions(
338
+ transitional,
339
+ {
340
+ silentJSONParsing: validators.transitional!(validators.boolean),
341
+ forcedJSONParsing: validators.transitional!(validators.boolean),
342
+ clarifyTimeoutError: validators.transitional!(validators.boolean),
343
+ advertiseZstdAcceptEncoding: validators.transitional!(
344
+ validators.boolean
345
+ ),
346
+ validateStatusUndefinedResolves: validators.transitional!(
347
+ validators.boolean
348
+ ),
349
+ },
350
+ false
351
+ );
352
+ }
353
+
354
+ normalizeParamsSerializer(config);
355
+ resolveAllowAbsoluteUrls(config, this.defaults);
356
+
357
+ validator.assertOptions(
358
+ config,
359
+ {
360
+ baseUrl: validators.spelling!("baseURL"),
361
+ withXsrfToken: validators.spelling!("withXSRFToken"),
362
+ },
363
+ true
364
+ );
365
+
366
+ // Set config.method
367
+ const defaultMethod = utils.hasOwnProp(this.defaults, "method") ? this.defaults.method : undefined;
368
+ config.method = (
369
+ (config.method || defaultMethod || "get") as string
370
+ ).toLowerCase();
371
+
372
+ // Flatten headers
373
+ // Every FaxiosConfigHeaders member is a string-keyed object, so this is a
374
+ // checked widening, not an assertion: mergeConfig spreads a top-level
375
+ // FaxiosHeaders, and method header groups are typed as plain header bags.
376
+ const h: Record<string, unknown> | undefined = headers;
377
+ let contextHeaders = h && utils.merge(h.common, h[config.method]);
378
+
379
+ if (h) {
380
+ for (const group of METHOD_HEADER_GROUPS) {
381
+ delete h[group];
382
+ }
383
+ }
384
+
385
+ config.headers = FaxiosHeaders.concat(
386
+ contextHeaders,
387
+ ...(h ? [ h as unknown as null ] : [])
388
+ );
389
+
390
+ const composed = this.#composed;
391
+ if (!composed) return dispatchRequest(config as InternalFaxiosRequestConfig);
392
+
393
+ const ctx: FaxiosContext = {
394
+ config: config as InternalFaxiosRequestConfig,
395
+ state: Object.create(null),
396
+ capabilities: this.#capabilities,
397
+ };
398
+ const signal = utils.hasOwnProp(config, "signal") ? config.signal : undefined;
399
+ return signal ? settleOnAbort(() => composed(ctx), signal, ctx.config) : composed(ctx);
400
+ }
401
+
402
+ get<O, D = unknown>(url: string, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
403
+ get<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D>): Promise<R>;
404
+ get(url: string, config?: FaxiosRequestConfig) {
405
+ return this.request(mergeConfig(config || {}, {
406
+ method: "get",
407
+ url,
408
+ data: config && utils.hasOwnProp(config, "data") ? config.data : undefined,
409
+ }));
410
+ }
411
+
412
+ delete<O, D = unknown>(url: string, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
413
+ delete<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D>): Promise<R>;
414
+ delete(url: string, config?: FaxiosRequestConfig) {
415
+ return this.request(mergeConfig(config || {}, {
416
+ method: "delete",
417
+ url,
418
+ data: config && utils.hasOwnProp(config, "data") ? config.data : undefined,
419
+ }));
420
+ }
421
+
422
+ head<O, D = unknown>(url: string, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
423
+ head<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D>): Promise<R>;
424
+ head(url: string, config?: FaxiosRequestConfig) {
425
+ return this.request(mergeConfig(config || {}, {
426
+ method: "head",
427
+ url,
428
+ data: config && utils.hasOwnProp(config, "data") ? config.data : undefined,
429
+ }));
430
+ }
431
+
432
+ options<O, D = unknown>(url: string, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
433
+ options<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, config?: FaxiosRequestConfig<D>): Promise<R>;
434
+ options(url: string, config?: FaxiosRequestConfig) {
435
+ return this.request(mergeConfig(config || {}, {
436
+ method: "options",
437
+ url,
438
+ data: config && utils.hasOwnProp(config, "data") ? config.data : undefined,
439
+ }));
440
+ }
441
+
442
+ post<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
443
+ post<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
444
+ post(url: string, data?: unknown, config?: FaxiosRequestConfig) {
445
+ return this.request(mergeConfig(config || {}, { method: "post", headers: {}, url, data }));
446
+ }
447
+
448
+ postForm<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
449
+ postForm<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
450
+ postForm(url: string, data?: unknown, config?: FaxiosRequestConfig) {
451
+ return this.request(mergeConfig(config || {}, { method: "post", headers: { "Content-Type": "multipart/form-data" }, url, data }));
452
+ }
453
+
454
+ put<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
455
+ put<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
456
+ put(url: string, data?: unknown, config?: FaxiosRequestConfig) {
457
+ return this.request(mergeConfig(config || {}, { method: "put", headers: {}, url, data }));
458
+ }
459
+
460
+ putForm<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
461
+ putForm<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
462
+ putForm(url: string, data?: unknown, config?: FaxiosRequestConfig) {
463
+ return this.request(mergeConfig(config || {}, { method: "put", headers: { "Content-Type": "multipart/form-data" }, url, data }));
464
+ }
465
+
466
+ patch<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
467
+ patch<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
468
+ patch(url: string, data?: unknown, config?: FaxiosRequestConfig) {
469
+ return this.request(mergeConfig(config || {}, { method: "patch", headers: {}, url, data }));
470
+ }
471
+
472
+ patchForm<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
473
+ patchForm<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
474
+ patchForm(url: string, data?: unknown, config?: FaxiosRequestConfig) {
475
+ return this.request(mergeConfig(config || {}, { method: "patch", headers: { "Content-Type": "multipart/form-data" }, url, data }));
476
+ }
477
+
478
+ query<O, D = unknown>(url: string, data: D | undefined, config: SchemaConfig<O, D>): Promise<FaxiosResponse<O, D>>;
479
+ query<T = unknown, R = FaxiosResponse<T>, D = unknown>(url: string, data?: D, config?: FaxiosRequestConfig<D>): Promise<R>;
480
+ query(url: string, data?: unknown, config?: FaxiosRequestConfig) {
481
+ return this.request(mergeConfig(config || {}, { method: "query", headers: {}, url, data }));
482
+ }
483
+
484
+ getUri(config?: FaxiosRequestConfig) {
485
+ config = mergeConfig(this.defaults, config);
486
+ const fullPath = buildFullPath(
487
+ config.baseURL,
488
+ config.url,
489
+ config.allowAbsoluteUrls,
490
+ config
491
+ );
492
+ return buildURL(fullPath, config.params, config.paramsSerializer);
493
+ }
494
+
495
+ define<
496
+ PP extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined,
497
+ P extends StandardSchemaV1 | undefined = undefined,
498
+ D extends StandardSchemaV1 | undefined = undefined,
499
+ R extends StandardSchemaV1 | undefined = undefined
500
+ >(
501
+ method: StringLiteralsOrString<Method>,
502
+ url: string,
503
+ config?: DefineConfig<PP, P, D, R>
504
+ ): DefinedEndpoint<PP, P, D, R> {
505
+ return createDefinedEndpoint(this, method, url, config);
506
+ }
507
+
508
+ route<PP extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined>(
509
+ url: string,
510
+ config?: RouteConfig<PP>
511
+ ): RouteBuilder<PP> {
512
+ return createRouteBuilder(this, url, config);
513
+ }
514
+ }
515
+
516
+ export { ejectMiddleware, useMiddleware };
517
+ export default Faxios;