create-request 1.4.3-rc.2 → 1.4.3-rc.4

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 CHANGED
@@ -14,6 +14,7 @@
14
14
 
15
15
  - [Core Features](#core-features)
16
16
  - [Why create-request](#why-create-request)
17
+ - [Mental Model](#mental-model)
17
18
  - [Installation](#installation)
18
19
  - [Basic Usage](#basic-usage)
19
20
  - [URL Handling](#url-handling)
@@ -43,6 +44,7 @@
43
44
  - 🔁 **Automatic Retries** - Retry failed requests with customizable settings
44
45
  - 📉 **Reduced Boilerplate** - Write 60% less code for common API operations
45
46
  - 🔒 **CSRF Protection** - Built-in safeguards against cross-site request forgery
47
+ - 🏗️ **API Builder** - Create configured API instances with reusable default settings
46
48
  - 🛑 **Request Cancellation** - Abort requests on demand with AbortController integration
47
49
  - 🔌 **Interceptors** - Global and per-request interceptors for requests, responses, and errors
48
50
  - 🔷 **GraphQL Support** - Built-in GraphQL query and mutation helpers
@@ -95,6 +97,127 @@ function createUser(userData) {
95
97
  }
96
98
  ```
97
99
 
100
+ ## Mental Model
101
+
102
+ ### 1. **Separation of Building and Execution**
103
+
104
+ Requests are built first, then executed. This separation allows you to:
105
+
106
+ - Configure requests incrementally
107
+ - Reuse request configurations
108
+ - Pass requests around before executing them
109
+ - Chain configuration methods fluently
110
+
111
+ ```typescript
112
+ // Building phase: configure the request
113
+ const request = create
114
+ .get("https://api.example.com/users")
115
+ .withBearerToken(token)
116
+ .withTimeout(5000);
117
+
118
+ // Execution phase: actually make the HTTP call
119
+ const data = await request.getJson();
120
+ ```
121
+
122
+ ### 2. **Fluent Chainable Interface**
123
+
124
+ Every configuration method returns the request instance, enabling method chaining. This creates a readable, declarative API that reads like a sentence:
125
+
126
+ ```typescript
127
+ // Reads like: "Create a POST request to users endpoint, with auth, body, and timeout, then get JSON"
128
+ const user = await create
129
+ .post("https://api.example.com/users")
130
+ .withBearerToken(token)
131
+ .withBody(userData)
132
+ .withTimeout(3000)
133
+ .getJson();
134
+ ```
135
+
136
+ ### 3. **Configuration Layers**
137
+
138
+ Configuration follows a layered approach, with more specific settings overriding general ones:
139
+
140
+ 1. **Global Configuration** (via `create.config`) - Applies to all requests
141
+ 2. **API Builder Defaults** (via `create.api()`) - Applies to requests from that API instance
142
+ 3. **Per-Request Configuration** - Specific to individual requests
143
+
144
+ ```typescript
145
+ // Global: all requests get this
146
+ create.config.setCsrfToken("global-token");
147
+
148
+ // API instance: requests from this API get these defaults
149
+ const api = create
150
+ .api()
151
+ .withBaseURL("https://api.example.com")
152
+ .withBearerToken("default-token");
153
+
154
+ // Per-request: this specific request overrides the default token
155
+ const user = await api
156
+ .get("/users")
157
+ .withBearerToken("specific-token") // Overrides default-token
158
+ .getJson();
159
+ ```
160
+
161
+ ### 4. **Request Definition with `with...` Functions**
162
+
163
+ All request configuration is done through methods that start with `with...`. This consistent naming convention makes it immediately clear which methods are used for configuration:
164
+
165
+ ```typescript
166
+ // All configuration uses 'with...' prefix
167
+ const request = create
168
+ .get("https://api.example.com/users")
169
+ .withHeaders({ "X-API-Key": "abc123" })
170
+ .withBearerToken("token")
171
+ .withTimeout(5000)
172
+ .withRetries(3)
173
+ .withQueryParams({ page: 1 })
174
+ .withCookie("session", "abc123");
175
+ ```
176
+
177
+ This pattern makes the API self-documenting - any method starting with `with...` is a configuration method that returns the request instance for chaining.
178
+
179
+ ### 5. **Request Lifecycle**
180
+
181
+ The typical request lifecycle follows this pattern:
182
+
183
+ ```
184
+ Build → Configure → Execute → Transform → Handle
185
+ ```
186
+
187
+ 1. **Build**: Create a request with a method and URL (`create.get(url)`)
188
+ 2. **Configure**: Chain configuration methods using `with...` functions (`.withHeaders()`, `.withTimeout()`, etc.)
189
+ 3. **Execute**: Call an execution method (`.getJson()`, `.getData()`, etc.)
190
+ 4. **Transform**: Optionally transform the response (via `.getData()` selector or interceptors)
191
+ 5. **Handle**: Process the result or catch errors
192
+
193
+ ### 6. **Promise-Based Execution**
194
+
195
+ All execution methods return Promises, making the library compatible with:
196
+
197
+ - `async/await` syntax (recommended)
198
+ - `.then()/.catch()` chains
199
+ - Promise utilities like `Promise.all()`, `Promise.race()`, etc.
200
+
201
+ ```typescript
202
+ // All of these work:
203
+ const data1 = await request.getJson();
204
+
205
+ request.getJson().then(data => console.log(data));
206
+
207
+ const results = await Promise.all([
208
+ create.get("/users").getJson(),
209
+ create.get("/posts").getJson(),
210
+ ]);
211
+ ```
212
+
213
+ ### 7. **Comprehensive JSDoc Documentation**
214
+
215
+ The library includes extensive JSDoc documentation throughout the codebase. This documentation is valuable for developers of all levels:
216
+
217
+ - **For Junior Developers**: JSDoc provides clear explanations of what each method does, parameter types, return values, and usage examples directly in your IDE. This helps with learning and understanding the API without constantly referring to external documentation.
218
+
219
+ - **For Senior Developers**: JSDoc offers detailed type information, edge cases, and implementation details that enable deeper understanding and more advanced usage patterns. The type definitions help with TypeScript inference and ensure type safety.
220
+
98
221
  ## Installation
99
222
 
100
223
  ```bash
@@ -989,26 +1112,27 @@ This library works with all browsers that support the Fetch API:
989
1112
 
990
1113
  ## Comparison of JavaScript HTTP Client Libraries
991
1114
 
992
- | Feature | create-request | Fetch | Axios | SuperAgent | Got | Ky | node-fetch | Redaxios |
993
- | ------------------- | -------------- | ------ | ------- | ---------- | ------- | ------ | ---------- | -------- |
994
- | **Size (min+gzip)** | ~5.8KB | Native | ~13.6KB | ~17.8KB | ~17.8KB | ~3.4KB | ~7.7KB | ~1KB |
995
- | **Browser** | Modern | Modern | IE11+ | IE9+ | ❌ No | Modern | ❌ No | Modern |
996
- | **Node.js** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
997
- | **HTTP/2** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
998
- | **Auto Retries** | ✅ | ❌ | 🛠️ | ✅ | ✅ | ✅ | ❌ | ❌ |
999
- | **Cancellation** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1000
- | **Auto JSON** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
1001
- | **Timeout** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1002
- | **TypeScript** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1003
- | **Streaming** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
1004
- | **Progress** | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
1005
- | **Cookies** | ✅ | ✅ | 🛠️ | ✅ | ✅ | ❌ | ❌ | ❌ |
1006
- | **Pagination API** | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
1007
- | **Zero Deps** | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
1008
- | **Chainable API** | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
1009
- | **CSRF Protection** | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
1010
- | **GraphQL Support** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
1011
- | **Interceptors** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
1115
+ | Feature | create-request | Fetch | Axios | SuperAgent | Got | Ky | node-fetch | Redaxios |
1116
+ | --------------------- | -------------- | ------ | ------- | ---------- | ------- | ------ | ---------- | -------- |
1117
+ | **Size (min+gzip)** | ~6.3KB | Native | ~13.6KB | ~17.8KB | ~17.8KB | ~3.4KB | ~7.7KB | ~1KB |
1118
+ | **Browser** | Modern | Modern | IE11+ | IE9+ | ❌ No | Modern | ❌ No | Modern |
1119
+ | **Node.js** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1120
+ | **HTTP/2** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
1121
+ | **Auto Retries** | ✅ | ❌ | 🛠️ | ✅ | ✅ | ✅ | ❌ | ❌ |
1122
+ | **Cancellation** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1123
+ | **Auto JSON** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
1124
+ | **Timeout** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1125
+ | **TypeScript** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1126
+ | **Streaming** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
1127
+ | **Progress** | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
1128
+ | **Cookies** | ✅ | ✅ | 🛠️ | ✅ | ✅ | ❌ | ❌ | ❌ |
1129
+ | **Pagination API** | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
1130
+ | **Zero Deps** | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
1131
+ | **Chainable API** | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
1132
+ | **CSRF Protection** | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
1133
+ | **GraphQL Support** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
1134
+ | **Interceptors** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
1135
+ | **Instance Creation** | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
1012
1136
 
1013
1137
  **Notes:**
1014
1138
 
@@ -1018,3 +1142,9 @@ This library works with all browsers that support the Fetch API:
1018
1142
  ## License
1019
1143
 
1020
1144
  MIT
1145
+
1146
+ ---
1147
+
1148
+ ## Website
1149
+
1150
+ Visit [create-request.com](https://create-request.com) for documentation, examples, and more resources.
@@ -365,16 +365,56 @@ export declare abstract class BaseRequest {
365
365
  ONLY_IF_CACHED: () => BaseRequest;
366
366
  };
367
367
  /**
368
- * Adds query parameters to the request URL
369
- * @param params - An object containing the query parameters
370
- * @returns The instance for chaining
368
+ * Adds query parameters to the request URL.
369
+ * Multiple calls will append parameters. Array values will create multiple query parameters with the same key.
370
+ * Null and undefined values are ignored.
371
+ *
372
+ * @param params - An object containing query parameter key-value pairs.
373
+ * Values can be strings, numbers, booleans, arrays (for multiple values), or null/undefined (ignored).
374
+ * @returns The request instance for chaining
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * // Simple parameters
379
+ * request.withQueryParams({ page: 1, limit: 10, active: true });
380
+ * // Results in: ?page=1&limit=10&active=true
381
+ * ```
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * // Array values create multiple parameters
386
+ * request.withQueryParams({ tags: ['js', 'ts', 'node'] });
387
+ * // Results in: ?tags=js&tags=ts&tags=node
388
+ * ```
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * // Null/undefined values are ignored
393
+ * request.withQueryParams({ page: 1, filter: null, sort: undefined });
394
+ * // Results in: ?page=1
395
+ * ```
371
396
  */
372
397
  withQueryParams(params: Record<string, string | string[] | number | boolean | null | undefined>): this;
373
398
  /**
374
- * Adds a single query parameter
375
- * @param key - The parameter name
376
- * @param value - The parameter value, can be a single value or array of values
377
- * @returns The instance for chaining
399
+ * Adds a single query parameter to the request URL.
400
+ * Convenience method for adding one parameter at a time.
401
+ *
402
+ * @param key - The query parameter name
403
+ * @param value - The query parameter value. Can be a string, number, boolean, array (for multiple values), or null/undefined (ignored).
404
+ * @returns The request instance for chaining
405
+ *
406
+ * @example
407
+ * ```typescript
408
+ * request.withQueryParam('page', 1).withQueryParam('limit', 10);
409
+ * // Results in: ?page=1&limit=10
410
+ * ```
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * // Array values create multiple parameters
415
+ * request.withQueryParam('tags', ['js', 'ts']);
416
+ * // Results in: ?tags=js&tags=ts
417
+ * ```
378
418
  */
379
419
  withQueryParam(key: string, value: string | string[] | number | boolean | null | undefined): this;
380
420
  /**
@@ -412,22 +452,55 @@ export declare abstract class BaseRequest {
412
452
  NAVIGATE: () => BaseRequest;
413
453
  };
414
454
  /**
415
- * Shorthand for setting the Content-Type header
416
- * @param contentType - The content type
417
- * @returns The instance for chaining
455
+ * Sets the Content-Type header for the request.
456
+ * Shorthand for `withHeader('Content-Type', contentType)`.
457
+ *
458
+ * @param contentType - The MIME type (e.g., `'application/json'`, `'text/plain'`, `'multipart/form-data'`)
459
+ * @returns The request instance for chaining
460
+ *
461
+ * @example
462
+ * ```typescript
463
+ * request.withContentType('application/json');
464
+ * ```
465
+ *
466
+ * @example
467
+ * ```typescript
468
+ * request.withContentType('application/xml');
469
+ * ```
418
470
  */
419
471
  withContentType(contentType: string): this;
420
472
  /**
421
- * Shorthand for setting the Authorization header
422
- * @param authValue - The authorization value
423
- * @returns The instance for chaining
473
+ * Sets the Authorization header for the request.
474
+ * Shorthand for `withHeader('Authorization', authValue)`.
475
+ * For Bearer tokens, use `withBearerToken()` instead. For Basic auth, use `withBasicAuth()`.
476
+ *
477
+ * @param authValue - The full authorization header value (e.g., `'Bearer token123'`, `'Basic base64string'`)
478
+ * @returns The request instance for chaining
479
+ *
480
+ * @example
481
+ * ```typescript
482
+ * request.withAuthorization('Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');
483
+ * ```
484
+ *
485
+ * @example
486
+ * ```typescript
487
+ * request.withAuthorization('CustomScheme customToken');
488
+ * ```
424
489
  */
425
490
  withAuthorization(authValue: string): this;
426
491
  /**
427
- * Shorthand for setting up Basic authentication
428
- * @param username - The username
429
- * @param password - The password
430
- * @returns The instance for chaining
492
+ * Sets up HTTP Basic Authentication.
493
+ * Encodes the username and password in base64 and sets the Authorization header.
494
+ *
495
+ * @param username - The username for Basic authentication
496
+ * @param password - The password for Basic authentication
497
+ * @returns The request instance for chaining
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * request.withBasicAuth('myuser', 'mypassword');
502
+ * // Sets: Authorization: Basic bXl1c2VyOm15cGFzc3dvcmQ=
503
+ * ```
431
504
  */
432
505
  withBasicAuth(username: string, password: string): this;
433
506
  /**
@@ -436,9 +509,17 @@ export declare abstract class BaseRequest {
436
509
  */
437
510
  private encodeBase64;
438
511
  /**
439
- * Sets the bearer token for authentication
440
- * @param token - The bearer token
441
- * @returns The instance for chaining
512
+ * Sets a Bearer token for authentication.
513
+ * Shorthand for `withAuthorization('Bearer ' + token)`.
514
+ *
515
+ * @param token - The Bearer token (JWT, OAuth token, etc.)
516
+ * @returns The request instance for chaining
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * request.withBearerToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');
521
+ * // Sets: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
522
+ * ```
442
523
  */
443
524
  withBearerToken(token: string): this;
444
525
  /**
@@ -453,23 +534,69 @@ export declare abstract class BaseRequest {
453
534
  */
454
535
  private hasHeader;
455
536
  /**
456
- * Sets cookies for the request
457
- * @param cookies Object containing cookie name-value pairs or cookie options
458
- * @returns The instance for chaining
537
+ * Sets cookies for the request.
538
+ * Cookies are sent in the Cookie header. Multiple calls will merge cookies.
539
+ * Cookie values can be simple strings or objects with additional cookie options.
540
+ *
541
+ * @param cookies - An object where keys are cookie names and values are either:
542
+ * - A string (the cookie value)
543
+ * - A CookieOptions object with `value` and optional properties (secure, httpOnly, sameSite, expires, path, domain, maxAge)
544
+ * @returns The request instance for chaining
545
+ *
546
+ * @example
547
+ * ```typescript
548
+ * // Simple string cookies
549
+ * request.withCookies({ sessionId: 'abc123', userId: '456' });
550
+ * ```
551
+ *
552
+ * @example
553
+ * ```typescript
554
+ * // Cookies with options (note: options are for documentation only in request cookies)
555
+ * request.withCookies({
556
+ * sessionId: 'abc123',
557
+ * token: { value: 'xyz789', secure: true }
558
+ * });
559
+ * ```
459
560
  */
460
561
  withCookies(cookies: CookiesRecord): this;
461
562
  /**
462
- * Set a single cookie
463
- * @param name Cookie name
464
- * @param value Cookie value or options object
465
- * @returns The instance for chaining
563
+ * Sets a single cookie for the request.
564
+ * Convenience method for adding one cookie at a time.
565
+ *
566
+ * @param name - The cookie name
567
+ * @param value - The cookie value as a string, or a CookieOptions object with `value` and optional properties
568
+ * @returns The request instance for chaining
569
+ *
570
+ * @example
571
+ * ```typescript
572
+ * request.withCookie('sessionId', 'abc123');
573
+ * ```
574
+ *
575
+ * @example
576
+ * ```typescript
577
+ * request.withCookie('token', { value: 'xyz789', secure: true });
578
+ * ```
466
579
  */
467
580
  withCookie(name: string, value: string | CookieOptions): this;
468
581
  /**
469
- * Sets a CSRF token in the request headers
470
- * @param token The CSRF token
471
- * @param headerName The name of the header to use (default: X-CSRF-Token)
472
- * @returns The instance for chaining
582
+ * Sets a CSRF (Cross-Site Request Forgery) token in the request headers.
583
+ * This is commonly used to protect against CSRF attacks in web applications.
584
+ *
585
+ * @param token - The CSRF token value
586
+ * @param headerName - The name of the header to use. Defaults to `'X-CSRF-Token'`.
587
+ * @returns The request instance for chaining
588
+ *
589
+ * @example
590
+ * ```typescript
591
+ * request.withCsrfToken('csrf-token-123');
592
+ * // Sets: X-CSRF-Token: csrf-token-123
593
+ * ```
594
+ *
595
+ * @example
596
+ * ```typescript
597
+ * request.withCsrfToken('token', 'X-Custom-CSRF-Header');
598
+ * // Sets: X-Custom-CSRF-Header: token
599
+ * ```
473
600
  */
474
601
  withCsrfToken(token: string, headerName?: string): this;
475
602
  /**
@@ -557,30 +684,48 @@ export declare abstract class BaseRequest {
557
684
  */
558
685
  getJson<T = unknown>(): Promise<T>;
559
686
  /**
560
- * Execute the request and get the response as text
687
+ * Execute the request and get the response body as text.
561
688
  *
562
- * @returns A promise that resolves to the response text
689
+ * @returns A promise that resolves to the response body as a string
690
+ * @throws {RequestError} When the request fails or reading the response fails
563
691
  *
564
692
  * @example
693
+ * ```typescript
565
694
  * const text = await request.getText();
695
+ * console.log(text); // "Hello, world!"
696
+ * ```
566
697
  */
567
698
  getText(): Promise<string>;
568
699
  /**
569
- * Execute the request and get the response as a Blob
700
+ * Execute the request and get the response body as a Blob.
701
+ * Useful for downloading files or handling binary data.
570
702
  *
571
- * @returns A promise that resolves to the response Blob
703
+ * @returns A promise that resolves to the response body as a Blob
704
+ * @throws {RequestError} When the request fails or reading the response fails
572
705
  *
573
706
  * @example
707
+ * ```typescript
574
708
  * const blob = await request.getBlob();
709
+ * const url = URL.createObjectURL(blob);
710
+ * // Use the blob URL (e.g., for downloading or displaying)
711
+ * ```
575
712
  */
576
713
  getBlob(): Promise<Blob>;
577
714
  /**
578
- * Execute the request and get the response body as a ReadableStream
715
+ * Execute the request and get the response body as a ReadableStream.
716
+ * Note: Unlike other methods, streams cannot be cached. The body can only be consumed once.
579
717
  *
580
- * @returns A promise that resolves to the response body stream
718
+ * @returns A promise that resolves to the response body as a ReadableStream, or `null` if the body is not available
719
+ * @throws {RequestError} When the request fails or the body has already been consumed
581
720
  *
582
721
  * @example
722
+ * ```typescript
583
723
  * const stream = await request.getBody();
724
+ * if (stream) {
725
+ * const reader = stream.getReader();
726
+ * // Process the stream chunk by chunk
727
+ * }
728
+ * ```
584
729
  */
585
730
  getBody(): Promise<ReadableStream<Uint8Array> | null>;
586
731
  /**
@@ -10,31 +10,77 @@ export declare abstract class BodyRequest extends BaseRequest {
10
10
  private graphQLOptions;
11
11
  constructor(url: string);
12
12
  /**
13
- * Sets the body of the request
14
- * @param body - The request body
13
+ * Sets the request body. Automatically detects the body type and sets appropriate Content-Type header.
14
+ * Supports JSON objects/arrays, strings, FormData, Blob, ArrayBuffer, URLSearchParams, and ReadableStream.
15
+ *
16
+ * @param body - The request body. Can be:
17
+ * - A JSON-serializable object or array (automatically stringified)
18
+ * - A string (sets Content-Type to `text/plain` if not already set)
19
+ * - FormData, Blob, File, ArrayBuffer, TypedArray, URLSearchParams, or ReadableStream
20
+ * @returns The request instance for chaining
21
+ * @throws {RequestError} If the body is a JSON object that cannot be stringified
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // JSON object (automatically stringified)
26
+ * request.withBody({ name: 'John', age: 30 });
27
+ *
28
+ * @example
29
+ * // JSON array
30
+ * request.withBody([1, 2, 3]);
31
+ *
32
+ * @example
33
+ * // String
34
+ * request.withBody('plain text');
35
+ *
36
+ * @example
37
+ * // FormData
38
+ * const formData = new FormData();
39
+ * formData.append('file', fileBlob);
40
+ * request.withBody(formData);
41
+ *
42
+ * @example
43
+ * // Blob
44
+ * request.withBody(new Blob(['content'], { type: 'text/plain' }));
45
+ * ```
15
46
  */
16
47
  withBody(body: Body): this;
17
48
  /**
18
- * Sets a GraphQL query or mutation as the request body
19
- * Automatically formats the body as JSON and sets Content-Type to application/json
49
+ * Sets a GraphQL query or mutation as the request body.
50
+ * Automatically formats the body as JSON and sets Content-Type to `application/json`.
51
+ * If `throwOnError` is enabled in options, the response will be checked for GraphQL errors
52
+ * and a RequestError will be thrown if any are found.
20
53
  *
21
- * @param query - The GraphQL query or mutation string
22
- * @param variables - Optional variables object to pass with the query
54
+ * @param query - The GraphQL query or mutation string (e.g., `'query { user { id } }'`)
55
+ * @param variables - Optional variables object to pass with the query. Must be a plain object.
23
56
  * @param options - Optional GraphQL-specific options
57
+ * @param options.throwOnError - If `true`, throws a RequestError when the GraphQL response contains errors
24
58
  * @returns The request instance for chaining
59
+ * @throws {RequestError} If the query is empty, variables is invalid, or JSON stringification fails
25
60
  *
26
61
  * @example
27
- * const request = new PostRequest('/graphql')
62
+ * ```typescript
63
+ * // Simple query with variables
64
+ * const request = create.post('/graphql')
28
65
  * .withGraphQL('query { user(id: $id) { name email } }', { id: '123' });
66
+ * const data = await request.getJson();
67
+ * ```
29
68
  *
30
69
  * @example
31
- * const request = new PostRequest('/graphql')
70
+ * ```typescript
71
+ * // Mutation with variables
72
+ * const request = create.post('/graphql')
32
73
  * .withGraphQL('mutation { createUser(name: $name) { id } }', { name: 'John' });
74
+ * ```
33
75
  *
34
76
  * @example
35
- * // Throw an error if the GraphQL response contains errors
36
- * const request = new PostRequest('/graphql')
77
+ * ```typescript
78
+ * // Throw error if GraphQL response contains errors
79
+ * const request = create.post('/graphql')
37
80
  * .withGraphQL('query { user { id } }', undefined, { throwOnError: true });
81
+ * // If the response has errors, this will throw a RequestError
82
+ * const data = await request.getJson();
83
+ * ```
38
84
  */
39
85
  withGraphQL(query: string, variables?: Record<string, unknown>, options?: GraphQLOptions): this;
40
86
  /**