create-request 1.6.1 → 2.0.0-next.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.
@@ -1,870 +0,0 @@
1
- import { type HttpMethod, RedirectMode, RequestMode, RequestPriority, ReferrerPolicy, CredentialsPolicy } from "./enums.js";
2
- import type { RetryConfig, RetryCallback, CookiesRecord, CookieOptions, FetchFunction, RequestOptions, GraphQLOptions, ErrorInterceptor, RequestInterceptor, ResponseInterceptor } from "./types.js";
3
- import { ResponseWrapper } from "./ResponseWrapper.js";
4
- /**
5
- * Base class with common functionality for all request types
6
- * Provides the core request building and execution capabilities.
7
- */
8
- export declare abstract class BaseRequest {
9
- protected abstract _method: HttpMethod;
10
- protected _url: string;
11
- protected _opts: RequestOptions;
12
- protected _ctrl?: AbortController;
13
- protected _fetch?: FetchFunction;
14
- protected _query: URLSearchParams;
15
- protected _autoCsrf: boolean;
16
- private _reqI;
17
- private _resI;
18
- private _errI;
19
- constructor(url: string);
20
- /**
21
- * Get GraphQL options if set (only for BodyRequest subclasses)
22
- * @returns GraphQL options or undefined
23
- */
24
- protected _gql(): GraphQLOptions | undefined;
25
- /**
26
- * Creates a fluent API for setting enum-based options
27
- * Combines direct setter with convenience methods
28
- */
29
- private _fluent;
30
- private _validateUrl;
31
- /**
32
- * Add multiple HTTP headers to the request
33
- *
34
- * @param headers - Key-value pairs of header names and values
35
- * @returns The request instance for chaining
36
- *
37
- * @example
38
- * request.withHeaders({
39
- * 'Accept': 'application/json',
40
- * 'X-Custom-Header': 'value'
41
- * });
42
- */
43
- withHeaders(headers: Record<string, string>): this;
44
- /**
45
- * Add a single HTTP header to the request
46
- *
47
- * @param key - The header name
48
- * @param value - The header value
49
- * @returns The request instance for chaining
50
- *
51
- * @example
52
- * request.withHeader('Accept', 'application/json');
53
- */
54
- withHeader(key: string, value: string): this;
55
- /**
56
- * Set a timeout for the request
57
- * If the request takes longer than the specified timeout, it will be aborted.
58
- *
59
- * @param timeout - The timeout in milliseconds
60
- * @returns The request instance for chaining
61
- * @throws RequestError if timeout is not a positive number
62
- *
63
- * @example
64
- * request.withTimeout(5000); // 5 seconds timeout
65
- */
66
- withTimeout(timeout: number): this;
67
- /**
68
- * Configure automatic retry behavior for failed requests
69
- *
70
- * @param retries - Number of retry attempts before failing, or a configuration object
71
- * @returns The request instance for chaining
72
- * @throws RequestError if retries is not a non-negative integer or invalid config
73
- *
74
- * @example
75
- * // Simple number (backward compatible)
76
- * request.withRetries(3); // Retry up to 3 times
77
- *
78
- * @example
79
- * // With fixed delay
80
- * request.withRetries({ attempts: 3, delay: 1000 }); // Retry 3 times with 1 second delay
81
- *
82
- * @example
83
- * // With exponential backoff function
84
- * request.withRetries({
85
- * attempts: 3,
86
- * delay: ({ attempt }) => Math.min(1000 * Math.pow(2, attempt - 1), 10000)
87
- * });
88
- *
89
- * @example
90
- * // With delay function based on error
91
- * request.withRetries({
92
- * attempts: 3,
93
- * delay: ({ attempt, error }) => {
94
- * if (error.status === 429) return 5000; // Rate limited, wait longer
95
- * return attempt * 1000; // Exponential backoff
96
- * }
97
- * });
98
- */
99
- withRetries(retries: number | RetryConfig): this;
100
- /**
101
- * Set a callback to be invoked before each retry attempt
102
- * Useful for implementing backoff strategies or logging retry attempts.
103
- *
104
- * @param callback - Function to call before retrying
105
- * @returns The request instance for chaining
106
- *
107
- * @example
108
- * request.onRetry(({ attempt, error }) => {
109
- * console.log(`Retry attempt ${attempt} after error: ${error.message}`);
110
- * return new Promise(resolve => setTimeout(resolve, attempt * 1000));
111
- * });
112
- */
113
- onRetry(callback: RetryCallback): this;
114
- /**
115
- * Sets the credentials policy for the request, controlling whether cookies and authentication
116
- * headers are sent with cross-origin requests.
117
- *
118
- * @param credentialsPolicy - The credentials policy to use:
119
- * - `"include"` or `CredentialsPolicy.INCLUDE`: Always send credentials (cookies, authorization headers) with the request, even for cross-origin requests.
120
- * - `"omit"` or `CredentialsPolicy.OMIT`: Never send credentials, even for same-origin requests.
121
- * - `"same-origin"` or `CredentialsPolicy.SAME_ORIGIN`: Only send credentials for same-origin requests (default behavior in most browsers).
122
- *
123
- * @returns The request instance for chaining
124
- *
125
- * @example
126
- * // Using string values
127
- * request.withCredentials("include")
128
- *
129
- * @example
130
- * // Using enum values
131
- * request.withCredentials(CredentialsPolicy.INCLUDE)
132
- *
133
- * @example
134
- * // Using fluent API
135
- * request.withCredentials.INCLUDE()
136
- */
137
- get withCredentials(): ((credentialsPolicy: CredentialsPolicy) => BaseRequest) & {
138
- INCLUDE: () => BaseRequest;
139
- OMIT: () => BaseRequest;
140
- SAME_ORIGIN: () => BaseRequest;
141
- };
142
- /**
143
- * Allows providing an external AbortController to cancel the request.
144
- * This is useful when you need to cancel a request from outside the request chain,
145
- *
146
- * @param controller - The AbortController to use for this request. When `controller.abort()` is called,
147
- * the request will be cancelled and throw an abort error.
148
- *
149
- * @returns The request instance for chaining
150
- *
151
- * @example
152
- * const controller = new AbortController();
153
- * const request = createRequest('/api/data')
154
- * .withAbortController(controller)
155
- * .getJson();
156
- *
157
- * // Later, cancel the request
158
- * controller.abort();
159
- *
160
- * @example
161
- * // Share abort controller across multiple requests
162
- * const controller = new AbortController();
163
- * request1.withAbortController(controller).getJson();
164
- * request2.withAbortController(controller).getJson();
165
- * // Aborting will cancel both requests
166
- * controller.abort();
167
- */
168
- withAbortController(controller: AbortController): this;
169
- /**
170
- * Sets a custom fetch implementation used to execute this request.
171
- * By default, requests use the global `fetch`. Injecting a custom function unlocks
172
- * testing without global mocks, custom undici dispatchers/agents in Node.js,
173
- * and framework-specific fetch extensions (e.g. Next.js caching options).
174
- *
175
- * The provided function receives the final URL and `RequestInit` (after interceptors)
176
- * and must return a `Promise<Response>`. It should honor `init.signal` so that
177
- * `withTimeout` and `withAbortController` keep working.
178
- *
179
- * @param fetchFn - A fetch-compatible function
180
- * @returns The request instance for chaining
181
- * @throws {RequestError} If fetchFn is not a function
182
- *
183
- * @example
184
- * // Testing: inject a stub instead of mocking the global fetch
185
- * const stubFetch: FetchFunction = async () => new Response('{"ok":true}');
186
- * const data = await create.get('/api/users').withFetch(stubFetch).getJson();
187
- *
188
- * @example
189
- * // Node.js: route through a custom undici agent (proxy, keep-alive tuning, ...)
190
- * import { fetch as undiciFetch, Agent } from 'undici';
191
- * const agent = new Agent({ keepAliveTimeout: 30_000 });
192
- * request.withFetch((url, init) => undiciFetch(url, { ...init, dispatcher: agent }));
193
- *
194
- * @example
195
- * // Next.js: pass caching hints through to the framework's patched fetch
196
- * request.withFetch((url, init) => fetch(url, { ...init, next: { revalidate: 60 } }));
197
- */
198
- withFetch(fetchFn: FetchFunction): this;
199
- /**
200
- * Sets the referrer URL for the request. The referrer is the URL of the page that initiated the request.
201
- * This can be used to override the default referrer that the browser would normally send.
202
- *
203
- * @param referrer - The referrer URL to send with the request. Can be:
204
- * - A full URL (e.g., "https://example.com/page")
205
- * - An empty string to omit the referrer
206
- * - A relative URL (will be resolved relative to the current page)
207
- *
208
- * @returns The request instance for chaining
209
- *
210
- * @example
211
- * request.withReferrer("https://example.com/previous-page")
212
- *
213
- * @example
214
- * // Omit referrer
215
- * request.withReferrer("")
216
- */
217
- withReferrer(referrer: string): this;
218
- /**
219
- * Sets the referrer policy for the request, controlling how much referrer information
220
- * is sent with the request. This helps balance privacy and functionality.
221
- *
222
- * @param policy - The referrer policy to use:
223
- * - `"no-referrer"` or `ReferrerPolicy.NO_REFERRER`: Never send the referrer header.
224
- * - `"no-referrer-when-downgrade"` or `ReferrerPolicy.NO_REFERRER_WHEN_DOWNGRADE`: Send full referrer for same-origin or HTTPS→HTTPS, omit for HTTPS→HTTP (default in most browsers).
225
- * - `"origin"` or `ReferrerPolicy.ORIGIN`: Only send the origin (scheme, host, port), not the full URL.
226
- * - `"origin-when-cross-origin"` or `ReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN`: Send full referrer for same-origin, only origin for cross-origin.
227
- * - `"same-origin"` or `ReferrerPolicy.SAME_ORIGIN`: Send full referrer for same-origin requests only, omit for cross-origin.
228
- * - `"strict-origin"` or `ReferrerPolicy.STRICT_ORIGIN`: Send origin for HTTPS→HTTPS or HTTP→HTTP, omit for HTTPS→HTTP.
229
- * - `"strict-origin-when-cross-origin"` or `ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN`: Send full referrer for same-origin, origin for cross-origin HTTPS→HTTPS, omit for HTTPS→HTTP.
230
- * - `"unsafe-url"` or `ReferrerPolicy.UNSAFE_URL`: Always send the full referrer URL (may leak sensitive information).
231
- *
232
- * @returns The request instance for chaining
233
- *
234
- * @example
235
- * // Using string values
236
- * request.withReferrerPolicy("no-referrer")
237
- *
238
- * @example
239
- * // Using enum values
240
- * request.withReferrerPolicy(ReferrerPolicy.NO_REFERRER)
241
- *
242
- * @example
243
- * // Using fluent API
244
- * request.withReferrerPolicy.NO_REFERRER()
245
- */
246
- get withReferrerPolicy(): ((policy: ReferrerPolicy) => BaseRequest) & {
247
- ORIGIN: () => BaseRequest;
248
- UNSAFE_URL: () => BaseRequest;
249
- SAME_ORIGIN: () => BaseRequest;
250
- NO_REFERRER: () => BaseRequest;
251
- STRICT_ORIGIN: () => BaseRequest;
252
- ORIGIN_WHEN_CROSS_ORIGIN: () => BaseRequest;
253
- NO_REFERRER_WHEN_DOWNGRADE: () => BaseRequest;
254
- STRICT_ORIGIN_WHEN_CROSS_ORIGIN: () => BaseRequest;
255
- };
256
- /**
257
- * Sets how the request handles HTTP redirects (3xx status codes).
258
- *
259
- * @param redirect - The redirect handling mode:
260
- * - `"follow"` or `RedirectMode.FOLLOW`: Automatically follow redirects. The fetch will transparently follow redirects and return the final response (default behavior).
261
- * - `"error"` or `RedirectMode.ERROR`: Treat redirects as errors. If a redirect occurs, the request will fail with an error.
262
- * - `"manual"` or `RedirectMode.MANUAL`: Return the redirect response without following it. The response will have a `type` of "opaqueredirect" and you can manually handle the redirect.
263
- *
264
- * @returns The request instance for chaining
265
- *
266
- * @example
267
- * // Using string values
268
- * request.withRedirect("follow")
269
- *
270
- * @example
271
- * // Using enum values
272
- * request.withRedirect(RedirectMode.FOLLOW)
273
- *
274
- * @example
275
- * // Using fluent API
276
- * request.withRedirect.FOLLOW()
277
- *
278
- * @example
279
- * // Fail on redirects
280
- * request.withRedirect.ERROR()
281
- */
282
- get withRedirect(): ((redirect: RedirectMode) => BaseRequest) & {
283
- FOLLOW: () => BaseRequest;
284
- ERROR: () => BaseRequest;
285
- MANUAL: () => BaseRequest;
286
- };
287
- /**
288
- * Sets the keepalive flag for the request. When enabled, the request can continue
289
- * even after the page that initiated it is closed. This is useful for analytics,
290
- * logging, or other background requests that should complete even if the user navigates away.
291
- *
292
- * @param keepalive - Whether to allow the request to outlive the page:
293
- * - `true`: The request will continue even if the page is closed or navigated away.
294
- * - `false`: The request will be cancelled if the page is closed (default).
295
- *
296
- * @returns The request instance for chaining
297
- *
298
- * @example
299
- * // Send analytics event that should complete even if user navigates away
300
- * request.withKeepAlive(true)
301
- */
302
- withKeepAlive(keepalive: boolean): this;
303
- /**
304
- * Sets the priority hint for the request, indicating to the browser how important
305
- * this request is relative to other requests. This helps the browser optimize resource loading.
306
- *
307
- * @param priority - The request priority:
308
- * - `"high"` or `RequestPriority.HIGH`: High priority - the browser should prioritize this request.
309
- * - `"low"` or `RequestPriority.LOW`: Low priority - the browser can defer this request if needed.
310
- * - `"auto"` or `RequestPriority.AUTO`: Automatic priority based on the request type (default).
311
- *
312
- * @returns The request instance for chaining
313
- *
314
- * @example
315
- * // Using string values
316
- * request.withPriority("high")
317
- *
318
- * @example
319
- * // Using enum values
320
- * request.withPriority(RequestPriority.HIGH)
321
- *
322
- * @example
323
- * // Using fluent API
324
- * request.withPriority.HIGH()
325
- *
326
- * @example
327
- * // Low priority for non-critical requests
328
- * request.withPriority.LOW()
329
- */
330
- get withPriority(): ((priority: RequestPriority) => BaseRequest) & {
331
- HIGH: () => BaseRequest;
332
- LOW: () => BaseRequest;
333
- AUTO: () => BaseRequest;
334
- };
335
- /**
336
- * Sets the integrity hash for Subresource Integrity (SRI) verification.
337
- * This allows the browser to verify that the fetched resource hasn't been tampered with
338
- * by comparing its hash against the provided value. If the hashes don't match, the request fails.
339
- *
340
- * @param integrity - The integrity hash string in the format `"algorithm-hash"`:
341
- * - Example: `"sha256-abcdef1234567890..."` (SHA-256 hash)
342
- * - Example: `"sha384-abcdef1234567890..."` (SHA-384 hash)
343
- * - Example: `"sha512-abcdef1234567890..."` (SHA-512 hash)
344
- * - Multiple hashes can be separated by spaces: `"sha256-... sha384-..."`
345
- *
346
- * @returns The request instance for chaining
347
- *
348
- * @example
349
- * request.withIntegrity("sha256-abcdef1234567890...")
350
- *
351
- * @example
352
- * // Multiple algorithms for better compatibility
353
- * request.withIntegrity("sha256-... sha384-...")
354
- */
355
- withIntegrity(integrity: string): this;
356
- /**
357
- * Sets the cache mode for the request, controlling how the browser's HTTP cache
358
- * is used for this request.
359
- *
360
- * @param cache - The cache mode:
361
- * - `"default"` or `CacheMode.DEFAULT`: Use the browser's default cache behavior. The browser will check the cache and use it if valid, otherwise fetch from network.
362
- * - `"no-store"` or `CacheMode.NO_STORE`: Never use the cache and don't store the response in cache. Always fetch from network.
363
- * - `"reload"` or `CacheMode.RELOAD`: Bypass the cache but store the response. Always fetch from network, ignoring cached responses.
364
- * - `"no-cache"` or `CacheMode.NO_CACHE`: Check the cache but revalidate with the server. Use cached response only if server confirms it's still valid.
365
- * - `"force-cache"` or `CacheMode.FORCE_CACHE`: Use the cache if available, even if stale. Only fetch from network if not in cache.
366
- * - `"only-if-cached"` or `CacheMode.ONLY_IF_CACHED`: Only use the cache. If not in cache, return an error. Never fetch from network.
367
- *
368
- * @returns The request instance for chaining
369
- *
370
- * @example
371
- * // Using string values
372
- * request.withCache("no-cache")
373
- *
374
- * @example
375
- * // Using enum values
376
- * request.withCache(CacheMode.NO_CACHE)
377
- *
378
- * @example
379
- * // Using fluent API
380
- * request.withCache.NO_CACHE()
381
- *
382
- * @example
383
- * // Always fetch fresh data
384
- * request.withCache.RELOAD()
385
- *
386
- * @example
387
- * // Use cache only, fail if not cached
388
- * request.withCache.ONLY_IF_CACHED()
389
- */
390
- get withCache(): ((cache: string) => BaseRequest) & {
391
- DEFAULT: () => BaseRequest;
392
- NO_STORE: () => BaseRequest;
393
- RELOAD: () => BaseRequest;
394
- NO_CACHE: () => BaseRequest;
395
- FORCE_CACHE: () => BaseRequest;
396
- ONLY_IF_CACHED: () => BaseRequest;
397
- };
398
- /**
399
- * Adds query parameters to the request URL.
400
- * Multiple calls will append parameters. Array values will create multiple query parameters with the same key.
401
- * Null and undefined values are ignored.
402
- *
403
- * @param params - An object containing query parameter key-value pairs.
404
- * Values can be strings, numbers, booleans, arrays (for multiple values), or null/undefined (ignored).
405
- * @returns The request instance for chaining
406
- *
407
- * @example
408
- * ```typescript
409
- * // Simple parameters
410
- * request.withQueryParams({ page: 1, limit: 10, active: true });
411
- * // Results in: ?page=1&limit=10&active=true
412
- * ```
413
- *
414
- * @example
415
- * ```typescript
416
- * // Array values create multiple parameters
417
- * request.withQueryParams({ tags: ['js', 'ts', 'node'] });
418
- * // Results in: ?tags=js&tags=ts&tags=node
419
- * ```
420
- *
421
- * @example
422
- * ```typescript
423
- * // Null/undefined values are ignored
424
- * request.withQueryParams({ page: 1, filter: null, sort: undefined });
425
- * // Results in: ?page=1
426
- * ```
427
- */
428
- withQueryParams(params: Record<string, string | string[] | number | boolean | null | undefined>): this;
429
- /**
430
- * Adds a single query parameter to the request URL.
431
- * Convenience method for adding one parameter at a time.
432
- *
433
- * @param key - The query parameter name
434
- * @param value - The query parameter value. Can be a string, number, boolean, array (for multiple values), or null/undefined (ignored).
435
- * @returns The request instance for chaining
436
- *
437
- * @example
438
- * ```typescript
439
- * request.withQueryParam('page', 1).withQueryParam('limit', 10);
440
- * // Results in: ?page=1&limit=10
441
- * ```
442
- *
443
- * @example
444
- * ```typescript
445
- * // Array values create multiple parameters
446
- * request.withQueryParam('tags', ['js', 'ts']);
447
- * // Results in: ?tags=js&tags=ts
448
- * ```
449
- */
450
- withQueryParam(key: string, value: string | string[] | number | boolean | null | undefined): this;
451
- /**
452
- * Sets the request mode, which determines the CORS (Cross-Origin Resource Sharing) behavior
453
- * for the request. This controls how the browser handles cross-origin requests.
454
- *
455
- * @param mode - The request mode:
456
- * - `"cors"` or `RequestMode.CORS`: Enable CORS. The browser will send CORS headers and enforce CORS rules. This is the default for most cross-origin requests.
457
- * - `"no-cors"` or `RequestMode.NO_CORS`: Disable CORS. The request is sent as a "simple" request without CORS headers. The response will be opaque (you can't read it).
458
- * - `"same-origin"` or `RequestMode.SAME_ORIGIN`: Only allow same-origin requests. Cross-origin requests will fail.
459
- * - `"navigate"` or `RequestMode.NAVIGATE`: Used for navigation requests (typically only used by the browser itself).
460
- *
461
- * @returns The request instance for chaining
462
- *
463
- * @example
464
- * // Using string values
465
- * request.withMode("cors")
466
- *
467
- * @example
468
- * // Using enum values
469
- * request.withMode(RequestMode.CORS)
470
- *
471
- * @example
472
- * // Using fluent API
473
- * request.withMode.CORS()
474
- *
475
- * @example
476
- * // Restrict to same-origin only
477
- * request.withMode.SAME_ORIGIN()
478
- */
479
- get withMode(): ((mode: RequestMode) => BaseRequest) & {
480
- CORS: () => BaseRequest;
481
- NO_CORS: () => BaseRequest;
482
- SAME_ORIGIN: () => BaseRequest;
483
- NAVIGATE: () => BaseRequest;
484
- };
485
- /**
486
- * Sets the Content-Type header for the request.
487
- * Shorthand for `withHeader('Content-Type', contentType)`.
488
- *
489
- * @param contentType - The MIME type (e.g., `'application/json'`, `'text/plain'`, `'multipart/form-data'`)
490
- * @returns The request instance for chaining
491
- *
492
- * @example
493
- * ```typescript
494
- * request.withContentType('application/json');
495
- * ```
496
- *
497
- * @example
498
- * ```typescript
499
- * request.withContentType('application/xml');
500
- * ```
501
- */
502
- withContentType(contentType: string): this;
503
- /**
504
- * Sets the Authorization header for the request.
505
- * Shorthand for `withHeader('Authorization', authValue)`.
506
- * For Bearer tokens, use `withBearerToken()` instead. For Basic auth, use `withBasicAuth()`.
507
- *
508
- * @param authValue - The full authorization header value (e.g., `'Bearer token123'`, `'Basic base64string'`)
509
- * @returns The request instance for chaining
510
- *
511
- * @example
512
- * ```typescript
513
- * request.withAuthorization('Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');
514
- * ```
515
- *
516
- * @example
517
- * ```typescript
518
- * request.withAuthorization('CustomScheme customToken');
519
- * ```
520
- */
521
- withAuthorization(authValue: string): this;
522
- /**
523
- * Sets up HTTP Basic Authentication.
524
- * Encodes the username and password in base64 and sets the Authorization header.
525
- *
526
- * @param username - The username for Basic authentication
527
- * @param password - The password for Basic authentication
528
- * @returns The request instance for chaining
529
- *
530
- * @example
531
- * ```typescript
532
- * request.withBasicAuth('myuser', 'mypassword');
533
- * // Sets: Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=
534
- * ```
535
- */
536
- withBasicAuth(username: string, password: string): this;
537
- /**
538
- * Cross-environment base64 encoding
539
- * Works in both browser and Node.js environments
540
- */
541
- private _b64;
542
- /**
543
- * Sets a Bearer token for authentication.
544
- * Shorthand for `withAuthorization('Bearer ' + token)`.
545
- *
546
- * @param token - The Bearer token (JWT, OAuth token, etc.)
547
- * @returns The request instance for chaining
548
- *
549
- * @example
550
- * ```typescript
551
- * request.withBearerToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');
552
- * // Sets: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
553
- * ```
554
- */
555
- withBearerToken(token: string): this;
556
- /**
557
- * Safely get headers as a Record<string, string>
558
- * @returns The headers object
559
- */
560
- private _headers;
561
- /**
562
- * Helper function to check for header presence in a case-insensitive way
563
- * @param headerName Header name to check
564
- * @returns Boolean indicating if the header exists (case-insensitive)
565
- */
566
- private _hasHeader;
567
- /**
568
- * Sets cookies for the request.
569
- * Cookies are sent in the Cookie header. Multiple calls will merge cookies.
570
- * Cookie values can be simple strings or objects with additional cookie options.
571
- *
572
- * @param cookies - An object where keys are cookie names and values are either:
573
- * - A string (the cookie value)
574
- * - A CookieOptions object with `value` and optional properties (secure, httpOnly, sameSite, expires, path, domain, maxAge)
575
- * @returns The request instance for chaining
576
- *
577
- * @example
578
- * ```typescript
579
- * // Simple string cookies
580
- * request.withCookies({ sessionId: 'abc123', userId: '456' });
581
- * ```
582
- *
583
- * @example
584
- * ```typescript
585
- * // Cookies with options (note: options are for documentation only in request cookies)
586
- * request.withCookies({
587
- * sessionId: 'abc123',
588
- * token: { value: 'xyz789', secure: true }
589
- * });
590
- * ```
591
- */
592
- withCookies(cookies: CookiesRecord): this;
593
- /**
594
- * Sets a single cookie for the request.
595
- * Convenience method for adding one cookie at a time.
596
- *
597
- * @param name - The cookie name
598
- * @param value - The cookie value as a string, or a CookieOptions object with `value` and optional properties
599
- * @returns The request instance for chaining
600
- *
601
- * @example
602
- * ```typescript
603
- * request.withCookie('sessionId', 'abc123');
604
- * ```
605
- *
606
- * @example
607
- * ```typescript
608
- * request.withCookie('token', { value: 'xyz789', secure: true });
609
- * ```
610
- */
611
- withCookie(name: string, value: string | CookieOptions): this;
612
- /**
613
- * Sets a CSRF (Cross-Site Request Forgery) token in the request headers.
614
- * This is commonly used to protect against CSRF attacks in web applications.
615
- *
616
- * @param token - The CSRF token value
617
- * @param headerName - The name of the header to use. Defaults to `'X-CSRF-Token'`.
618
- * @returns The request instance for chaining
619
- *
620
- * @example
621
- * ```typescript
622
- * request.withCsrfToken('csrf-token-123');
623
- * // Sets: X-CSRF-Token: csrf-token-123
624
- * ```
625
- *
626
- * @example
627
- * ```typescript
628
- * request.withCsrfToken('token', 'X-Custom-CSRF-Header');
629
- * // Sets: X-Custom-CSRF-Header: token
630
- * ```
631
- */
632
- withCsrfToken(token: string, headerName?: string): this;
633
- /**
634
- * Disables automatic anti-CSRF protection.
635
- * By default, X-Requested-With: XMLHttpRequest header is sent with all requests.
636
- * @returns The instance for chaining
637
- */
638
- withoutCsrfProtection(): this;
639
- /**
640
- * Sets common security headers to help prevent CSRF attacks
641
- * @returns The instance for chaining
642
- */
643
- withAntiCsrfHeaders(): this;
644
- /**
645
- * Add a request interceptor for this specific request
646
- * Request interceptors can modify the request configuration or return an early response
647
- *
648
- * @param interceptor - The request interceptor function
649
- * @returns The instance for chaining
650
- *
651
- * @example
652
- * request.withRequestInterceptor((config) => {
653
- * config.headers['X-Custom'] = 'value';
654
- * return config;
655
- * });
656
- */
657
- withRequestInterceptor(interceptor: RequestInterceptor): this;
658
- /**
659
- * Add a response interceptor for this specific request
660
- * Response interceptors can transform the response
661
- *
662
- * @param interceptor - The response interceptor function
663
- * @returns The instance for chaining
664
- *
665
- * @example
666
- * request.withResponseInterceptor((response) => {
667
- * console.log('Status:', response.status);
668
- * return response;
669
- * });
670
- */
671
- withResponseInterceptor(interceptor: ResponseInterceptor): this;
672
- /**
673
- * Add an error interceptor for this specific request
674
- * Error interceptors can handle or transform errors
675
- *
676
- * @param interceptor - The error interceptor function
677
- * @returns The instance for chaining
678
- *
679
- * @example
680
- * request.withErrorInterceptor((error) => {
681
- * console.error('Request failed:', error);
682
- * throw error;
683
- * });
684
- */
685
- withErrorInterceptor(interceptor: ErrorInterceptor): this;
686
- /**
687
- * Execute the request and return the ResponseWrapper
688
- * This is the base method for getting the full response.
689
- *
690
- * @returns A promise that resolves to the ResponseWrapper
691
- *
692
- * @example
693
- * const response = await request.getResponse();
694
- * console.log(response.status);
695
- */
696
- getResponse(): Promise<ResponseWrapper>;
697
- /**
698
- * Execute the request and parse the response as JSON
699
- *
700
- * Returns `null` for empty responses (204 No Content, content-length: 0, or empty body).
701
- *
702
- * @returns A promise that resolves to the parsed JSON data, or `null` for empty responses
703
- * @throws {RequestError} When the request fails, JSON parsing fails, GraphQL errors occur (if throwOnError enabled), or body is already consumed
704
- *
705
- * @example
706
- * const users = await request.getJson<User[]>();
707
- * if (users !== null) {
708
- * users.forEach(u => console.log(u.name));
709
- * }
710
- *
711
- * @example
712
- * // Error handling - errors are always RequestError
713
- * try {
714
- * const data = await request.getJson();
715
- * } catch (error) {
716
- * if (error instanceof RequestError) {
717
- * console.log(error.status, error.url, error.method);
718
- * }
719
- * }
720
- */
721
- getJson<T = unknown>(): Promise<T | null>;
722
- /**
723
- * Execute the request and get the response body as text.
724
- *
725
- * @returns A promise that resolves to the response body as a string
726
- * @throws {RequestError} When the request fails or reading the response fails
727
- *
728
- * @example
729
- * ```typescript
730
- * const text = await request.getText();
731
- * console.log(text); // "Hello, world!"
732
- * ```
733
- */
734
- getText(): Promise<string>;
735
- /**
736
- * Execute the request and get the response body as a Blob.
737
- * Useful for downloading files or handling binary data.
738
- *
739
- * @returns A promise that resolves to the response body as a Blob
740
- * @throws {RequestError} When the request fails or reading the response fails
741
- *
742
- * @example
743
- * ```typescript
744
- * const blob = await request.getBlob();
745
- * const url = URL.createObjectURL(blob);
746
- * // Use the blob URL (e.g., for downloading or displaying)
747
- * ```
748
- */
749
- getBlob(): Promise<Blob>;
750
- /**
751
- * Execute the request and get the response body as an ArrayBuffer.
752
- * Useful for processing binary data at a low level.
753
- *
754
- * @returns A promise that resolves to the response body as an ArrayBuffer
755
- * @throws {RequestError} When the request fails or reading the response fails
756
- *
757
- * @example
758
- * ```typescript
759
- * const buffer = await request.getArrayBuffer();
760
- * const uint8Array = new Uint8Array(buffer);
761
- * // Process the binary data
762
- * ```
763
- */
764
- getArrayBuffer(): Promise<ArrayBuffer>;
765
- /**
766
- * Execute the request and get the response body as a ReadableStream.
767
- * Note: Unlike other methods, streams cannot be cached. The body can only be consumed once.
768
- *
769
- * @returns A promise that resolves to the response body as a ReadableStream, or `null` if the body is not available
770
- * @throws {RequestError} When the request fails or the body has already been consumed
771
- *
772
- * @example
773
- * ```typescript
774
- * const stream = await request.getBody();
775
- * if (stream) {
776
- * const reader = stream.getReader();
777
- * // Process the stream chunk by chunk
778
- * }
779
- * ```
780
- */
781
- getBody(): Promise<ReadableStream<Uint8Array> | null>;
782
- /**
783
- * Execute the request and extract specific data using a selector function
784
- * If no selector is provided, returns the full JSON response.
785
- *
786
- * Returns `null` for empty responses (204 No Content, content-length: 0, or empty body).
787
- * If a selector is provided and data is `null`, the selector will receive `null`.
788
- *
789
- * @param selector - Optional function to extract and transform data (receives `null` for empty responses)
790
- * @returns A promise that resolves to the selected data, or `null` for empty responses
791
- * @throws {RequestError} When the request fails, JSON parsing fails, or the selector throws an error
792
- *
793
- * @example
794
- * // Get full response
795
- * const data = await request.getData();
796
- * if (data !== null) {
797
- * console.log(data.items);
798
- * }
799
- *
800
- * @example
801
- * // Extract specific data (use null-safe selector for empty responses)
802
- * const users = await request.getData(data => data?.results?.users);
803
- *
804
- * @example
805
- * // Error handling - errors are always RequestError
806
- * try {
807
- * const data = await request.getData();
808
- * } catch (error) {
809
- * if (error instanceof RequestError) {
810
- * console.log(error.status, error.url, error.method);
811
- * }
812
- * }
813
- */
814
- getData<T = unknown, R = T>(selector?: (data: T | null) => R): Promise<T | R | null>;
815
- /**
816
- * Apply CSRF protection headers based on configuration
817
- */
818
- private _applyCsrf;
819
- /**
820
- * Formats the URL with any query parameters
821
- * @param url The base URL
822
- * @returns The URL with query parameters appended
823
- */
824
- private _fullUrl;
825
- /**
826
- * Executes a request with configured retry logic
827
- * @param url The formatted URL to send the request to
828
- * @param fetchOptions The fetch options to use
829
- * @returns A wrapped response object
830
- * @throws RequestError if the request fails after all retries
831
- */
832
- private _retry;
833
- /**
834
- * Run request interceptors in order: global interceptors first, then per-request
835
- * @param configParam - The request configuration
836
- * @returns Modified config or a Response to short-circuit
837
- */
838
- private _runReqI;
839
- /**
840
- * Run response interceptors in reverse order: per-request interceptors first, then global in reverse
841
- * @param response - The response wrapper
842
- * @returns Modified response wrapper
843
- */
844
- private _runResI;
845
- /**
846
- * Run error interceptors in reverse order: per-request interceptors first, then global in reverse
847
- * @param error - The error that occurred
848
- * @returns Modified error or a ResponseWrapper to recover
849
- */
850
- private _runErrI;
851
- /**
852
- * Helper to create an abort signal with timeout support
853
- * Handles various AbortSignal API levels gracefully
854
- */
855
- private _signal;
856
- /**
857
- * Manually combine two abort signals for older environments
858
- * Returns the first signal and listens to the second
859
- */
860
- private _combine;
861
- /**
862
- * Convert fetchOptions to RequestConfig with proper typing
863
- */
864
- private _config;
865
- /**
866
- * Apply interceptor results back to fetchOptions
867
- */
868
- private _applyConfig;
869
- private _run;
870
- }