@gcmdev/faxios 0.1.0 → 0.2.1

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 (210) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +40 -1774
  3. package/dist/index.d.ts +9 -6
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/adapters/fetch-helpers.d.ts +1 -0
  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 +23 -3
  11. package/dist/lib/adapters/fetch.js.map +1 -1
  12. package/dist/lib/cancel/CanceledError.d.ts +1 -0
  13. package/dist/lib/cancel/CanceledError.d.ts.map +1 -0
  14. package/dist/lib/cancel/isCancel.d.ts +3 -1
  15. package/dist/lib/cancel/isCancel.d.ts.map +1 -0
  16. package/dist/lib/cancel/isCancel.js +3 -0
  17. package/dist/lib/cancel/isCancel.js.map +1 -1
  18. package/dist/lib/core/Faxios.d.ts +6 -17
  19. package/dist/lib/core/Faxios.d.ts.map +1 -0
  20. package/dist/lib/core/Faxios.js +144 -76
  21. package/dist/lib/core/Faxios.js.map +1 -1
  22. package/dist/lib/core/FaxiosError.d.ts +19 -6
  23. package/dist/lib/core/FaxiosError.d.ts.map +1 -0
  24. package/dist/lib/core/FaxiosError.js +16 -1
  25. package/dist/lib/core/FaxiosError.js.map +1 -1
  26. package/dist/lib/core/FaxiosHeaders.d.ts +12 -8
  27. package/dist/lib/core/FaxiosHeaders.d.ts.map +1 -0
  28. package/dist/lib/core/FaxiosHeaders.js +1 -0
  29. package/dist/lib/core/FaxiosHeaders.js.map +1 -1
  30. package/dist/lib/core/buildFullPath.d.ts +1 -0
  31. package/dist/lib/core/buildFullPath.d.ts.map +1 -0
  32. package/dist/lib/core/define.d.ts +19 -2
  33. package/dist/lib/core/define.d.ts.map +1 -0
  34. package/dist/lib/core/define.js.map +1 -1
  35. package/dist/lib/core/dispatchRequest.d.ts +1 -0
  36. package/dist/lib/core/dispatchRequest.d.ts.map +1 -0
  37. package/dist/lib/core/dispatchRequest.js +4 -0
  38. package/dist/lib/core/dispatchRequest.js.map +1 -1
  39. package/dist/lib/core/mergeConfig.d.ts +1 -0
  40. package/dist/lib/core/mergeConfig.d.ts.map +1 -0
  41. package/dist/lib/core/prepareRequest.d.ts +1 -0
  42. package/dist/lib/core/prepareRequest.d.ts.map +1 -0
  43. package/dist/lib/core/prepareRequest.js +1 -20
  44. package/dist/lib/core/prepareRequest.js.map +1 -1
  45. package/dist/lib/core/route.d.ts +11 -2
  46. package/dist/lib/core/route.d.ts.map +1 -0
  47. package/dist/lib/core/route.js.map +1 -1
  48. package/dist/lib/core/settle.d.ts +1 -0
  49. package/dist/lib/core/settle.d.ts.map +1 -0
  50. package/dist/lib/core/transformData.d.ts +1 -0
  51. package/dist/lib/core/transformData.d.ts.map +1 -0
  52. package/dist/lib/core/validateSchema.d.ts +1 -0
  53. package/dist/lib/core/validateSchema.d.ts.map +1 -0
  54. package/dist/lib/defaults/index.d.ts +1 -0
  55. package/dist/lib/defaults/index.d.ts.map +1 -0
  56. package/dist/lib/defaults/index.js +3 -3
  57. package/dist/lib/defaults/index.js.map +1 -1
  58. package/dist/lib/defaults/transitional.d.ts +1 -1
  59. package/dist/lib/defaults/transitional.d.ts.map +1 -0
  60. package/dist/lib/defaults/transitional.js +0 -1
  61. package/dist/lib/defaults/transitional.js.map +1 -1
  62. package/dist/lib/env/data.d.ts +2 -1
  63. package/dist/lib/env/data.d.ts.map +1 -0
  64. package/dist/lib/env/data.js +1 -1
  65. package/dist/lib/env/data.js.map +1 -1
  66. package/dist/lib/faxios.d.ts +115 -48
  67. package/dist/lib/faxios.d.ts.map +1 -0
  68. package/dist/lib/faxios.js +14 -2
  69. package/dist/lib/faxios.js.map +1 -1
  70. package/dist/lib/helpers/FaxiosURLSearchParams.d.ts +3 -1
  71. package/dist/lib/helpers/FaxiosURLSearchParams.d.ts.map +1 -0
  72. package/dist/lib/helpers/FaxiosURLSearchParams.js.map +1 -1
  73. package/dist/lib/helpers/HttpStatusCode.d.ts +1 -0
  74. package/dist/lib/helpers/HttpStatusCode.d.ts.map +1 -0
  75. package/dist/lib/helpers/buildURL.d.ts +1 -0
  76. package/dist/lib/helpers/buildURL.d.ts.map +1 -0
  77. package/dist/lib/helpers/buildURL.js +7 -1
  78. package/dist/lib/helpers/buildURL.js.map +1 -1
  79. package/dist/lib/helpers/cloneConfig.d.ts +4 -0
  80. package/dist/lib/helpers/cloneConfig.d.ts.map +1 -0
  81. package/dist/lib/helpers/cloneConfig.js +21 -0
  82. package/dist/lib/helpers/cloneConfig.js.map +1 -0
  83. package/dist/lib/helpers/combineURLs.d.ts +1 -0
  84. package/dist/lib/helpers/combineURLs.d.ts.map +1 -0
  85. package/dist/lib/helpers/composeSignals.d.ts +1 -0
  86. package/dist/lib/helpers/composeSignals.d.ts.map +1 -0
  87. package/dist/lib/helpers/composeSignals.js +8 -1
  88. package/dist/lib/helpers/composeSignals.js.map +1 -1
  89. package/dist/lib/helpers/cookies.d.ts +1 -0
  90. package/dist/lib/helpers/cookies.d.ts.map +1 -0
  91. package/dist/lib/helpers/estimateDataURLDecodedBytes.d.ts +1 -0
  92. package/dist/lib/helpers/estimateDataURLDecodedBytes.d.ts.map +1 -0
  93. package/dist/lib/helpers/formDataToJSON.d.ts +1 -0
  94. package/dist/lib/helpers/formDataToJSON.d.ts.map +1 -0
  95. package/dist/lib/helpers/isAbsoluteURL.d.ts +1 -0
  96. package/dist/lib/helpers/isAbsoluteURL.d.ts.map +1 -0
  97. package/dist/lib/helpers/isFaxiosError.d.ts +8 -2
  98. package/dist/lib/helpers/isFaxiosError.d.ts.map +1 -0
  99. package/dist/lib/helpers/isFaxiosError.js +5 -1
  100. package/dist/lib/helpers/isFaxiosError.js.map +1 -1
  101. package/dist/lib/helpers/isURLSameOrigin.d.ts +1 -0
  102. package/dist/lib/helpers/isURLSameOrigin.d.ts.map +1 -0
  103. package/dist/lib/helpers/parseHeaders.d.ts +1 -0
  104. package/dist/lib/helpers/parseHeaders.d.ts.map +1 -0
  105. package/dist/lib/helpers/progressEventReducer.d.ts +1 -0
  106. package/dist/lib/helpers/progressEventReducer.d.ts.map +1 -0
  107. package/dist/lib/helpers/sanitizeHeaderValue.d.ts +1 -0
  108. package/dist/lib/helpers/sanitizeHeaderValue.d.ts.map +1 -0
  109. package/dist/lib/helpers/speedometer.d.ts +1 -0
  110. package/dist/lib/helpers/speedometer.d.ts.map +1 -0
  111. package/dist/lib/helpers/substitutePathParams.d.ts +1 -0
  112. package/dist/lib/helpers/substitutePathParams.d.ts.map +1 -0
  113. package/dist/lib/helpers/throttle.d.ts +1 -0
  114. package/dist/lib/helpers/throttle.d.ts.map +1 -0
  115. package/dist/lib/helpers/toFormData.d.ts +1 -0
  116. package/dist/lib/helpers/toFormData.d.ts.map +1 -0
  117. package/dist/lib/helpers/toURLEncodedForm.d.ts +1 -0
  118. package/dist/lib/helpers/toURLEncodedForm.d.ts.map +1 -0
  119. package/dist/lib/helpers/trackStream.d.ts +1 -0
  120. package/dist/lib/helpers/trackStream.d.ts.map +1 -0
  121. package/dist/lib/helpers/validator.d.ts +1 -0
  122. package/dist/lib/helpers/validator.d.ts.map +1 -0
  123. package/dist/lib/platform.d.ts +2 -1
  124. package/dist/lib/platform.d.ts.map +1 -0
  125. package/dist/lib/plugins/attempt.d.ts +2 -0
  126. package/dist/lib/plugins/attempt.d.ts.map +1 -0
  127. package/dist/lib/plugins/attempt.js +4 -0
  128. package/dist/lib/plugins/attempt.js.map +1 -0
  129. package/dist/lib/plugins/authBearer.d.ts +31 -0
  130. package/dist/lib/plugins/authBearer.d.ts.map +1 -0
  131. package/dist/lib/plugins/authBearer.js +99 -0
  132. package/dist/lib/plugins/authBearer.js.map +1 -0
  133. package/dist/lib/plugins/definePlugin.d.ts +22 -0
  134. package/dist/lib/plugins/definePlugin.d.ts.map +1 -0
  135. package/dist/lib/plugins/definePlugin.js +14 -0
  136. package/dist/lib/plugins/definePlugin.js.map +1 -0
  137. package/dist/lib/plugins/retry.d.ts +66 -0
  138. package/dist/lib/plugins/retry.d.ts.map +1 -0
  139. package/dist/lib/plugins/retry.js +168 -0
  140. package/dist/lib/plugins/retry.js.map +1 -0
  141. package/dist/lib/plugins/timing.d.ts +32 -0
  142. package/dist/lib/plugins/timing.d.ts.map +1 -0
  143. package/dist/lib/plugins/timing.js +53 -0
  144. package/dist/lib/plugins/timing.js.map +1 -0
  145. package/dist/lib/types/standard-schema.d.ts +1 -0
  146. package/dist/lib/types/standard-schema.d.ts.map +1 -0
  147. package/dist/lib/types.d.ts +125 -34
  148. package/dist/lib/types.d.ts.map +1 -0
  149. package/dist/lib/utils.d.ts +1 -0
  150. package/dist/lib/utils.d.ts.map +1 -0
  151. package/package.json +42 -19
  152. package/skills/configure-requests/SKILL.md +380 -0
  153. package/skills/configure-requests/references/axios-differences.md +67 -0
  154. package/skills/configure-requests/references/plugins.md +127 -0
  155. package/src/index.ts +57 -0
  156. package/src/lib/adapters/fetch-helpers.ts +167 -0
  157. package/src/lib/adapters/fetch.ts +810 -0
  158. package/src/lib/cancel/CanceledError.ts +23 -0
  159. package/src/lib/cancel/isCancel.ts +10 -0
  160. package/src/lib/core/Faxios.ts +513 -0
  161. package/src/lib/core/FaxiosError.ts +283 -0
  162. package/src/lib/core/FaxiosHeaders.ts +529 -0
  163. package/src/lib/core/buildFullPath.ts +51 -0
  164. package/src/lib/core/define.ts +127 -0
  165. package/src/lib/core/dispatchRequest.ts +171 -0
  166. package/src/lib/core/mergeConfig.ts +175 -0
  167. package/src/lib/core/prepareRequest.ts +155 -0
  168. package/src/lib/core/route.ts +68 -0
  169. package/src/lib/core/settle.ts +20 -0
  170. package/src/lib/core/transformData.ts +23 -0
  171. package/src/lib/core/validateSchema.ts +53 -0
  172. package/src/lib/defaults/index.ts +221 -0
  173. package/src/lib/defaults/transitional.ts +9 -0
  174. package/src/lib/env/data.ts +1 -0
  175. package/src/lib/faxios.ts +306 -0
  176. package/src/lib/helpers/FaxiosURLSearchParams.ts +52 -0
  177. package/src/lib/helpers/HttpStatusCode.ts +77 -0
  178. package/src/lib/helpers/buildURL.ts +77 -0
  179. package/src/lib/helpers/cloneConfig.ts +23 -0
  180. package/src/lib/helpers/combineURLs.ts +11 -0
  181. package/src/lib/helpers/composeSignals.ts +74 -0
  182. package/src/lib/helpers/cookies.ts +68 -0
  183. package/src/lib/helpers/deprecatedMethod.ts +32 -0
  184. package/src/lib/helpers/estimateDataURLDecodedBytes.ts +95 -0
  185. package/src/lib/helpers/formDataToJSON.ts +122 -0
  186. package/src/lib/helpers/isAbsoluteURL.ts +13 -0
  187. package/src/lib/helpers/isFaxiosError.ts +19 -0
  188. package/src/lib/helpers/isURLSameOrigin.ts +16 -0
  189. package/src/lib/helpers/parseHeaders.ts +76 -0
  190. package/src/lib/helpers/progressEventReducer.ts +57 -0
  191. package/src/lib/helpers/sanitizeHeaderValue.ts +61 -0
  192. package/src/lib/helpers/speedometer.ts +55 -0
  193. package/src/lib/helpers/substitutePathParams.ts +13 -0
  194. package/src/lib/helpers/throttle.ts +45 -0
  195. package/src/lib/helpers/toFormData.ts +296 -0
  196. package/src/lib/helpers/toURLEncodedForm.ts +14 -0
  197. package/src/lib/helpers/trackStream.ts +123 -0
  198. package/src/lib/helpers/validator.ts +114 -0
  199. package/src/lib/platform.ts +44 -0
  200. package/src/lib/plugins/attempt.ts +3 -0
  201. package/src/lib/plugins/authBearer.ts +124 -0
  202. package/src/lib/plugins/definePlugin.ts +34 -0
  203. package/src/lib/plugins/retry.ts +245 -0
  204. package/src/lib/plugins/timing.ts +76 -0
  205. package/src/lib/types/standard-schema.ts +58 -0
  206. package/src/lib/types.ts +496 -0
  207. package/src/lib/utils.ts +932 -0
  208. package/dist/lib/core/InterceptorManager.d.ts +0 -9
  209. package/dist/lib/core/InterceptorManager.js +0 -28
  210. package/dist/lib/core/InterceptorManager.js.map +0 -1
