accessio 1.0.0

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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +487 -0
  3. package/cjs/accessio.cjs +208 -0
  4. package/cjs/accessio.cjs.map +1 -0
  5. package/cjs/constants/errorCodes.cjs +76 -0
  6. package/cjs/constants/errorCodes.cjs.map +1 -0
  7. package/cjs/core/accessioError.cjs +93 -0
  8. package/cjs/core/accessioError.cjs.map +1 -0
  9. package/cjs/core/buildURL.cjs +100 -0
  10. package/cjs/core/buildURL.cjs.map +1 -0
  11. package/cjs/core/mergeConfig.cjs +73 -0
  12. package/cjs/core/mergeConfig.cjs.map +1 -0
  13. package/cjs/core/request.cjs +259 -0
  14. package/cjs/core/request.cjs.map +1 -0
  15. package/cjs/core/retry.cjs +109 -0
  16. package/cjs/core/retry.cjs.map +1 -0
  17. package/cjs/defaults/index.cjs +55 -0
  18. package/cjs/defaults/index.cjs.map +1 -0
  19. package/cjs/defaults/transforms.cjs +59 -0
  20. package/cjs/defaults/transforms.cjs.map +1 -0
  21. package/cjs/helpers/debug.cjs +96 -0
  22. package/cjs/helpers/debug.cjs.map +1 -0
  23. package/cjs/helpers/parseHeaders.cjs +52 -0
  24. package/cjs/helpers/parseHeaders.cjs.map +1 -0
  25. package/cjs/helpers/rateLimiter.cjs +98 -0
  26. package/cjs/helpers/rateLimiter.cjs.map +1 -0
  27. package/cjs/helpers/settle.cjs +50 -0
  28. package/cjs/helpers/settle.cjs.map +1 -0
  29. package/cjs/helpers/transformData.cjs +57 -0
  30. package/cjs/helpers/transformData.cjs.map +1 -0
  31. package/cjs/index.cjs +121 -0
  32. package/cjs/index.cjs.map +1 -0
  33. package/cjs/interceptors/interceptorManager.cjs +31 -0
  34. package/cjs/interceptors/interceptorManager.cjs.map +1 -0
  35. package/index.d.ts +454 -0
  36. package/package.json +116 -0
  37. package/src/accessio.ts +251 -0
  38. package/src/constants/errorCodes.ts +29 -0
  39. package/src/core/accessioError.ts +74 -0
  40. package/src/core/buildURL.ts +99 -0
  41. package/src/core/mergeConfig.ts +78 -0
  42. package/src/core/request.ts +284 -0
  43. package/src/core/retry.ts +117 -0
  44. package/src/defaults/index.ts +36 -0
  45. package/src/defaults/transforms.ts +44 -0
  46. package/src/helpers/debug.ts +103 -0
  47. package/src/helpers/parseHeaders.ts +35 -0
  48. package/src/helpers/rateLimiter.ts +96 -0
  49. package/src/helpers/settle.ts +26 -0
  50. package/src/helpers/transformData.ts +36 -0
  51. package/src/index.ts +102 -0
  52. package/src/interceptors/interceptorManager.ts +5 -0
  53. package/src/types.ts +159 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 **salvatorecorvaglia** (https://github.com/salvatorecorvaglia)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,487 @@
1
+ # accessio ðŸŽŊ
2
+
3
+ **Fast, flexible HTTP client for Node.js and browsers — simple, modular, and dependency-free** — lightweight, modern, zero dependencies.
4
+
5
+ ---
6
+
7
+ ## âœĻ Features
8
+
9
+ - 🚀 **Promise-based** — works seamlessly with `async`/`await`
10
+ - 🌐 **Isomorphic** — runs in both browser and Node.js (â‰Ĩ 18)
11
+ - ðŸŠķ **Zero dependencies** — lightweight, built on native `fetch`
12
+ - 🔄 **Interceptors** — transform requests and responses globally
13
+ - ⚙ïļ **Configurable instances** — create multiple API clients with custom defaults
14
+ - ðŸ›Ąïļ **Error handling** — structured `AccessioError` with status, config, and response
15
+ - ðŸ“Ķ **Dual format** — supports both ESM and CommonJS
16
+ - 📐 **TypeScript support** — full type definitions included
17
+ - ⏱ïļ **Timeout support** — built-in request timeout via `AbortController`
18
+ - 🔧 **Transform pipelines** — customize request/response data transformation
19
+ - â™ŧïļ **Automatic Retries** — built-in retry logic with exponential backoff and jitter
20
+ - ⏱ïļ **Duration tracking** — every response includes a `duration` field in milliseconds
21
+ - ðŸšĨ **Rate Limiter** — limit concurrent requests with acquire/release/destroy lifecycle
22
+ - 🐞 **Debug Mode** — structured console logging for outgoing requests and responses
23
+ - ðŸŽŊ **Familiar API** — intuitive, developer-friendly interface
24
+
25
+ ---
26
+
27
+ ## ðŸ“Ķ Installation
28
+
29
+ accessio is available on both the official npm registry (unscoped) and GitHub Packages (scoped).
30
+
31
+ ```bash
32
+ # Recommended: Standard npm registry
33
+ npm install accessio
34
+
35
+ # Alternative: GitHub Packages
36
+ npm install @salvatorecorvaglia/accessio
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 🚀 Quick Start
42
+
43
+ ```typescript
44
+ import accessio from "accessio";
45
+
46
+ // GET request
47
+ const response = await accessio.get("https://api.example.com/users");
48
+ console.log(response.data);
49
+
50
+ // POST request with JSON body
51
+ const newUser = await accessio.post("https://api.example.com/users", {
52
+ name: "John Doe",
53
+ email: "john@example.com",
54
+ });
55
+ console.log(newUser.data);
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 📖 API Reference
61
+
62
+ ### Request Methods
63
+
64
+ ```javascript
65
+ accessio(config)
66
+ accessio(url, config?)
67
+
68
+ accessio.request(config)
69
+ accessio.get(url, config?)
70
+ accessio.delete(url, config?)
71
+ accessio.head(url, config?)
72
+ accessio.options(url, config?)
73
+ accessio.post(url, data?, config?)
74
+ accessio.put(url, data?, config?)
75
+ accessio.patch(url, data?, config?)
76
+ accessio.postForm(url, data?, config?)
77
+ accessio.putForm(url, data?, config?)
78
+ accessio.patchForm(url, data?, config?)
79
+ accessio.getUri(config)
80
+ ```
81
+
82
+ ### Configuration
83
+
84
+ ```javascript
85
+ {
86
+ // URL path (optional if baseURL is set)
87
+ url: '/users',
88
+
89
+ // HTTP method (default: 'get')
90
+ method: 'get',
91
+
92
+ // Base URL prepended to `url` unless `url` is absolute
93
+ baseURL: 'https://api.example.com',
94
+
95
+ // Request headers
96
+ headers: {
97
+ 'Authorization': 'Bearer token',
98
+ 'X-Custom-Header': 'value'
99
+ },
100
+
101
+ // URL query parameters
102
+ params: { page: 1, limit: 10 },
103
+
104
+ // Custom params serializer
105
+ paramsSerializer: (params) => Qs.stringify(params),
106
+
107
+ // Request body (for POST, PUT, PATCH)
108
+ data: { name: 'John' },
109
+
110
+ // Timeout in milliseconds (0 = no timeout)
111
+ timeout: 5000,
112
+
113
+ // Expected response type: 'json' | 'text' | 'blob' | 'arraybuffer' | 'stream'
114
+ responseType: 'json',
115
+
116
+ // Include credentials in cross-site requests
117
+ withCredentials: false,
118
+
119
+ // Basic auth (sets Authorization header automatically)
120
+ auth: { username: 'user', password: 'secret' },
121
+
122
+ // Transform functions for request/response data
123
+ transformRequest: [(data, headers) => { /* ... */ return data; }],
124
+ transformResponse: [(data) => { /* ... */ return data; }],
125
+
126
+ // Automatic retry strategy
127
+ retry: 3, // Max retry attempts (default: 0)
128
+ retryDelay: 1000, // Base delay in ms, doubles on each attempt (default: 1000)
129
+ retryCondition: (error) => true, // Custom retry predicate
130
+ onRetry: (attempt, error, config) => {}, // Called before each retry
131
+
132
+ // Debug logging
133
+ debug: true, // Enable request/response debug logger
134
+
135
+ // Rate limiting
136
+ rateLimiter: limiter, // Rate limiter instance for concurrency control
137
+
138
+ // Determine which status codes resolve/reject the promise
139
+ validateStatus: (status) => status >= 200 && status < 300,
140
+
141
+ // AbortSignal for request cancellation
142
+ signal: controller.signal
143
+ }
144
+ ```
145
+
146
+ ### Response Object
147
+
148
+ ```javascript
149
+ {
150
+ data: {}, // Parsed response body
151
+ status: 200, // HTTP status code
152
+ statusText: 'OK', // HTTP status message
153
+ headers: {}, // Response headers (lowercase keys)
154
+ config: {}, // Request configuration used
155
+ request: {}, // Underlying fetch Response object
156
+ duration: 142 // Request duration in milliseconds
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## 🔧 Creating Instances
163
+
164
+ ```typescript
165
+ import accessio from "accessio";
166
+
167
+ const api = accessio.create({
168
+ baseURL: "https://api.example.com",
169
+ timeout: 10000,
170
+ headers: {
171
+ Authorization: "Bearer my-token",
172
+ },
173
+ });
174
+
175
+ // All requests will use the instance config
176
+ const users = await api.get("/users");
177
+ const posts = await api.get("/posts", { params: { limit: 5 } });
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 🔄 Interceptors
183
+
184
+ ```typescript
185
+ // Request interceptor — runs before every request
186
+ accessio.interceptors.request.use(
187
+ (config) => {
188
+ config.headers["Authorization"] = `Bearer ${getToken()}`;
189
+ return config;
190
+ },
191
+ (error) => Promise.reject(error),
192
+ );
193
+
194
+ // Response interceptor — runs after every response
195
+ accessio.interceptors.response.use(
196
+ (response) => response,
197
+ (error) => {
198
+ // Handle 401 globally
199
+ if (error.response?.status === 401) {
200
+ redirectToLogin();
201
+ }
202
+ return Promise.reject(error);
203
+ },
204
+ );
205
+
206
+ // Conditional interceptor — runs only when the predicate returns true
207
+ accessio.interceptors.request.use(
208
+ (config) => {
209
+ /* ... */ return config;
210
+ },
211
+ null,
212
+ { runWhen: (config) => config.method === "post" },
213
+ );
214
+
215
+ // Remove a single interceptor
216
+ const id = accessio.interceptors.request.use(/* ... */);
217
+ accessio.interceptors.request.eject(id);
218
+
219
+ // Remove all interceptors
220
+ accessio.interceptors.request.clear();
221
+ ```
222
+
223
+ **Execution order:**
224
+
225
+ - Request interceptors run in **reverse** order (last added → first executed)
226
+ - Response interceptors run in **normal** order (first added → first executed)
227
+
228
+ ---
229
+
230
+ ## ðŸ›Ąïļ Error Handling
231
+
232
+ ```typescript
233
+ try {
234
+ await accessio.get("/might-fail");
235
+ } catch (error) {
236
+ if (accessio.isAccessioError(error)) {
237
+ if (error.response) {
238
+ console.log(error.response.status); // 404, 500, etc.
239
+ console.log(error.response.data); // Response body
240
+ } else if (error.code === "ERR_NETWORK") {
241
+ console.log("Network error — no response received");
242
+ } else if (error.code === "ETIMEDOUT") {
243
+ console.log("Request timed out");
244
+ } else if (accessio.isCancel(error)) {
245
+ console.log("Request was cancelled");
246
+ }
247
+
248
+ console.log(error.config); // Request config
249
+ console.log(error.message); // Error message
250
+ console.log(error.toJSON()); // Serializable summary
251
+ }
252
+ }
253
+ ```
254
+
255
+ ### Error Codes
256
+
257
+ | Code | Description |
258
+ | --------------------------- | --------------------------------------- |
259
+ | `ERR_BAD_REQUEST` | 4xx status code |
260
+ | `ERR_BAD_RESPONSE` | 5xx status code |
261
+ | `ERR_NETWORK` | Network error (no response received) |
262
+ | `ETIMEDOUT` | Request timed out |
263
+ | `ECONNABORTED` | Request was aborted |
264
+ | `ERR_CANCELED` | Request was cancelled via `AbortSignal` |
265
+ | `ERR_BAD_OPTION` | Invalid or missing configuration option |
266
+ | `ERR_BAD_OPTION_VALUE` | Invalid configuration option value |
267
+ | `ERR_INVALID_URL` | The provided URL is invalid |
268
+ | `ERR_FR_TOO_MANY_REDIRECTS` | Too many redirects |
269
+ | `ERR_NOT_SUPPORT` | Feature not supported in environment |
270
+
271
+ ---
272
+
273
+ ## 🔀 Concurrent Requests
274
+
275
+ ```javascript
276
+ const [users, posts] = await accessio.all([
277
+ accessio.get("/users"),
278
+ accessio.get("/posts"),
279
+ ]);
280
+
281
+ // Or with the spread helper (deprecated — use modern spread syntax instead)
282
+ accessio.all([accessio.get("/users"), accessio.get("/posts")]).then(
283
+ accessio.spread((users, posts) => {
284
+ console.log(users.data, posts.data);
285
+ }),
286
+ );
287
+ ```
288
+
289
+ ---
290
+
291
+ ## ❌ Cancellation
292
+
293
+ ```javascript
294
+ const controller = new AbortController();
295
+
296
+ accessio
297
+ .get("/slow-endpoint", {
298
+ signal: controller.signal,
299
+ })
300
+ .catch((error) => {
301
+ if (accessio.isCancel(error)) {
302
+ console.log("Request cancelled:", error.message);
303
+ }
304
+ });
305
+
306
+ // Cancel the request
307
+ controller.abort();
308
+ ```
309
+
310
+ ---
311
+
312
+ ## 🔧 Transform Request / Response
313
+
314
+ ```javascript
315
+ const api = accessio.create({
316
+ transformRequest: [
317
+ (data, headers) => {
318
+ // Add a timestamp to every outgoing body
319
+ if (data && typeof data === "object") {
320
+ data.timestamp = Date.now();
321
+ }
322
+ return JSON.stringify(data);
323
+ },
324
+ ],
325
+ transformResponse: [
326
+ (data) => {
327
+ if (typeof data === "string") {
328
+ try {
329
+ return JSON.parse(data);
330
+ } catch {}
331
+ }
332
+ return data;
333
+ },
334
+ (data) => {
335
+ // Unwrap a { data: ... } envelope
336
+ return data?.data ?? data;
337
+ },
338
+ ],
339
+ });
340
+ ```
341
+
342
+ ---
343
+
344
+ ## â™ŧïļ Advanced Features
345
+
346
+ ### Automatic Retry
347
+
348
+ accessio supports configurable retries with exponential backoff and Âą25% jitter to prevent thundering herd.
349
+
350
+ ```javascript
351
+ const response = await accessio.get("/flaky-api", {
352
+ retry: 3, // Retry up to 3 times
353
+ retryDelay: 1000, // Base delay — doubles on each attempt: 1s, 2s, 4s
354
+
355
+ // Optional: custom condition (default: network errors + 5xx)
356
+ retryCondition: (error) => error.response?.status === 503,
357
+
358
+ // Optional: callback before each retry
359
+ onRetry: (attempt, error, config) => {
360
+ console.log(`Retry attempt #${attempt} after: ${error.message}`);
361
+ },
362
+ });
363
+ ```
364
+
365
+ The default `retryCondition` retries on:
366
+
367
+ - `ERR_NETWORK` — no response received
368
+ - `ETIMEDOUT` — request timed out
369
+ - 5xx server errors
370
+ - Does **not** retry on `ERR_CANCELED` or 4xx client errors
371
+
372
+ ### Rate Limiting
373
+
374
+ Control the maximum number of concurrent in-flight requests.
375
+
376
+ #### Option 1: Built-in config integration (recommended)
377
+
378
+ ```javascript
379
+ import accessio, { createRateLimiter } from "accessio";
380
+
381
+ const limiter = createRateLimiter(5); // max 5 concurrent requests
382
+
383
+ // Pass the limiter directly in the request config
384
+ const response = await accessio.get("/api/data", { rateLimiter: limiter });
385
+
386
+ // Or set it as an instance default
387
+ const api = accessio.create({ rateLimiter: limiter });
388
+ const users = await api.get("/users");
389
+ ```
390
+
391
+ #### Option 2: Manual acquire / release
392
+
393
+ ```javascript
394
+ import { createRateLimiter } from "accessio";
395
+
396
+ const limiter = createRateLimiter(5);
397
+
398
+ await limiter.acquire();
399
+ try {
400
+ const res = await accessio.get("/api/data");
401
+ } finally {
402
+ limiter.release();
403
+ }
404
+
405
+ // Inspect state
406
+ console.log(limiter.active); // Currently running requests
407
+ console.log(limiter.pending); // Requests waiting in queue
408
+
409
+ // Cleanup on navigation / component unmount — rejects all queued promises
410
+ limiter.destroy();
411
+ console.log(limiter.destroyed); // true
412
+ ```
413
+
414
+ ### Debug Logging
415
+
416
+ Enable `debug: true` on an instance or a single request to get structured console output.
417
+
418
+ ```javascript
419
+ const api = accessio.create({ debug: true });
420
+
421
+ // ðŸĶ‍⮛ [accessio] → GET https://api.example.com/users
422
+ // Params: {"page":1}
423
+ // Timeout: 5000ms
424
+ // ðŸĶ‍⮛ [accessio] ← ✅ 200 OK (142ms)
425
+ // Size: ~3.2 KB
426
+
427
+ // Or enable per-request only
428
+ await accessio.get("/debug-this", { debug: true });
429
+ ```
430
+
431
+ ---
432
+
433
+ ## ðŸ“Ĩ Imports
434
+
435
+ ### ESM (recommended)
436
+
437
+ ```typescript
438
+ import accessio from "accessio";
439
+ import {
440
+ createRateLimiter,
441
+ AccessioError,
442
+ mergeConfig,
443
+ buildURL,
444
+ logRequest,
445
+ logResponse,
446
+ logError,
447
+ } from "accessio";
448
+ ```
449
+
450
+ ### CommonJS
451
+
452
+ ```typescript
453
+ const accessio = require("accessio");
454
+ const { createRateLimiter } = require("accessio");
455
+ ```
456
+
457
+ ### Sub-path imports
458
+
459
+ ```javascript
460
+ // Import only what you need
461
+ import { createRateLimiter } from "accessio/helpers/rateLimiter";
462
+ import { logRequest, logResponse, logError } from "accessio/helpers/debug";
463
+ import { buildURL } from "accessio/core/buildURL";
464
+ import { mergeConfig } from "accessio/core/mergeConfig";
465
+ import { dispatchRequest } from "accessio/core/request";
466
+ import { retryRequest } from "accessio/core/retry";
467
+ import { parseHeaders } from "accessio/helpers/parseHeaders";
468
+ import { settle } from "accessio/helpers/settle";
469
+ import { transformData } from "accessio/helpers/transformData";
470
+ ```
471
+
472
+ ---
473
+
474
+ ## 📚 Documentation
475
+
476
+ | Document | Description |
477
+ | --------------------------------- | ------------------------------------------- |
478
+ | [CHANGELOG](./CHANGELOG.md) | Version history and release notes |
479
+ | [CONTRIBUTING](./CONTRIBUTING.md) | Guide for contributors |
480
+ | [SECURITY](./SECURITY.md) | Security policy and vulnerability reporting |
481
+ | [CONTRIBUTORS](./CONTRIBUTORS.md) | Project contributors |
482
+
483
+ ## 📝 Author
484
+
485
+ **Salvatore Corvaglia**
486
+
487
+ - GitHub: [@salvatorecorvaglia](https://github.com/salvatorecorvaglia)
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var accessio_exports = {};
30
+ __export(accessio_exports, {
31
+ Accessio: () => Accessio,
32
+ default: () => accessio_default
33
+ });
34
+ module.exports = __toCommonJS(accessio_exports);
35
+ var import_interceptorManager = __toESM(require("./interceptors/interceptorManager"), 1);
36
+ var import_accessioError = __toESM(require("./core/accessioError"), 1);
37
+ var import_mergeConfig = __toESM(require("./core/mergeConfig"), 1);
38
+ var import_request = __toESM(require("./core/request"), 1);
39
+ var import_buildURL = __toESM(require("./core/buildURL"), 1);
40
+ var import_retry = __toESM(require("./core/retry"), 1);
41
+ var import_debug = require("./helpers/debug");
42
+ var import_rateLimiter = require("./helpers/rateLimiter");
43
+ class Accessio {
44
+ defaults;
45
+ interceptors;
46
+ constructor(instanceConfig = {}) {
47
+ this.defaults = instanceConfig;
48
+ this.interceptors = {
49
+ request: new import_interceptorManager.default(),
50
+ response: new import_interceptorManager.default()
51
+ };
52
+ }
53
+ request(configOrUrl, config) {
54
+ if (typeof configOrUrl === "string") {
55
+ config = { ...config, url: configOrUrl };
56
+ } else {
57
+ config = configOrUrl ? { ...configOrUrl } : {};
58
+ }
59
+ const mergedConfig = (0, import_mergeConfig.default)(this.defaults, config);
60
+ mergedConfig.method = (mergedConfig.method || "get").toLowerCase();
61
+ if (!mergedConfig.url && !mergedConfig.baseURL) {
62
+ throw new import_accessioError.default(
63
+ "Request URL is required. Provide a `url` or `baseURL` in the config.",
64
+ import_accessioError.default.ERR_BAD_OPTION,
65
+ mergedConfig,
66
+ null,
67
+ null
68
+ );
69
+ }
70
+ const requestInterceptors = [];
71
+ const responseInterceptors = [];
72
+ this.interceptors.request.forEach((interceptor) => {
73
+ if (interceptor.runWhen && !interceptor.runWhen(mergedConfig)) {
74
+ return;
75
+ }
76
+ requestInterceptors.unshift(interceptor);
77
+ });
78
+ this.interceptors.response.forEach((interceptor) => {
79
+ responseInterceptors.push(interceptor);
80
+ });
81
+ let promise = Promise.resolve(mergedConfig);
82
+ for (const interceptor of requestInterceptors) {
83
+ promise = promise.then(
84
+ (value) => {
85
+ if (interceptor.fulfilled) {
86
+ return interceptor.fulfilled(value);
87
+ }
88
+ return value;
89
+ },
90
+ interceptor.rejected
91
+ );
92
+ }
93
+ promise = promise.then((cfg) => {
94
+ const fullUrl = (0, import_buildURL.default)(
95
+ cfg.url ?? "",
96
+ cfg.baseURL,
97
+ cfg.params,
98
+ cfg.paramsSerializer
99
+ );
100
+ (0, import_debug.logRequest)(cfg, fullUrl);
101
+ const enrichedCfg = fullUrl !== (cfg.url || "") ? { ...cfg, _builtUrl: fullUrl } : cfg;
102
+ const dispatchFn = cfg.rateLimiter ? (config2) => (0, import_rateLimiter.rateLimitedRequest)(import_request.default, config2.rateLimiter, config2) : import_request.default;
103
+ return (0, import_retry.default)(dispatchFn, enrichedCfg);
104
+ });
105
+ promise = promise.then(
106
+ (value) => {
107
+ (0, import_debug.logResponse)(value);
108
+ return value;
109
+ },
110
+ (error) => {
111
+ (0, import_debug.logError)(error, mergedConfig);
112
+ throw error;
113
+ }
114
+ );
115
+ for (const interceptor of responseInterceptors) {
116
+ promise = promise.then(
117
+ (value) => {
118
+ if (interceptor.fulfilled) {
119
+ return interceptor.fulfilled(value);
120
+ }
121
+ return value;
122
+ },
123
+ interceptor.rejected
124
+ );
125
+ }
126
+ return promise;
127
+ }
128
+ getUri(config) {
129
+ const merged = (0, import_mergeConfig.default)(this.defaults, config);
130
+ return (0, import_buildURL.default)(
131
+ merged.url ?? "",
132
+ merged.baseURL,
133
+ merged.params,
134
+ merged.paramsSerializer
135
+ );
136
+ }
137
+ get(url, config) {
138
+ return this.request(
139
+ (0, import_mergeConfig.default)(config || {}, { method: "get", url })
140
+ );
141
+ }
142
+ delete(url, config) {
143
+ return this.request(
144
+ (0, import_mergeConfig.default)(config || {}, { method: "delete", url })
145
+ );
146
+ }
147
+ head(url, config) {
148
+ return this.request(
149
+ (0, import_mergeConfig.default)(config || {}, { method: "head", url })
150
+ );
151
+ }
152
+ options(url, config) {
153
+ return this.request(
154
+ (0, import_mergeConfig.default)(config || {}, { method: "options", url })
155
+ );
156
+ }
157
+ post(url, data, config) {
158
+ return this.request(
159
+ (0, import_mergeConfig.default)(config || {}, { method: "post", url, data })
160
+ );
161
+ }
162
+ put(url, data, config) {
163
+ return this.request(
164
+ (0, import_mergeConfig.default)(config || {}, { method: "put", url, data })
165
+ );
166
+ }
167
+ patch(url, data, config) {
168
+ return this.request(
169
+ (0, import_mergeConfig.default)(config || {}, { method: "patch", url, data })
170
+ );
171
+ }
172
+ postForm(url, data, config) {
173
+ return this.request(
174
+ (0, import_mergeConfig.default)(config || {}, {
175
+ method: "post",
176
+ url,
177
+ data,
178
+ headers: { "Content-Type": "multipart/form-data" }
179
+ })
180
+ );
181
+ }
182
+ putForm(url, data, config) {
183
+ return this.request(
184
+ (0, import_mergeConfig.default)(config || {}, {
185
+ method: "put",
186
+ url,
187
+ data,
188
+ headers: { "Content-Type": "multipart/form-data" }
189
+ })
190
+ );
191
+ }
192
+ patchForm(url, data, config) {
193
+ return this.request(
194
+ (0, import_mergeConfig.default)(config || {}, {
195
+ method: "patch",
196
+ url,
197
+ data,
198
+ headers: { "Content-Type": "multipart/form-data" }
199
+ })
200
+ );
201
+ }
202
+ }
203
+ var accessio_default = Accessio;
204
+ // Annotate the CommonJS export names for ESM import in node:
205
+ 0 && (module.exports = {
206
+ Accessio
207
+ });
208
+ //# sourceMappingURL=accessio.cjs.map