accessio 1.4.0 → 1.6.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.
- package/README.md +165 -207
- package/cjs/accessio.cjs +30 -13
- package/cjs/accessio.cjs.map +1 -1
- package/cjs/core/accessioError.cjs +28 -0
- package/cjs/core/accessioError.cjs.map +1 -1
- package/cjs/core/buildURL.cjs +11 -8
- package/cjs/core/buildURL.cjs.map +1 -1
- package/cjs/core/fetchAdapter.cjs +4 -0
- package/cjs/core/fetchAdapter.cjs.map +1 -1
- package/cjs/core/mergeConfig.cjs +1 -1
- package/cjs/core/mergeConfig.cjs.map +1 -1
- package/cjs/core/request.cjs +43 -15
- package/cjs/core/request.cjs.map +1 -1
- package/cjs/core/retry.cjs +8 -5
- package/cjs/core/retry.cjs.map +1 -1
- package/cjs/helpers/flattenHeaders.cjs +4 -1
- package/cjs/helpers/flattenHeaders.cjs.map +1 -1
- package/cjs/helpers/memoryCache.cjs +19 -1
- package/cjs/helpers/memoryCache.cjs.map +1 -1
- package/cjs/helpers/rateLimiter.cjs +31 -3
- package/cjs/helpers/rateLimiter.cjs.map +1 -1
- package/cjs/helpers/toFormData.cjs +1 -1
- package/cjs/helpers/toFormData.cjs.map +1 -1
- package/index.d.ts +7 -0
- package/package.json +5 -4
- package/src/accessio.ts +44 -15
- package/src/core/accessioError.ts +33 -2
- package/src/core/buildURL.ts +16 -13
- package/src/core/fetchAdapter.ts +3 -0
- package/src/core/mergeConfig.ts +1 -1
- package/src/core/request.ts +54 -16
- package/src/core/retry.ts +8 -5
- package/src/helpers/flattenHeaders.ts +4 -1
- package/src/helpers/memoryCache.ts +24 -1
- package/src/helpers/rateLimiter.ts +35 -3
- package/src/helpers/toFormData.ts +5 -1
- package/src/types.ts +7 -1
package/README.md
CHANGED
|
@@ -2,298 +2,256 @@
|
|
|
2
2
|
|
|
3
3
|
**Fast, flexible HTTP client — simple, modular, and dependency-free.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Accessio is a lightweight, modern HTTP client built on top of the native fetch API. It provides a familiar, Promise-based interface with advanced features like interceptors, automatic retries, rate limiting, and structured debug logging, all while maintaining zero external dependencies.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
- 📚 **Auto-Pagination** — seamlessly iterate through paginated APIs via `autoPaginate`
|
|
28
|
-
- 🛡️ **Schema Validation** — validate responses automatically using Zod or custom schemas
|
|
29
|
-
- 🗂️ **Caching & Deduplication** — prevent redundant requests and cache responses
|
|
30
|
-
- 🪝 **Lifecycle Hooks** — simple hooks for request/response/error events
|
|
9
|
+
## ⚡ Key Features
|
|
10
|
+
|
|
11
|
+
- **Zero Runtime Dependencies**: Keep your bundle size minimal and avoid supply chain vulnerabilities.
|
|
12
|
+
- **Axios-Compatible API**: Direct drop-in replacement with `.get()`, `.post()`, `.request()`, and custom instances via `.create()`.
|
|
13
|
+
- **🛡️ Built-in Security & Auto-Redaction**: Prevents accidental leakage of secrets in error logs. Automatically redacts:
|
|
14
|
+
- `Authorization`, `Cookie`, and `Set-Cookie` headers.
|
|
15
|
+
- Sensitive request/response parameters (e.g., `api_key`, `token`, `password`, `secret`).
|
|
16
|
+
- Inline credentials inside URLs.
|
|
17
|
+
- **⏳ Concurrency Rate Limiter**: Built-in queue-based rate limiter to throttle concurrent requests, complete with immediate queue ejection on `AbortSignal` cancellation.
|
|
18
|
+
- **🔁 Jittered Exponential Backoff Retry**: Automatic retries for network failures or `5xx` status codes. Fully respects the HTTP 429 `Retry-After` header and supports customizable retry conditions and callbacks.
|
|
19
|
+
- **🌊 SSE & Newline JSON Streaming**: Native asynchronous generator-based parsing for Server-Sent Events (SSE) and newline-delimited JSON streams.
|
|
20
|
+
- **📂 Auto-Pagination**: Seamlessly yields paginated items from APIs using page links (e.g., `next` or `links.next`).
|
|
21
|
+
- **🧪 Type-safe Schema Validation**: Validate API response payloads at runtime using Zod, ArkType, or any validation library with a `.parse()` or `.parseAsync()` method.
|
|
22
|
+
- **📦 Request Deduplication**: Automatically coalesces concurrent duplicate GET requests to avoid redundant network traffic.
|
|
23
|
+
- **💾 Memory Caching**: In-memory caching out-of-the-box with custom TTL, or easily swap in a custom storage provider (e.g., Redis, LocalStorage).
|
|
24
|
+
- **🔗 Synchronous & Asynchronous Interceptors**: Hook into the request/response pipeline to dynamically inject headers, handle global errors, or log metrics.
|
|
25
|
+
- **⚓ Lifecycle Hooks**: Granular callbacks (`onBeforeRequest`, `onRequestResponse`, `onRequestError`) for custom instrumentation.
|
|
26
|
+
- **FormData Serialization**: Automatically converts flat or nested JS objects to `FormData` for multipart submissions.
|
|
31
27
|
|
|
32
28
|
---
|
|
33
29
|
|
|
34
30
|
## 📦 Installation
|
|
35
31
|
|
|
36
32
|
```bash
|
|
37
|
-
# Using npm
|
|
38
33
|
npm install accessio
|
|
39
|
-
|
|
40
|
-
# Using yarn
|
|
41
|
-
yarn add accessio
|
|
42
|
-
|
|
43
|
-
# Using pnpm
|
|
44
|
-
pnpm add accessio
|
|
45
34
|
```
|
|
46
35
|
|
|
47
36
|
---
|
|
48
37
|
|
|
49
38
|
## 🚀 Quick Start
|
|
50
39
|
|
|
40
|
+
### Basic Requests
|
|
41
|
+
|
|
51
42
|
```typescript
|
|
52
43
|
import accessio from 'accessio';
|
|
53
44
|
|
|
54
45
|
// Simple GET request
|
|
55
|
-
const
|
|
46
|
+
const response = await accessio.get('https://api.example.com/users/123');
|
|
47
|
+
console.log(response.data); // Automatically parsed JSON response
|
|
56
48
|
|
|
57
|
-
// POST request with
|
|
58
|
-
const
|
|
59
|
-
name: '
|
|
49
|
+
// POST request with body
|
|
50
|
+
const postResponse = await accessio.post('https://api.example.com/users', {
|
|
51
|
+
name: 'Jane Doe',
|
|
60
52
|
role: 'Developer',
|
|
61
53
|
});
|
|
62
|
-
|
|
63
|
-
console.log(`User created in ${response.duration}ms`);
|
|
64
54
|
```
|
|
65
55
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
## 📖 API Reference
|
|
69
|
-
|
|
70
|
-
### Request Methods
|
|
71
|
-
|
|
72
|
-
| Method | Description |
|
|
73
|
-
| :----------------------------------------- | :--------------------------------------- |
|
|
74
|
-
| `accessio(config)` | Generic request using config object |
|
|
75
|
-
| `accessio.get(url, config?)` | GET request |
|
|
76
|
-
| `accessio.post(url, data?, config?)` | POST request |
|
|
77
|
-
| `accessio.put(url, data?, config?)` | PUT request |
|
|
78
|
-
| `accessio.patch(url, data?, config?)` | PATCH request |
|
|
79
|
-
| `accessio.delete(url, config?)` | DELETE request |
|
|
80
|
-
| `accessio.head(url, config?)` | HEAD request |
|
|
81
|
-
| `accessio.options(url, config?)` | OPTIONS request |
|
|
82
|
-
| `accessio.postForm(url, data?, config?)` | POST request with `multipart/form-data` |
|
|
83
|
-
| `accessio.putForm(url, data?, config?)` | PUT request with `multipart/form-data` |
|
|
84
|
-
| `accessio.patchForm(url, data?, config?)` | PATCH request with `multipart/form-data` |
|
|
85
|
-
| `accessio.stream(url, config?)` | Server-Sent Events (SSE) streaming |
|
|
86
|
-
| `accessio.autoPaginate(url, config?)` | Async iterator for paginated endpoints |
|
|
87
|
-
| `accessio.gql(url, query, vars?, config?)` | GraphQL query/mutation wrapper |
|
|
88
|
-
|
|
89
|
-
### Configuration Options
|
|
56
|
+
### Custom Instances
|
|
90
57
|
|
|
91
58
|
```typescript
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
rateLimiter: limiter, // Concurrency limiter instance
|
|
106
|
-
validateStatus: (s) => s < 400, // Resolve/reject predicate
|
|
107
|
-
signal: abortController.signal, // Custom AbortSignal
|
|
108
|
-
dedupe: true, // Prevent duplicate in-flight requests
|
|
109
|
-
cache: true, // Cache responses (boolean or CacheProvider)
|
|
110
|
-
cacheTTL: 60000, // Cache time-to-live in ms
|
|
111
|
-
schema: z.object({...}), // Schema validator (e.g., Zod)
|
|
112
|
-
fetch: customFetch, // Custom fetch implementation
|
|
113
|
-
retryOn429: true, // Automatically retry on rate limits
|
|
114
|
-
hooks: { // Lifecycle hooks
|
|
115
|
-
onBeforeRequest: (config) => {},
|
|
116
|
-
onRequestResponse: (response) => {},
|
|
117
|
-
onRequestError: (error) => {}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
59
|
+
import accessio from 'accessio';
|
|
60
|
+
|
|
61
|
+
// Create a configured instance
|
|
62
|
+
const api = accessio.create({
|
|
63
|
+
baseURL: 'https://api.example.com/v1',
|
|
64
|
+
headers: {
|
|
65
|
+
'X-Client-Name': 'AccessioClient',
|
|
66
|
+
},
|
|
67
|
+
timeout: 5000, // 5-second timeout
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Use instance methods
|
|
71
|
+
const { data } = await api.get('/users');
|
|
120
72
|
```
|
|
121
73
|
|
|
122
74
|
---
|
|
123
75
|
|
|
124
|
-
##
|
|
76
|
+
## 🛠️ Advanced Features
|
|
125
77
|
|
|
126
|
-
###
|
|
78
|
+
### 🛡️ Auto-Redaction (Zero-leak Logs)
|
|
127
79
|
|
|
128
|
-
|
|
80
|
+
Accessio is built with security first. If a request fails, sensitive credentials in request/response properties are redacted automatically before being attached to the `AccessioError`.
|
|
129
81
|
|
|
130
82
|
```typescript
|
|
131
|
-
|
|
132
|
-
accessio.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
83
|
+
try {
|
|
84
|
+
await accessio.get('https://admin:secret_password@api.example.com/users', {
|
|
85
|
+
params: { api_key: 'super_secret_token_123' },
|
|
86
|
+
headers: { Authorization: 'Bearer token_xyz' },
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (accessio.isAccessioError(error)) {
|
|
90
|
+
console.error(error.toJSON());
|
|
91
|
+
/*
|
|
92
|
+
Outputs:
|
|
93
|
+
{
|
|
94
|
+
"name": "AccessioError",
|
|
95
|
+
"message": "Request failed with status code 401",
|
|
96
|
+
"code": "ERR_BAD_REQUEST",
|
|
97
|
+
"status": 401,
|
|
98
|
+
"config": {
|
|
99
|
+
"url": "https://admin:[REDACTED]@api.example.com/users",
|
|
100
|
+
"params": {
|
|
101
|
+
"api_key": "[REDACTED]"
|
|
102
|
+
},
|
|
103
|
+
"headers": {
|
|
104
|
+
"authorization": "[REDACTED]"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
*/
|
|
109
|
+
}
|
|
110
|
+
}
|
|
145
111
|
```
|
|
146
112
|
|
|
147
|
-
###
|
|
148
|
-
|
|
149
|
-
`Accessio` provides a structured error object with specific codes to help you handle failures gracefully.
|
|
113
|
+
### 🔁 Automatic Retries & Backoff
|
|
150
114
|
|
|
151
|
-
|
|
152
|
-
| :----------------- | :---------------------------- |
|
|
153
|
-
| `ERR_BAD_REQUEST` | 4xx status code |
|
|
154
|
-
| `ERR_BAD_RESPONSE` | 5xx status code |
|
|
155
|
-
| `ERR_NETWORK` | Network connectivity issues |
|
|
156
|
-
| `ETIMEDOUT` | Request exceeded timeout |
|
|
157
|
-
| `ERR_CANCELED` | Request was manually aborted |
|
|
158
|
-
| `ERR_INVALID_URL` | The provided URL is malformed |
|
|
159
|
-
| `ERR_BAD_OPTION` | Invalid configuration option |
|
|
160
|
-
|
|
161
|
-
### Automatic Retries
|
|
162
|
-
|
|
163
|
-
`Accessio` includes a powerful retry mechanism that handles network errors and 5xx responses automatically.
|
|
115
|
+
Automatically retry failed requests using exponential backoff with randomized jitter to prevent thundering herds.
|
|
164
116
|
|
|
165
117
|
```typescript
|
|
166
118
|
const response = await accessio.get('/flaky-endpoint', {
|
|
167
|
-
retry:
|
|
168
|
-
retryDelay: 1000, //
|
|
169
|
-
|
|
119
|
+
retry: 3, // Max retry attempts
|
|
120
|
+
retryDelay: 1000, // Initial delay in ms (doubles each attempt)
|
|
121
|
+
maxRetryDelay: 10000, // Maximum delay cap
|
|
122
|
+
retryOn429: true, // Respect Retry-After header for HTTP 429 responses
|
|
123
|
+
onRetry: (attempt, error, config) => {
|
|
124
|
+
console.warn(`Retry attempt #${attempt} due to: ${error.message}`);
|
|
125
|
+
},
|
|
170
126
|
});
|
|
171
127
|
```
|
|
172
128
|
|
|
173
|
-
### Rate Limiting
|
|
129
|
+
### ⏳ Concurrency Rate Limiting
|
|
174
130
|
|
|
175
|
-
|
|
131
|
+
Throttle outbound requests using a queue-based rate limiter. This is especially useful for third-party APIs with tight request limits.
|
|
176
132
|
|
|
177
133
|
```typescript
|
|
178
|
-
import { createRateLimiter } from 'accessio';
|
|
134
|
+
import accessio, { createRateLimiter } from 'accessio';
|
|
135
|
+
|
|
136
|
+
// Allow a maximum of 2 requests in parallel
|
|
137
|
+
const rateLimiter = createRateLimiter(2);
|
|
179
138
|
|
|
180
|
-
const
|
|
181
|
-
const api = accessio.create({ rateLimiter: limiter });
|
|
139
|
+
const api = accessio.create({ rateLimiter });
|
|
182
140
|
|
|
183
|
-
//
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
api.get('/req-2'),
|
|
187
|
-
// ...
|
|
188
|
-
]);
|
|
141
|
+
// These will run with a max concurrency of 2, queueing the rest
|
|
142
|
+
const requests = [1, 2, 3, 4, 5].map((id) => api.get(`/users/${id}`));
|
|
143
|
+
const responses = await Promise.all(requests);
|
|
189
144
|
```
|
|
190
145
|
|
|
191
|
-
###
|
|
146
|
+
### 🌊 SSE & Newline JSON Streaming
|
|
192
147
|
|
|
193
|
-
|
|
148
|
+
Accessio leverages asynchronous generators to handle incoming response streams dynamically (works with Server-Sent Events or line-by-line JSON streams).
|
|
194
149
|
|
|
195
150
|
```typescript
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
// Size: ~3.2 KB
|
|
151
|
+
// Iterating through an AI completion SSE stream
|
|
152
|
+
for await (const chunk of api.stream('/ai/complete')) {
|
|
153
|
+
console.log(chunk); // Parsed JSON chunk, e.g., { text: "hello" }
|
|
154
|
+
}
|
|
201
155
|
```
|
|
202
156
|
|
|
203
|
-
###
|
|
157
|
+
### 📂 Auto-Pagination
|
|
204
158
|
|
|
205
|
-
|
|
159
|
+
Avoid boilerplate code for pagination. Accessio can auto-follow `next` and `links.next` properties automatically:
|
|
206
160
|
|
|
207
161
|
```typescript
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
});
|
|
162
|
+
// Automatically fetches subsequent pages until next link is null
|
|
163
|
+
for await (const item of api.autoPaginate('/users?page=1')) {
|
|
164
|
+
console.log(item.name); // Yields individual items from each page's items array
|
|
165
|
+
}
|
|
213
166
|
```
|
|
214
167
|
|
|
215
|
-
### Schema Validation
|
|
168
|
+
### 🧪 Runtime Schema Validation
|
|
216
169
|
|
|
217
|
-
|
|
170
|
+
Validate your API payloads at runtime using your favorite validation library (e.g., Zod, ArkType, Superstruct).
|
|
218
171
|
|
|
219
172
|
```typescript
|
|
220
173
|
import { z } from 'zod';
|
|
221
174
|
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
### Server-Sent Events (SSE)
|
|
175
|
+
const UserSchema = z.object({
|
|
176
|
+
id: z.string(),
|
|
177
|
+
name: z.string(),
|
|
178
|
+
email: z.string().email(),
|
|
179
|
+
});
|
|
229
180
|
|
|
230
|
-
|
|
181
|
+
const response = await api.get('/users/123', {
|
|
182
|
+
schema: UserSchema, // Throws AccessioError (ERR_BAD_RESPONSE) if validation fails
|
|
183
|
+
});
|
|
231
184
|
|
|
232
|
-
|
|
233
|
-
for await (const chunk of accessio.stream('/stream')) {
|
|
234
|
-
console.log(chunk); // Parsed JSON or string data from SSE
|
|
235
|
-
}
|
|
185
|
+
const user = response.data; // Fully typed as { id: string; name: string; email: string }
|
|
236
186
|
```
|
|
237
187
|
|
|
238
|
-
###
|
|
188
|
+
### 📦 Request Deduplication & Caching
|
|
239
189
|
|
|
240
|
-
|
|
190
|
+
Optimize application performance by preventing duplicate queries and utilizing caching.
|
|
241
191
|
|
|
242
192
|
```typescript
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
193
|
+
const api = accessio.create({
|
|
194
|
+
dedupe: true, // Merge concurrent requests targeting the same endpoint
|
|
195
|
+
cache: true, // Enable in-memory cache
|
|
196
|
+
cacheTTL: 60000, // Cache responses for 60 seconds
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// Executes exactly 1 network call, resolves both promises
|
|
200
|
+
const [res1, res2] = await Promise.all([api.get('/heavy-report'), api.get('/heavy-report')]);
|
|
246
201
|
```
|
|
247
202
|
|
|
248
|
-
###
|
|
203
|
+
### 🔗 Interceptors & Hooks
|
|
249
204
|
|
|
250
|
-
|
|
205
|
+
Modify requests and responses at runtime, or listen to client lifecycles:
|
|
251
206
|
|
|
252
207
|
```typescript
|
|
253
|
-
const
|
|
254
|
-
query GetUser($id: ID!) {
|
|
255
|
-
user(id: $id) { name, email }
|
|
256
|
-
}
|
|
257
|
-
`;
|
|
258
|
-
|
|
259
|
-
const response = await accessio.gql('/graphql', query, { id: '1' });
|
|
260
|
-
```
|
|
208
|
+
const api = accessio.create();
|
|
261
209
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
210
|
+
// Add Request Interceptor
|
|
211
|
+
api.interceptors.request.use((config) => {
|
|
212
|
+
config.headers = config.headers || {};
|
|
213
|
+
config.headers['X-Request-Timestamp'] = Date.now().toString();
|
|
214
|
+
return config;
|
|
215
|
+
});
|
|
265
216
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
onRequestError: (error) => console.error('Request failed!'),
|
|
217
|
+
// Add Response Interceptor
|
|
218
|
+
api.interceptors.response.use(
|
|
219
|
+
(response) => {
|
|
220
|
+
// Modify output data
|
|
221
|
+
return response;
|
|
272
222
|
},
|
|
273
|
-
|
|
223
|
+
(error) => {
|
|
224
|
+
// Handle global errors (e.g. token refresh)
|
|
225
|
+
return Promise.reject(error);
|
|
226
|
+
},
|
|
227
|
+
);
|
|
274
228
|
```
|
|
275
229
|
|
|
276
230
|
---
|
|
277
231
|
|
|
278
|
-
##
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
232
|
+
## ⚙️ Configuration Options
|
|
233
|
+
|
|
234
|
+
Here is the complete list of config parameters available in `AccessioRequestConfig`:
|
|
235
|
+
|
|
236
|
+
| Option | Type | Default | Description |
|
|
237
|
+
| :----------------- | :-------------------------------------------------------- | :-------------------- | :----------------------------------------------------------------------------- |
|
|
238
|
+
| `baseURL` | `string` | `undefined` | Prepended to relative URLs. |
|
|
239
|
+
| `method` | `string` | `'get'` | HTTP request method (e.g., `'get'`, `'post'`). |
|
|
240
|
+
| `headers` | `Record` | `{}` | Key-value mapping of custom headers. |
|
|
241
|
+
| `params` | `Record` | `undefined` | Query parameters appended to the URL. |
|
|
242
|
+
| `data` | `any` | `undefined` | The payload to send in the request body. |
|
|
243
|
+
| `timeout` | `number` | `0` (disabled) | Request timeout in milliseconds. |
|
|
244
|
+
| `responseType` | `'json' \| 'text' \| 'blob' \| 'arraybuffer' \| 'stream'` | `'json'` | Expected format of the response data. |
|
|
245
|
+
| `retry` | `number` | `0` | Number of times to retry failed requests. |
|
|
246
|
+
| `retryDelay` | `number` | `1000` | Initial delay for exponential backoff (ms). |
|
|
247
|
+
| `retryOn429` | `boolean` | `false` | Automatically retry on 429 using the `Retry-After` header. |
|
|
248
|
+
| `rateLimiter` | `RateLimiter` | `undefined` | A rate limiter instance to enqueue requests. |
|
|
249
|
+
| `dedupe` | `boolean` | `false` | Coalesce concurrent duplicate GET requests. |
|
|
250
|
+
| `cache` | `boolean \| CacheProvider` | `false` | Enable caching using memory or custom provider. |
|
|
251
|
+
| `cacheTTL` | `number` | `undefined` | TTL for cached responses in ms. |
|
|
252
|
+
| `schema` | `SchemaValidator` | `undefined` | Zod/schema parser to validate response body. |
|
|
253
|
+
| `hooks` | `AccessioHooks` | `undefined` | Lifecycle callbacks: `onBeforeRequest`, `onRequestResponse`, `onRequestError`. |
|
|
254
|
+
| `allowedProtocols` | `string[] \| null` | `['http:', 'https:']` | Protocols allowed for requesting. Set to `null` to disable check. |
|
|
297
255
|
|
|
298
256
|
---
|
|
299
257
|
|
package/cjs/accessio.cjs
CHANGED
|
@@ -200,16 +200,12 @@ class Accessio {
|
|
|
200
200
|
);
|
|
201
201
|
if (!response.data) return;
|
|
202
202
|
const reader = response.data.getReader();
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const lines = buffer.split("\n");
|
|
210
|
-
buffer = lines.pop() || "";
|
|
211
|
-
for (const line of lines) {
|
|
212
|
-
if (line.trim().startsWith("data:")) {
|
|
203
|
+
try {
|
|
204
|
+
const decoder = new TextDecoder();
|
|
205
|
+
let buffer = "";
|
|
206
|
+
const processLine = function* (line) {
|
|
207
|
+
const trimmed = line.trim();
|
|
208
|
+
if (trimmed.startsWith("data:")) {
|
|
213
209
|
const dataStr = line.replace(/^data:\s*/, "");
|
|
214
210
|
if (dataStr === "[DONE]") return;
|
|
215
211
|
try {
|
|
@@ -217,13 +213,33 @@ class Accessio {
|
|
|
217
213
|
} catch (e) {
|
|
218
214
|
yield dataStr;
|
|
219
215
|
}
|
|
220
|
-
} else if (
|
|
216
|
+
} else if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
221
217
|
try {
|
|
222
218
|
yield JSON.parse(line);
|
|
223
219
|
} catch (e) {
|
|
224
220
|
}
|
|
225
221
|
}
|
|
222
|
+
};
|
|
223
|
+
while (true) {
|
|
224
|
+
const { done, value } = await reader.read();
|
|
225
|
+
if (done) break;
|
|
226
|
+
buffer += decoder.decode(value, { stream: true });
|
|
227
|
+
const lines = buffer.split("\n");
|
|
228
|
+
buffer = lines.pop() || "";
|
|
229
|
+
for (const line of lines) {
|
|
230
|
+
yield* processLine(line);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
buffer += decoder.decode(new Uint8Array(), { stream: false });
|
|
234
|
+
if (buffer.trim()) {
|
|
235
|
+
yield* processLine(buffer);
|
|
236
|
+
}
|
|
237
|
+
} finally {
|
|
238
|
+
try {
|
|
239
|
+
await reader.cancel();
|
|
240
|
+
} catch {
|
|
226
241
|
}
|
|
242
|
+
reader.releaseLock();
|
|
227
243
|
}
|
|
228
244
|
}
|
|
229
245
|
async *autoPaginate(url, config) {
|
|
@@ -231,13 +247,14 @@ class Accessio {
|
|
|
231
247
|
let currentConfig = config || {};
|
|
232
248
|
while (nextUrl) {
|
|
233
249
|
const response = await this.get(nextUrl, currentConfig);
|
|
234
|
-
const
|
|
250
|
+
const data = response.data;
|
|
251
|
+
const items = Array.isArray(data) ? data : data && typeof data === "object" ? data.data : null;
|
|
235
252
|
if (Array.isArray(items)) {
|
|
236
253
|
for (const item of items) {
|
|
237
254
|
yield item;
|
|
238
255
|
}
|
|
239
256
|
}
|
|
240
|
-
nextUrl =
|
|
257
|
+
nextUrl = data && typeof data === "object" ? data.next || data.links?.next || null : null;
|
|
241
258
|
if (nextUrl) {
|
|
242
259
|
currentConfig = (0, import_mergeConfig.default)(currentConfig, { url: nextUrl, params: {} });
|
|
243
260
|
}
|
package/cjs/accessio.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/accessio.ts"],"sourcesContent":["import InterceptorManager from './interceptors/interceptorManager';\nimport AccessioError from './core/accessioError';\nimport mergeConfig from './core/mergeConfig';\nimport dispatchRequest from './core/request';\nimport buildURL from './core/buildURL';\nimport retryRequest from './core/retry';\nimport { logRequest, logResponse, logError } from './helpers/debug';\nimport { rateLimitedRequest } from './helpers/rateLimiter';\nimport { toFormData } from './helpers/toFormData';\nimport type {\n AccessioRequestConfig,\n AccessioResponse,\n Interceptors,\n InterceptorHandler,\n} from './types';\nimport defaultsConfig from './defaults/index';\n\nfunction runRequestInterceptorsSync(\n startConfig: AccessioRequestConfig,\n interceptors: InterceptorHandler[],\n): Promise<AccessioRequestConfig> {\n let cfg = startConfig;\n let rejectReason: any = null;\n let isRejected = false;\n\n for (const interceptor of interceptors) {\n if (!isRejected) {\n try {\n if (interceptor.fulfilled) {\n cfg = (interceptor.fulfilled as any)(cfg) as AccessioRequestConfig;\n }\n } catch (err) {\n rejectReason = err;\n isRejected = true;\n }\n } else if (interceptor.rejected) {\n try {\n cfg = interceptor.rejected(rejectReason) as AccessioRequestConfig;\n isRejected = false;\n } catch (err) {\n rejectReason = err;\n isRejected = true;\n }\n }\n }\n\n return isRejected ? Promise.reject(rejectReason) : Promise.resolve(cfg);\n}\n\nfunction runRequestInterceptorsAsync(\n startConfig: AccessioRequestConfig,\n interceptors: InterceptorHandler[],\n): Promise<AccessioRequestConfig> {\n let promise: Promise<any> = Promise.resolve(startConfig);\n for (const interceptor of interceptors) {\n promise = promise.then(\n (value: any) => (interceptor.fulfilled ? (interceptor.fulfilled as any)(value) : value),\n interceptor.rejected ?? undefined,\n );\n }\n return promise as Promise<AccessioRequestConfig>;\n}\n\nfunction dispatchAndRetry(cfg: AccessioRequestConfig): Promise<AccessioResponse> {\n const fullUrl = buildURL(cfg.url ?? '', cfg.baseURL, cfg.params, cfg.paramsSerializer);\n logRequest(cfg, fullUrl);\n\n const enrichedCfg = fullUrl !== (cfg.url || '') ? { ...cfg, _builtUrl: fullUrl } : cfg;\n\n const dispatchFn = cfg.rateLimiter\n ? (config: AccessioRequestConfig) =>\n rateLimitedRequest(dispatchRequest, config.rateLimiter!, config)\n : dispatchRequest;\n\n return retryRequest(dispatchFn, enrichedCfg);\n}\n\nexport class Accessio {\n defaults: AccessioRequestConfig;\n interceptors: Interceptors;\n\n constructor(instanceConfig: AccessioRequestConfig = {}) {\n this.defaults = mergeConfig(defaultsConfig, instanceConfig);\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager(),\n };\n }\n\n request<T = any>(\n configOrUrl: string | AccessioRequestConfig,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n if (typeof configOrUrl === 'string') {\n config = { ...config, url: configOrUrl };\n } else {\n config = configOrUrl ? { ...configOrUrl } : {};\n }\n\n const mergedConfig = mergeConfig(this.defaults, config);\n\n mergedConfig.method = (mergedConfig.method || 'get').toLowerCase();\n\n if (!mergedConfig.url && !mergedConfig.baseURL) {\n throw new AccessioError(\n 'Request URL is required. Provide a `url` or `baseURL` in the config.',\n AccessioError.ERR_BAD_OPTION,\n mergedConfig,\n null,\n null,\n );\n }\n\n const { requestInterceptors, responseInterceptors, synchronous } =\n this.collectInterceptors(mergedConfig);\n\n let promise: Promise<any> = synchronous\n ? runRequestInterceptorsSync(mergedConfig, requestInterceptors)\n : runRequestInterceptorsAsync(mergedConfig, requestInterceptors);\n\n promise = promise.then((cfg: AccessioRequestConfig) => dispatchAndRetry(cfg));\n\n promise = promise.then(\n (value: AccessioResponse) => {\n logResponse(value);\n return value;\n },\n (error: any) => {\n logError(error, mergedConfig);\n throw error;\n },\n );\n\n for (const interceptor of responseInterceptors) {\n promise = promise.then((value: any) => {\n if (interceptor.fulfilled) {\n return (interceptor.fulfilled as any)(value);\n }\n return value;\n }, interceptor.rejected ?? undefined);\n }\n\n return promise;\n }\n\n private collectInterceptors(mergedConfig: AccessioRequestConfig): {\n requestInterceptors: InterceptorHandler[];\n responseInterceptors: InterceptorHandler[];\n synchronous: boolean;\n } {\n const requestInterceptors: InterceptorHandler[] = [];\n const responseInterceptors: InterceptorHandler[] = [];\n let synchronous = true;\n\n this.interceptors.request.forEach((interceptor: InterceptorHandler) => {\n if (interceptor.runWhen && !interceptor.runWhen(mergedConfig)) return;\n synchronous = synchronous && interceptor.synchronous;\n requestInterceptors.unshift(interceptor);\n });\n\n this.interceptors.response.forEach((interceptor: InterceptorHandler) => {\n responseInterceptors.push(interceptor);\n });\n\n return { requestInterceptors, responseInterceptors, synchronous };\n }\n\n getUri(config?: AccessioRequestConfig): string {\n const merged = mergeConfig(this.defaults, config);\n return buildURL(merged.url ?? '', merged.baseURL, merged.params, merged.paramsSerializer);\n }\n\n get<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'get', url }));\n }\n\n delete<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'delete', url }));\n }\n\n head<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'head', url }));\n }\n\n options<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'options', url }));\n }\n\n post<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'post', url, data }));\n }\n\n put<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'put', url, data }));\n }\n\n patch<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'patch', url, data }));\n }\n\n private formRequest<T = any>(\n method: 'post' | 'put' | 'patch',\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n const formData = data && !(data instanceof FormData) ? toFormData(data) : data;\n return this.request<T>(\n mergeConfig(config || {}, {\n method,\n url,\n data: formData,\n headers: { 'Content-Type': 'multipart/form-data' },\n }),\n );\n }\n\n postForm<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.formRequest<T>('post', url, data, config);\n }\n\n putForm<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.formRequest<T>('put', url, data, config);\n }\n\n patchForm<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.formRequest<T>('patch', url, data, config);\n }\n\n async *stream<T = any>(\n url: string,\n config?: AccessioRequestConfig,\n ): AsyncGenerator<T, void, unknown> {\n const response = await this.request<ReadableStream<Uint8Array>>(\n mergeConfig(config || {}, { method: 'get', url, responseType: 'stream' }),\n );\n if (!response.data) return;\n\n const reader = response.data.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim().startsWith('data:')) {\n const dataStr = line.replace(/^data:\\s*/, '');\n if (dataStr === '[DONE]') return;\n try {\n yield JSON.parse(dataStr);\n } catch (e) {\n yield dataStr as any;\n }\n } else if (line.trim().startsWith('{') || line.trim().startsWith('[')) {\n try {\n yield JSON.parse(line);\n } catch (e) {\n // ignore partial json\n }\n }\n }\n }\n }\n\n async *autoPaginate<T = any>(\n url: string,\n config?: AccessioRequestConfig,\n ): AsyncGenerator<T, void, unknown> {\n let nextUrl: string | null = url;\n let currentConfig = config || {};\n\n while (nextUrl) {\n const response: AccessioResponse<any> = await this.get(nextUrl, currentConfig);\n\n const items = Array.isArray(response.data) ? response.data : response.data.data;\n if (Array.isArray(items)) {\n for (const item of items) {\n yield item;\n }\n }\n\n nextUrl = response.data.next || response.data.links?.next || null;\n if (nextUrl) {\n currentConfig = mergeConfig(currentConfig, { url: nextUrl, params: {} });\n }\n }\n }\n\n gql<T = any>(\n url: string,\n query: string,\n variables?: Record<string, any>,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.post<T>(url, { query, variables }, config);\n }\n}\n\nexport default Accessio;\n"],"mappings":"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","names":["buildURL","dispatchRequest","retryRequest","mergeConfig","defaultsConfig","InterceptorManager","AccessioError"]}
|
|
1
|
+
{"version":3,"sources":["../src/accessio.ts"],"sourcesContent":["import InterceptorManager from './interceptors/interceptorManager';\nimport AccessioError from './core/accessioError';\nimport mergeConfig from './core/mergeConfig';\nimport dispatchRequest from './core/request';\nimport buildURL from './core/buildURL';\nimport retryRequest from './core/retry';\nimport { logRequest, logResponse, logError } from './helpers/debug';\nimport { rateLimitedRequest } from './helpers/rateLimiter';\nimport { toFormData } from './helpers/toFormData';\nimport type {\n AccessioRequestConfig,\n AccessioResponse,\n Interceptors,\n InterceptorHandler,\n} from './types';\nimport defaultsConfig from './defaults/index';\n\nfunction runRequestInterceptorsSync(\n startConfig: AccessioRequestConfig,\n interceptors: InterceptorHandler[],\n): Promise<AccessioRequestConfig> {\n let cfg = startConfig;\n let rejectReason: any = null;\n let isRejected = false;\n\n for (const interceptor of interceptors) {\n if (!isRejected) {\n try {\n if (interceptor.fulfilled) {\n cfg = (interceptor.fulfilled as any)(cfg) as AccessioRequestConfig;\n }\n } catch (err) {\n rejectReason = err;\n isRejected = true;\n }\n } else if (interceptor.rejected) {\n try {\n cfg = interceptor.rejected(rejectReason) as AccessioRequestConfig;\n isRejected = false;\n } catch (err) {\n rejectReason = err;\n isRejected = true;\n }\n }\n }\n\n return isRejected ? Promise.reject(rejectReason) : Promise.resolve(cfg);\n}\n\nfunction runRequestInterceptorsAsync(\n startConfig: AccessioRequestConfig,\n interceptors: InterceptorHandler[],\n): Promise<AccessioRequestConfig> {\n let promise: Promise<any> = Promise.resolve(startConfig);\n for (const interceptor of interceptors) {\n promise = promise.then(\n (value: any) => (interceptor.fulfilled ? (interceptor.fulfilled as any)(value) : value),\n interceptor.rejected ?? undefined,\n );\n }\n return promise as Promise<AccessioRequestConfig>;\n}\n\nfunction dispatchAndRetry(cfg: AccessioRequestConfig): Promise<AccessioResponse> {\n const fullUrl = buildURL(cfg.url ?? '', cfg.baseURL, cfg.params, cfg.paramsSerializer);\n logRequest(cfg, fullUrl);\n\n const enrichedCfg = fullUrl !== (cfg.url || '') ? { ...cfg, _builtUrl: fullUrl } : cfg;\n\n const dispatchFn = cfg.rateLimiter\n ? (config: AccessioRequestConfig) =>\n rateLimitedRequest(dispatchRequest, config.rateLimiter!, config)\n : dispatchRequest;\n\n return retryRequest(dispatchFn, enrichedCfg);\n}\n\nexport class Accessio {\n defaults: AccessioRequestConfig;\n interceptors: Interceptors;\n\n constructor(instanceConfig: AccessioRequestConfig = {}) {\n this.defaults = mergeConfig(defaultsConfig, instanceConfig);\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager(),\n };\n }\n\n request<T = any>(\n configOrUrl: string | AccessioRequestConfig,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n if (typeof configOrUrl === 'string') {\n config = { ...config, url: configOrUrl };\n } else {\n config = configOrUrl ? { ...configOrUrl } : {};\n }\n\n const mergedConfig = mergeConfig(this.defaults, config);\n\n mergedConfig.method = (mergedConfig.method || 'get').toLowerCase();\n\n if (!mergedConfig.url && !mergedConfig.baseURL) {\n throw new AccessioError(\n 'Request URL is required. Provide a `url` or `baseURL` in the config.',\n AccessioError.ERR_BAD_OPTION,\n mergedConfig,\n null,\n null,\n );\n }\n\n const { requestInterceptors, responseInterceptors, synchronous } =\n this.collectInterceptors(mergedConfig);\n\n let promise: Promise<any> = synchronous\n ? runRequestInterceptorsSync(mergedConfig, requestInterceptors)\n : runRequestInterceptorsAsync(mergedConfig, requestInterceptors);\n\n promise = promise.then((cfg: AccessioRequestConfig) => dispatchAndRetry(cfg));\n\n promise = promise.then(\n (value: AccessioResponse) => {\n logResponse(value);\n return value;\n },\n (error: any) => {\n logError(error, mergedConfig);\n throw error;\n },\n );\n\n for (const interceptor of responseInterceptors) {\n promise = promise.then((value: any) => {\n if (interceptor.fulfilled) {\n return (interceptor.fulfilled as any)(value);\n }\n return value;\n }, interceptor.rejected ?? undefined);\n }\n\n return promise;\n }\n\n private collectInterceptors(mergedConfig: AccessioRequestConfig): {\n requestInterceptors: InterceptorHandler[];\n responseInterceptors: InterceptorHandler[];\n synchronous: boolean;\n } {\n const requestInterceptors: InterceptorHandler[] = [];\n const responseInterceptors: InterceptorHandler[] = [];\n let synchronous = true;\n\n this.interceptors.request.forEach((interceptor: InterceptorHandler) => {\n if (interceptor.runWhen && !interceptor.runWhen(mergedConfig)) return;\n synchronous = synchronous && interceptor.synchronous;\n requestInterceptors.unshift(interceptor);\n });\n\n this.interceptors.response.forEach((interceptor: InterceptorHandler) => {\n responseInterceptors.push(interceptor);\n });\n\n return { requestInterceptors, responseInterceptors, synchronous };\n }\n\n getUri(config?: AccessioRequestConfig): string {\n const merged = mergeConfig(this.defaults, config);\n return buildURL(merged.url ?? '', merged.baseURL, merged.params, merged.paramsSerializer);\n }\n\n get<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'get', url }));\n }\n\n delete<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'delete', url }));\n }\n\n head<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'head', url }));\n }\n\n options<T = any>(url: string, config?: AccessioRequestConfig): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'options', url }));\n }\n\n post<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'post', url, data }));\n }\n\n put<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'put', url, data }));\n }\n\n patch<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.request<T>(mergeConfig(config || {}, { method: 'patch', url, data }));\n }\n\n private formRequest<T = any>(\n method: 'post' | 'put' | 'patch',\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n const formData = data && !(data instanceof FormData) ? toFormData(data) : data;\n return this.request<T>(\n mergeConfig(config || {}, {\n method,\n url,\n data: formData,\n headers: { 'Content-Type': 'multipart/form-data' },\n }),\n );\n }\n\n postForm<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.formRequest<T>('post', url, data, config);\n }\n\n putForm<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.formRequest<T>('put', url, data, config);\n }\n\n patchForm<T = any>(\n url: string,\n data?: any,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.formRequest<T>('patch', url, data, config);\n }\n\n async *stream<T = any>(\n url: string,\n config?: AccessioRequestConfig,\n ): AsyncGenerator<T, void, unknown> {\n const response = await this.request<ReadableStream<Uint8Array>>(\n mergeConfig(config || {}, { method: 'get', url, responseType: 'stream' }),\n );\n if (!response.data) return;\n\n const reader = response.data.getReader();\n try {\n const decoder = new TextDecoder();\n let buffer = '';\n\n const processLine = function* (line: string) {\n const trimmed = line.trim();\n if (trimmed.startsWith('data:')) {\n const dataStr = line.replace(/^data:\\s*/, '');\n if (dataStr === '[DONE]') return;\n try {\n yield JSON.parse(dataStr);\n } catch (e) {\n yield dataStr as any;\n }\n } else if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n yield JSON.parse(line);\n } catch (e) {\n // ignore partial json\n }\n }\n };\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n yield* processLine(line);\n }\n }\n\n buffer += decoder.decode(new Uint8Array(), { stream: false });\n if (buffer.trim()) {\n yield* processLine(buffer);\n }\n } finally {\n try {\n await reader.cancel();\n } catch {\n // ignore errors on cancel\n }\n reader.releaseLock();\n }\n }\n\n async *autoPaginate<T = any>(\n url: string,\n config?: AccessioRequestConfig,\n ): AsyncGenerator<T, void, unknown> {\n let nextUrl: string | null = url;\n let currentConfig = config || {};\n\n while (nextUrl) {\n const response: AccessioResponse<any> = await this.get(nextUrl, currentConfig);\n\n const data = response.data;\n const items = Array.isArray(data)\n ? data\n : data && typeof data === 'object'\n ? (data as any).data\n : null;\n\n if (Array.isArray(items)) {\n for (const item of items) {\n yield item;\n }\n }\n\n nextUrl =\n data && typeof data === 'object'\n ? (data as any).next || (data as any).links?.next || null\n : null;\n\n if (nextUrl) {\n currentConfig = mergeConfig(currentConfig, { url: nextUrl, params: {} });\n }\n }\n }\n\n gql<T = any>(\n url: string,\n query: string,\n variables?: Record<string, any>,\n config?: AccessioRequestConfig,\n ): Promise<AccessioResponse<T>> {\n return this.post<T>(url, { query, variables }, config);\n }\n}\n\nexport default Accessio;\n"],"mappings":"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","names":["buildURL","dispatchRequest","retryRequest","mergeConfig","defaultsConfig","InterceptorManager","AccessioError"]}
|