@@ -0,0 +1,529 @@
1
+ // @ts-self-types="./FaxiosHeaders.d.ts" — required for Deno: types.d.ts imports FaxiosHeadersInstance from here
2
+ "use strict";
3
+
4
+ import parseHeaders from "../helpers/parseHeaders.js";
5
+ import { sanitizeHeaderValue } from "../helpers/sanitizeHeaderValue.js";
6
+ import type { FaxiosHeaderValue } from "../types.js";
7
+ import utils from "../utils.js";
8
+
9
+ const $internals = Symbol("internals");
10
+
11
+ type HeaderMatcher =
12
+ | string
13
+ | RegExp
14
+ | ((this: FaxiosHeaders, value: string, name: string) => boolean);
15
+
16
+ type HeaderInput =
17
+ | Record<string, unknown>
18
+ | FaxiosHeaders
19
+ | string
20
+ | undefined
21
+ | null;
22
+
23
+ /** Matches a `FaxiosHeaders` instance by its type-only brand. */
24
+ export type FaxiosHeadersInstance = Pick<FaxiosHeaders, typeof faxiosHeadersBrand>;
25
+
26
+ function normalizeHeader(header: string): string {
27
+ return header && String(header).trim()
28
+ .toLowerCase();
29
+ }
30
+
31
+ // eslint-disable-next-line sonarjs/function-return-type
32
+ function normalizeValue(
33
+ value: FaxiosHeaderValue | undefined
34
+ ): string | Array<string> | false | null | undefined {
35
+ if (value == null) {
36
+ return value;
37
+ }
38
+ if (value === false) {
39
+ return false;
40
+ }
41
+ if (utils.isArray(value)) {
42
+ return (value as Array<FaxiosHeaderValue>).map(normalizeValue) as Array<string>;
43
+ }
44
+ return sanitizeHeaderValue(String(value));
45
+ }
46
+
47
+ function parseTokens(str: string): Record<string, string> {
48
+ const tokens: Record<string, string> = Object.create(null);
49
+ const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;
50
+ let match;
51
+
52
+ while ((match = tokensRE.exec(str))) {
53
+ tokens[match[1]!] = match[2]!;
54
+ }
55
+
56
+ return tokens;
57
+ }
58
+
59
+ const isValidHeaderName = (str: string): boolean =>
60
+ /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());
61
+
62
+ function matchHeaderValue(
63
+ context: FaxiosHeaders,
64
+ value: unknown,
65
+ header: string,
66
+ filter:
67
+ | string
68
+ | RegExp
69
+ | ((this: FaxiosHeaders, value: string, name: string) => boolean)
70
+ | undefined,
71
+ isHeaderNameFilter?: boolean
72
+ ): boolean | undefined {
73
+ if (utils.isFunction(filter)) {
74
+ return (
75
+ filter as (this: FaxiosHeaders, value: string, name: string) => boolean
76
+ ).call(context, value as string, header);
77
+ }
78
+
79
+ if (isHeaderNameFilter) {
80
+ value = header;
81
+ }
82
+
83
+ if (!utils.isString(value)) return undefined;
84
+
85
+ if (utils.isString(filter)) {
86
+ return (value as string).indexOf(filter as string) !== -1;
87
+ }
88
+
89
+ if (utils.isRegExp(filter)) {
90
+ return (filter as RegExp).test(value as string);
91
+ }
92
+ return undefined;
93
+ }
94
+
95
+ function formatHeader(header: string): string {
96
+ return header
97
+ .trim()
98
+ .toLowerCase()
99
+ .replace(/([a-z\d])(\w*)/g, (_w, char, str) => char.toUpperCase() + str);
100
+ }
101
+
102
+ function iterableToHeaders(header: Iterable<unknown>): Record<string, unknown> {
103
+ const obj: Record<string, unknown> = Object.create(null);
104
+ for (const entry of header) {
105
+ if (!utils.isArray(entry)) {
106
+ throw new TypeError("Object iterator must return a key-value pair");
107
+ }
108
+ const key = (entry as Array<unknown>)[0] as string;
109
+ const val = (entry as Array<unknown>)[1];
110
+ if (utils.hasOwnProp(obj, key)) {
111
+ const dest = obj[key];
112
+ obj[key] = utils.isArray(dest) ? [ ...(dest as Array<unknown>), val ] : [ dest, val ];
113
+ }
114
+ else {
115
+ obj[key] = val;
116
+ }
117
+ }
118
+ return obj;
119
+ }
120
+
121
+ function buildAccessors(obj: object, header: string): void {
122
+ const accessorName = utils.toCamelCase(" " + header);
123
+
124
+ [ "get", "set", "has" ].forEach(methodName => {
125
+ Object.defineProperty(
126
+ obj,
127
+ methodName + accessorName,
128
+ Object.assign(Object.create(null) as PropertyDescriptor, {
129
+ value: function (
130
+ this: FaxiosHeaders,
131
+ arg1: unknown,
132
+ arg2: unknown,
133
+ arg3: unknown
134
+ ) {
135
+ return (
136
+ this as unknown as Record<
137
+ string,
138
+ ((...args: Array<unknown>) => unknown) | undefined
139
+ >
140
+ )[methodName]!.call(this, header, arg1, arg2, arg3);
141
+ },
142
+ configurable: true,
143
+ })
144
+ );
145
+ });
146
+ }
147
+
148
+ declare const faxiosHeadersBrand: unique symbol;
149
+
150
+ class FaxiosHeaders {
151
+ [key: string]: unknown;
152
+
153
+ // Type-only brand (nothing at runtime): lets config types accept an instance
154
+ // without its index signature or method names leaking into header-name completions.
155
+ declare readonly [faxiosHeadersBrand]: true;
156
+
157
+ // Accessors generated at runtime by FaxiosHeaders.accessor([...]) below.
158
+ // Declared here so consumers get real types instead of the index signature.
159
+ declare getContentType: (matcher?: HeaderMatcher) => FaxiosHeaderValue | undefined;
160
+ declare setContentType: (value: FaxiosHeaderValue, rewrite?: boolean) => this;
161
+ declare hasContentType: (matcher?: HeaderMatcher) => boolean;
162
+ declare getContentLength: (matcher?: HeaderMatcher) => FaxiosHeaderValue | undefined;
163
+ declare setContentLength: (value: FaxiosHeaderValue, rewrite?: boolean) => this;
164
+ declare hasContentLength: (matcher?: HeaderMatcher) => boolean;
165
+ declare getAccept: (matcher?: HeaderMatcher) => FaxiosHeaderValue | undefined;
166
+ declare setAccept: (value: FaxiosHeaderValue, rewrite?: boolean) => this;
167
+ declare hasAccept: (matcher?: HeaderMatcher) => boolean;
168
+ declare getAcceptEncoding: (matcher?: HeaderMatcher) => FaxiosHeaderValue | undefined;
169
+ declare setAcceptEncoding: (value: FaxiosHeaderValue, rewrite?: boolean) => this;
170
+ declare hasAcceptEncoding: (matcher?: HeaderMatcher) => boolean;
171
+ declare getUserAgent: (matcher?: HeaderMatcher) => FaxiosHeaderValue | undefined;
172
+ declare setUserAgent: (value: FaxiosHeaderValue, rewrite?: boolean) => this;
173
+ declare hasUserAgent: (matcher?: HeaderMatcher) => boolean;
174
+ declare getAuthorization: (matcher?: HeaderMatcher) => FaxiosHeaderValue | undefined;
175
+ declare setAuthorization: (value: FaxiosHeaderValue, rewrite?: boolean) => this;
176
+ declare hasAuthorization: (matcher?: HeaderMatcher) => boolean;
177
+
178
+ constructor(
179
+ headers?: Record<string, unknown> | FaxiosHeaders | string | null
180
+ ) {
181
+ headers && this.set(headers);
182
+ }
183
+
184
+ set(
185
+ header: HeaderInput,
186
+ valueOrRewrite?: unknown,
187
+ rewrite?: boolean
188
+ ): this {
189
+ const self = this;
190
+
191
+ function setHeader(
192
+ _value: unknown,
193
+ _header: string,
194
+ _rewrite: unknown
195
+ ): void {
196
+ const lHeader = normalizeHeader(_header);
197
+
198
+ if (!lHeader) {
199
+ return;
200
+ }
201
+
202
+ const key = utils.findKey(self, lHeader) as string | undefined;
203
+
204
+ if (
205
+ !key ||
206
+ (self as Record<string, unknown>)[key] === undefined ||
207
+ _rewrite === true ||
208
+ (_rewrite === undefined &&
209
+ (self as Record<string, unknown>)[key] !== false &&
210
+ (self as Record<string, unknown>)[key] !== null)
211
+ ) {
212
+ (self as Record<string, unknown>)[key || _header] = normalizeValue(
213
+ _value as FaxiosHeaderValue
214
+ );
215
+ }
216
+ }
217
+
218
+ const setHeaders = (headers: object, _rewrite: unknown): void =>
219
+ utils.forEach(headers, (_value: unknown, _header: unknown) =>
220
+ setHeader(_value, _header as string, _rewrite)
221
+ );
222
+
223
+ if (utils.isPlainObject(header) || header instanceof this.constructor) {
224
+ setHeaders(header as object, valueOrRewrite);
225
+ }
226
+ else if (utils.isString(header)) {
227
+ header = (header as string).trim();
228
+ if (!isValidHeaderName(header)) {
229
+ setHeaders(parseHeaders(header), valueOrRewrite);
230
+ }
231
+ else {
232
+ setHeader(valueOrRewrite, header, rewrite);
233
+ }
234
+ }
235
+ else if (utils.isObject(header) && utils.isSafeIterable(header)) {
236
+ setHeaders(iterableToHeaders(header as Iterable<unknown>), valueOrRewrite);
237
+ }
238
+ else {
239
+ header != null && setHeader(valueOrRewrite, header as string, rewrite);
240
+ }
241
+
242
+ return this;
243
+ }
244
+
245
+ get(header: string): FaxiosHeaderValue | undefined;
246
+ get(header: string, parser: true): Record<string, string> | undefined;
247
+ get(header: string, parser: RegExp): RegExpExecArray | null | undefined;
248
+ get<R>(header: string, parser: (this: FaxiosHeaders, value: FaxiosHeaderValue, header: string) => R): R | undefined;
249
+ get(
250
+ header: string,
251
+ parser?:
252
+ | RegExp
253
+ | ((
254
+ this: FaxiosHeaders,
255
+ value: FaxiosHeaderValue,
256
+ header: string
257
+ ) => unknown)
258
+ | true
259
+ ): unknown {
260
+ header = normalizeHeader(header);
261
+
262
+ if (header) {
263
+ const key = utils.findKey(this, header) as string | undefined;
264
+
265
+ if (key) {
266
+ const value = (this as Record<string, unknown>)[
267
+ key
268
+ ] as FaxiosHeaderValue;
269
+
270
+ if (!parser) {
271
+ return value;
272
+ }
273
+
274
+ if (parser === true) {
275
+ return parseTokens(value as string);
276
+ }
277
+
278
+ if (utils.isFunction(parser)) {
279
+ return (
280
+ parser as (
281
+ this: FaxiosHeaders,
282
+ value: FaxiosHeaderValue,
283
+ header: string
284
+ ) => unknown
285
+ ).call(this, value, key);
286
+ }
287
+
288
+ if (utils.isRegExp(parser)) {
289
+ return (parser as RegExp).exec(value as string);
290
+ }
291
+
292
+ throw new TypeError("parser must be boolean|regexp|function");
293
+ }
294
+ }
295
+ return undefined;
296
+ }
297
+
298
+ has(header: string, matcher?: HeaderMatcher): boolean {
299
+ header = normalizeHeader(header);
300
+
301
+ if (header) {
302
+ const key = utils.findKey(this, header) as string | undefined;
303
+
304
+ return !!(
305
+ key &&
306
+ (this as Record<string, unknown>)[key] !== undefined &&
307
+ (!matcher ||
308
+ matchHeaderValue(
309
+ this,
310
+ (this as Record<string, unknown>)[key],
311
+ key,
312
+ matcher
313
+ ))
314
+ );
315
+ }
316
+
317
+ return false;
318
+ }
319
+
320
+ delete(header: string | Array<string>, matcher?: HeaderMatcher): boolean {
321
+ const self = this;
322
+ let deleted = false;
323
+
324
+ function deleteHeader(_header: string): void {
325
+ _header = normalizeHeader(_header);
326
+
327
+ if (_header) {
328
+ const key = utils.findKey(self, _header) as string | undefined;
329
+
330
+ if (
331
+ key &&
332
+ (!matcher ||
333
+ matchHeaderValue(
334
+ self,
335
+ (self as Record<string, unknown>)[key],
336
+ key,
337
+ matcher
338
+ ))
339
+ ) {
340
+ delete (self as Record<string, unknown>)[key];
341
+
342
+ deleted = true;
343
+ }
344
+ }
345
+ }
346
+
347
+ if (utils.isArray(header)) {
348
+ header.forEach(deleteHeader);
349
+ }
350
+ else {
351
+ deleteHeader(header);
352
+ }
353
+
354
+ return deleted;
355
+ }
356
+
357
+ clear(matcher?: HeaderMatcher): boolean {
358
+ const keys = Object.keys(this);
359
+ let i = keys.length;
360
+ let deleted = false;
361
+
362
+ while (i--) {
363
+ const key = keys[i]!;
364
+ if (
365
+ !matcher ||
366
+ matchHeaderValue(
367
+ this,
368
+ (this as Record<string, unknown>)[key],
369
+ key,
370
+ matcher,
371
+ true
372
+ )
373
+ ) {
374
+ delete (this as Record<string, unknown>)[key];
375
+ deleted = true;
376
+ }
377
+ }
378
+
379
+ return deleted;
380
+ }
381
+
382
+ normalize(format: boolean = false): this {
383
+ const self = this;
384
+ const headers: Record<string, unknown> = {};
385
+
386
+ utils.forEach(this, (value: unknown, _header: unknown) => {
387
+ const header = _header as string;
388
+ const key = utils.findKey(headers, header) as string | undefined;
389
+
390
+ if (key) {
391
+ (self as Record<string, unknown>)[key] = normalizeValue(
392
+ value as FaxiosHeaderValue
393
+ );
394
+ delete (self as Record<string, unknown>)[header];
395
+ return;
396
+ }
397
+
398
+ const normalized = format ? formatHeader(header) : String(header).trim();
399
+
400
+ if (normalized !== header) {
401
+ delete (self as Record<string, unknown>)[header];
402
+ }
403
+
404
+ (self as Record<string, unknown>)[normalized] = normalizeValue(
405
+ value as FaxiosHeaderValue
406
+ );
407
+
408
+ headers[normalized] = true;
409
+ });
410
+
411
+ return this;
412
+ }
413
+
414
+ concat(...targets: Array<HeaderInput>): FaxiosHeaders {
415
+ return (this.constructor as typeof FaxiosHeaders).concat(this, ...targets);
416
+ }
417
+
418
+ toJSON(asStrings?: boolean): Record<string, unknown> {
419
+ const obj: Record<string, unknown> = Object.create(null);
420
+
421
+ utils.forEach(this, (value: unknown, _header: unknown) => {
422
+ const header = _header as string;
423
+ value != null &&
424
+ value !== false &&
425
+ (obj[header] =
426
+ asStrings && utils.isArray(value)
427
+ ? (value as Array<string>).join(", ")
428
+ : value);
429
+ });
430
+
431
+ return obj;
432
+ }
433
+
434
+ [Symbol.iterator](): IterableIterator<[string, unknown]> {
435
+ return Object.entries(this.toJSON())[Symbol.iterator]();
436
+ }
437
+
438
+ toString(): string {
439
+ return Object.entries(this.toJSON())
440
+ .map(([ header, value ]) => header + ": " + value)
441
+ .join("\n");
442
+ }
443
+
444
+ getSetCookie(): Array<string> {
445
+ return (this.get("set-cookie") as Array<string> | null) ?? [];
446
+ }
447
+
448
+ get [Symbol.toStringTag](): string {
449
+ return "FaxiosHeaders";
450
+ }
451
+
452
+ static from(
453
+ thing?: Record<string, unknown> | FaxiosHeaders | string | null
454
+ ): FaxiosHeaders {
455
+ return thing instanceof this ? thing : new this(thing);
456
+ }
457
+
458
+ static concat(
459
+ first: Record<string, unknown> | FaxiosHeaders | string | undefined | null,
460
+ ...targets: Array<
461
+ Record<string, unknown> | FaxiosHeaders | string | undefined | null
462
+ >
463
+ ): FaxiosHeaders {
464
+ const computed = new this(first);
465
+
466
+ targets.forEach(target => computed.set(target));
467
+
468
+ return computed;
469
+ }
470
+
471
+ static accessor(header: string | Array<string>): typeof FaxiosHeaders {
472
+ const self = this as unknown as Record<
473
+ symbol,
474
+ { accessors: Record<string, boolean>; }
475
+ >;
476
+ const internals =
477
+ (self[$internals] =
478
+ self[$internals] =
479
+ {
480
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
481
+ accessors: {} as Record<string, boolean>,
482
+ });
483
+
484
+ const accessors = internals.accessors;
485
+ const prototype = this.prototype;
486
+
487
+ function defineAccessor(_header: string): void {
488
+ const lHeader = normalizeHeader(_header);
489
+
490
+ if (!accessors[lHeader]) {
491
+ buildAccessors(prototype, _header);
492
+ accessors[lHeader] = true;
493
+ }
494
+ }
495
+
496
+ utils.isArray(header)
497
+ ? header.forEach(defineAccessor)
498
+ : defineAccessor(header);
499
+
500
+ return this;
501
+ }
502
+ }
503
+
504
+ FaxiosHeaders.accessor([
505
+ "Content-Type",
506
+ "Content-Length",
507
+ "Accept",
508
+ "Accept-Encoding",
509
+ "User-Agent",
510
+ "Authorization",
511
+ ]);
512
+
513
+ // reserved names hotfix
514
+ utils.reduceDescriptors(
515
+ FaxiosHeaders.prototype,
516
+ ({ value }: PropertyDescriptor, key: string) => {
517
+ let mapped = key[0]!.toUpperCase() + key.slice(1); // map `set` => `Set`
518
+ return {
519
+ get: () => value,
520
+ set(this: Record<string, unknown>, headerValue: unknown) {
521
+ this[mapped] = headerValue;
522
+ },
523
+ };
524
+ }
525
+ );
526
+
527
+ utils.freezeMethods(FaxiosHeaders);
528
+
529
+ export default FaxiosHeaders;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ import combineURLs from "../helpers/combineURLs.js";
4
+ import isAbsoluteURL from "../helpers/isAbsoluteURL.js";
5
+ import type { InternalFaxiosRequestConfig } from "../types.js";
6
+ import FaxiosError from "./FaxiosError.js";
7
+
8
+ const malformedHttpProtocol = /^https?:(?!\/\/)/i;
9
+ const httpProtocolControlCharacters = /[\t\n\r]/g;
10
+
11
+ function stripLeadingC0ControlOrSpace(url: string): string {
12
+ let i = 0;
13
+ while (i < url.length && url.charCodeAt(i) <= 0x20) {
14
+ i++;
15
+ }
16
+ return url.slice(i);
17
+ }
18
+
19
+ function normalizeURLForProtocolCheck(url: string): string {
20
+ return stripLeadingC0ControlOrSpace(url).replace(httpProtocolControlCharacters, "");
21
+ }
22
+
23
+ function assertValidHttpProtocolURL(url: unknown, config: unknown): void {
24
+ if (typeof url === "string" && malformedHttpProtocol.test(normalizeURLForProtocolCheck(url))) {
25
+ throw new FaxiosError(
26
+ "Invalid URL: missing \"//\" after protocol",
27
+ FaxiosError.ERR_INVALID_URL,
28
+ config as InternalFaxiosRequestConfig
29
+ );
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Creates a new URL by combining the baseURL with the requestedURL,
35
+ * only when the requestedURL is not already an absolute URL.
36
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
37
+ *
38
+ * @param {string} baseURL The base URL
39
+ * @param {string} requestedURL Absolute or relative URL to combine
40
+ *
41
+ * @returns {string} The combined full path
42
+ */
43
+ export default function buildFullPath(baseURL: unknown, requestedURL: unknown, allowAbsoluteUrls?: unknown, config?: unknown): string {
44
+ assertValidHttpProtocolURL(requestedURL, config);
45
+ let isRelativeUrl = !isAbsoluteURL(requestedURL);
46
+ if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
47
+ assertValidHttpProtocolURL(baseURL, config);
48
+ return combineURLs(baseURL as string, requestedURL as string);
49
+ }
50
+ return requestedURL as string;
51
+ }
@@ -0,0 +1,127 @@
1
+ // @ts-self-types="./define.d.ts" — required for Deno: maps built .js to adjacent .d.ts in dist/
2
+
3
+ import type { StandardSchemaV1 } from "../types/standard-schema.js";
4
+ import type { FaxiosRequestConfig, FaxiosResponse, StringLiteralsOrString, Method } from "../types.js";
5
+ import mergeConfig from "./mergeConfig.js";
6
+
7
+ type StrippedFields =
8
+ | "url"
9
+ | "method"
10
+ | "pathParams"
11
+ | "params"
12
+ | "data"
13
+ | "pathParamsSchema"
14
+ | "paramsSchema"
15
+ | "requestSchema"
16
+ | "responseSchema";
17
+
18
+ /** Request config accepted by a defined endpoint call: everything except `url`, `method`, `pathParams`, `params`, `data` and the schemas. */
19
+ export type BasePerCallConfig = Omit<FaxiosRequestConfig, StrippedFields>;
20
+
21
+ /** Config for one call of a defined endpoint; `pathParams`, `params` and `data` are required when their schema is set. */
22
+ export type PerCallConfig<
23
+ PP extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined,
24
+ P extends StandardSchemaV1 | undefined,
25
+ D extends StandardSchemaV1 | undefined,
26
+ TOpts = unknown
27
+ > =
28
+ BasePerCallConfig
29
+ & TOpts
30
+ & (PP extends StandardSchemaV1 ? {
31
+ /**
32
+ * Values for `{key}` placeholders in the endpoint URL (braces, not `:key`), validated by the
33
+ * endpoint's `pathParamsSchema` first. Each value goes through `String()` then
34
+ * `encodeURIComponent`; a missing, `null` or `undefined` value rejects with
35
+ * `ERR_BAD_OPTION_VALUE`, and a schema failure with `ERR_BAD_PATH_PARAMS_SCHEMA`.
36
+ * Keys with no matching placeholder are ignored.
37
+ */
38
+ pathParams: StandardSchemaV1.InferInput<PP>;
39
+ } : unknown)
40
+ & (P extends StandardSchemaV1 ? { params: StandardSchemaV1.InferInput<P>; } : unknown)
41
+ & (D extends StandardSchemaV1 ? { data: StandardSchemaV1.InferInput<D>; } : unknown);
42
+
43
+ /** Config for `define()`: request defaults plus the schemas, which are locked at define time. */
44
+ export type DefineConfig<
45
+ PP extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined,
46
+ P extends StandardSchemaV1 | undefined = undefined,
47
+ D extends StandardSchemaV1 | undefined = undefined,
48
+ R extends StandardSchemaV1 | undefined = undefined
49
+ > = BasePerCallConfig & {
50
+ /**
51
+ * Standard Schema that validates `pathParams` on every call; its output fills the `{key}`
52
+ * placeholders. Makes `pathParams` required per call. A failure rejects with `ERR_BAD_PATH_PARAMS_SCHEMA`.
53
+ */
54
+ pathParamsSchema?: PP;
55
+ paramsSchema?: P;
56
+ requestSchema?: D;
57
+ responseSchema?: R;
58
+ };
59
+
60
+ type HasInputSchema<PP, P, D> =
61
+ [PP, P, D] extends [undefined, undefined, undefined] ? false : true;
62
+
63
+ /** The function `define()` returns: call it with per-call config to send the request. */
64
+ export type DefinedEndpoint<
65
+ PP extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined,
66
+ P extends StandardSchemaV1 | undefined,
67
+ D extends StandardSchemaV1 | undefined,
68
+ R extends StandardSchemaV1 | undefined,
69
+ TOpts = unknown
70
+ > =
71
+ HasInputSchema<PP, P, D> extends true
72
+ ? (callConfig: PerCallConfig<PP, P, D, TOpts>) => Promise<FaxiosResponse<R extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<R> : unknown>>
73
+ : (callConfig?: PerCallConfig<PP, P, D, TOpts>) => Promise<FaxiosResponse<R extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<R> : unknown>>;
74
+
75
+ /** The minimal instance shape `define()` and `route()` need: a `request` method. */
76
+ export interface FaxiosLike {
77
+ request: (config: FaxiosRequestConfig) => Promise<FaxiosResponse<unknown>>;
78
+ }
79
+
80
+ type SchemaFields = Extract<StrippedFields, `${string}Schema`>;
81
+ const schemaKeys = [ "pathParamsSchema", "paramsSchema", "requestSchema", "responseSchema" ] as const;
82
+ // compile-time assertion: schemaKeys and SchemaFields must stay in sync
83
+ void (schemaKeys satisfies ReadonlyArray<SchemaFields>);
84
+ // strippedKeys strips url/method/schemas from per-call config; StrippedFields also omits pathParams/params/data
85
+ // at the type level (those are still allowed at runtime — they're the validated data, not the schema definitions)
86
+ const strippedKeys = [ "url", "method", ...schemaKeys ] as const;
87
+
88
+ export function createDefinedEndpoint<
89
+ PP extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined,
90
+ P extends StandardSchemaV1 | undefined,
91
+ D extends StandardSchemaV1 | undefined,
92
+ R extends StandardSchemaV1 | undefined
93
+ >(
94
+ instance: FaxiosLike,
95
+ method: StringLiteralsOrString<Method>,
96
+ url: string,
97
+ defineConfig?: DefineConfig<PP, P, D, R>
98
+ ): DefinedEndpoint<PP, P, D, R> {
99
+ const bakedConfig: FaxiosRequestConfig = { ...(defineConfig ?? {}), method, url };
100
+
101
+ const fn = (callConfig?: PerCallConfig<PP, P, D>) => {
102
+ const safeCall: FaxiosRequestConfig = { ...(callConfig ?? {}) };
103
+ // ponytail: runtime guard — strip identity + schemas so JS callers can't override
104
+ for (const k of strippedKeys) {
105
+ delete (safeCall as Record<string, unknown>)[k];
106
+ }
107
+
108
+ // mergeConfig(baked, perCall): perCall wins for most fields (signal, headers, timeout, env)
109
+ const merged = mergeConfig(bakedConfig, safeCall);
110
+ // Lock url/method and re-lock schemas — perCall cannot override define-time identity
111
+ (merged as Record<string, unknown>)["url"] = url;
112
+ (merged as Record<string, unknown>)["method"] = method;
113
+ // ponytail: defense-in-depth — mergeConfig would fall through, but this makes the invariant explicit
114
+ for (const k of schemaKeys) {
115
+ if (Object.prototype.hasOwnProperty.call(bakedConfig, k)) {
116
+ (merged as Record<string, unknown>)[k] = bakedConfig[k];
117
+ }
118
+ else {
119
+ delete (merged as Record<string, unknown>)[k];
120
+ }
121
+ }
122
+
123
+ return instance.request(merged);
124
+ };
125
+
126
+ return fn as DefinedEndpoint<PP, P, D, R>;
127
+ }