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,100 +0,0 @@
1
- import { BaseRequest } from "./BaseRequest.js";
2
- import type { Body, GraphQLOptions } from "./types.js";
3
- import type { ResponseWrapper } from "./ResponseWrapper.js";
4
- /**
5
- * Base class for requests that can have a body (POST, PUT, PATCH)
6
- */
7
- export declare abstract class BodyRequest extends BaseRequest {
8
- protected _body?: Body;
9
- private _bodyType?;
10
- private _gqlOpts;
11
- /**
12
- * Sets the request body. Automatically detects the body type and sets appropriate Content-Type header.
13
- * Supports JSON objects/arrays, strings, FormData, Blob, ArrayBuffer, URLSearchParams, and ReadableStream.
14
- *
15
- * @param body - The request body. Can be:
16
- * - A JSON-serializable object or array (automatically stringified)
17
- * - A string (sets Content-Type to `text/plain` if not already set)
18
- * - FormData, Blob, File, ArrayBuffer, TypedArray, URLSearchParams, or ReadableStream
19
- * @returns The request instance for chaining
20
- * @throws {RequestError} If the body is a JSON object that cannot be stringified
21
- *
22
- * @example
23
- * ```typescript
24
- * // JSON object (automatically stringified)
25
- * request.withBody({ name: 'John', age: 30 });
26
- *
27
- * @example
28
- * // JSON array
29
- * request.withBody([1, 2, 3]);
30
- *
31
- * @example
32
- * // String
33
- * request.withBody('plain text');
34
- *
35
- * @example
36
- * // FormData
37
- * const formData = new FormData();
38
- * formData.append('file', fileBlob);
39
- * request.withBody(formData);
40
- *
41
- * @example
42
- * // Blob
43
- * request.withBody(new Blob(['content'], { type: 'text/plain' }));
44
- * ```
45
- */
46
- withBody(body: Body): this;
47
- /**
48
- * Sets a GraphQL query or mutation as the request body.
49
- * Automatically formats the body as JSON and sets Content-Type to `application/json`.
50
- * If `throwOnError` is enabled in options, the response will be checked for GraphQL errors
51
- * and a RequestError will be thrown if any are found.
52
- *
53
- * @param query - The GraphQL query or mutation string (e.g., `'query { user { id } }'`)
54
- * @param variables - Optional variables object to pass with the query. Must be a plain object.
55
- * @param options - Optional GraphQL-specific options
56
- * @param options.throwOnError - If `true`, throws a RequestError when the GraphQL response contains errors
57
- * @returns The request instance for chaining
58
- * @throws {RequestError} If the query is empty, variables is invalid, or JSON stringification fails
59
- *
60
- * @example
61
- * ```typescript
62
- * // Simple query with variables
63
- * const request = create.post('/graphql')
64
- * .withGraphQL('query { user(id: $id) { name email } }', { id: '123' });
65
- * const data = await request.getJson();
66
- * ```
67
- *
68
- * @example
69
- * ```typescript
70
- * // Mutation with variables
71
- * const request = create.post('/graphql')
72
- * .withGraphQL('mutation { createUser(name: $name) { id } }', { name: 'John' });
73
- * ```
74
- *
75
- * @example
76
- * ```typescript
77
- * // Throw error if GraphQL response contains errors
78
- * const request = create.post('/graphql')
79
- * .withGraphQL('query { user { id } }', undefined, { throwOnError: true });
80
- * // If the response has errors, this will throw a RequestError
81
- * const data = await request.getJson();
82
- * ```
83
- */
84
- withGraphQL(query: string, variables?: Record<string, unknown>, options?: GraphQLOptions): this;
85
- /**
86
- * Check if Content-Type header is already set (case-insensitive)
87
- */
88
- private _hasCT;
89
- private _setCT;
90
- /**
91
- * Get the GraphQL options if set
92
- * @returns The GraphQL options or undefined
93
- */
94
- protected _gql(): GraphQLOptions | undefined;
95
- /**
96
- * Execute the request and return the ResponseWrapper
97
- * Overrides the base implementation to add body handling
98
- */
99
- getResponse(): Promise<ResponseWrapper>;
100
- }
@@ -1,181 +0,0 @@
1
- /**
2
- * Extract a message from an unknown thrown value
3
- * @internal
4
- */
5
- export declare const errorMessage: (e: unknown) => string;
6
- /**
7
- * Coerce an unknown thrown value to an Error
8
- * @internal
9
- */
10
- export declare const toError: (e: unknown) => Error;
11
- /**
12
- * Error class for HTTP request failures.
13
- * Extends the standard Error class with additional context about the failed request.
14
- *
15
- * @example
16
- * ```typescript
17
- * try {
18
- * await create.get('/api/users').getJson();
19
- * } catch (error) {
20
- * console.log(`Request failed: ${error.message}`);
21
- * console.log(`URL: ${error.url}`);
22
- * console.log(`Method: ${error.method}`);
23
- * console.log(`Status: ${error.status}`);
24
- * console.log(`Body: ${error.body}`); // Raw response body (if available)
25
- * console.log(error.getJson()); // Body parsed as JSON (or undefined)
26
- * console.log(`Is timeout: ${error.isTimeout}`);
27
- * console.log(`Is aborted: ${error.isAborted}`);
28
- * }
29
- * ```
30
- */
31
- export declare class RequestError extends Error {
32
- /** HTTP status code if the request received a response (e.g., 404, 500) */
33
- readonly status?: number;
34
- /** The Response object if the request received a response before failing */
35
- readonly response?: Response;
36
- /**
37
- * The raw response body as text, if a response was received and its body could be read.
38
- * `undefined` for errors without a response (network errors, timeouts, aborts)
39
- * or when the body could not be read.
40
- */
41
- readonly body?: string;
42
- /** The URL that was requested */
43
- readonly url: string;
44
- /** The HTTP method that was used (e.g., 'GET', 'POST') */
45
- readonly method: string;
46
- /** Whether the request failed due to a timeout */
47
- readonly isTimeout: boolean;
48
- /** Whether the request was aborted (cancelled) */
49
- readonly isAborted: boolean;
50
- /** Cached result of parsing `body` as JSON (lazily populated by getJson) */
51
- private _parsed?;
52
- /**
53
- * Creates a new RequestError instance.
54
- *
55
- * @param message - Error message describing what went wrong
56
- * @param url - The URL that was requested
57
- * @param method - The HTTP method that was used
58
- * @param options - Additional error context
59
- * @param options.status - HTTP status code if available
60
- * @param options.response - The Response object if available
61
- * @param options.body - The raw response body as text, if available
62
- * @param options.isTimeout - Whether this was a timeout error
63
- * @param options.isAborted - Whether the request was aborted
64
- * @param options.cause - The underlying error that caused this error
65
- */
66
- constructor(message: string, url: string, method: string, options?: {
67
- status?: number;
68
- response?: Response;
69
- body?: string;
70
- isTimeout?: boolean;
71
- isAborted?: boolean;
72
- cause?: Error;
73
- });
74
- /**
75
- * Parses the captured response body (`body`) as JSON.
76
- * The result is cached, so repeated calls don't re-parse.
77
- * This method never throws - it returns `undefined` when there is no body
78
- * or the body is not valid JSON, making it safe to use in error handlers.
79
- *
80
- * @returns The parsed JSON body, or `undefined` if no body was captured or it isn't valid JSON
81
- *
82
- * @example
83
- * ```typescript
84
- * try {
85
- * await create.post('/api/users').withBody(user).getJson();
86
- * } catch (error) {
87
- * if (error instanceof RequestError) {
88
- * const details = error.getJson<{ message: string; code: string }>();
89
- * console.log(details?.message ?? error.body ?? error.message);
90
- * }
91
- * }
92
- * ```
93
- */
94
- getJson<T = unknown>(): T | undefined;
95
- /**
96
- * Safely reads the body of a Response as text without consuming it.
97
- * The response is cloned before reading, so the original body remains readable.
98
- * Never throws - returns `undefined` if the body is unavailable or cannot be read
99
- * (e.g., already consumed, locked stream, or read failure).
100
- *
101
- * @param response - The Response to read the body from
102
- * @returns The body as text, or `undefined` if it could not be read
103
- *
104
- * @example
105
- * ```typescript
106
- * const body = await RequestError.captureBody(response);
107
- * throw RequestError.fromResponse(response, url, 'GET', body);
108
- * ```
109
- */
110
- static captureBody(response: Response): Promise<string | undefined>;
111
- /**
112
- * Creates a RequestError for a timeout failure.
113
- *
114
- * @param url - The URL that timed out
115
- * @param method - The HTTP method that was used
116
- * @param timeoutMs - The timeout duration in milliseconds
117
- * @returns A RequestError with `isTimeout` set to `true`
118
- *
119
- * @example
120
- * ```typescript
121
- * throw RequestError.timeout('/api/data', 'GET', 5000);
122
- * ```
123
- */
124
- static timeout(url: string, method: string, timeoutMs: number): RequestError;
125
- /**
126
- * Creates a RequestError from an HTTP error response.
127
- * Used when the server returns a non-2xx status code.
128
- *
129
- * @param response - The Response object from the failed request
130
- * @param url - The URL that was requested
131
- * @param method - The HTTP method that was used
132
- * @param body - The response body as text, if already read (see {@link RequestError.captureBody})
133
- * @returns A RequestError with the status code, response object, and body (if provided)
134
- *
135
- * @example
136
- * ```typescript
137
- * const response = await fetch('/api/users');
138
- * if (!response.ok) {
139
- * const body = await RequestError.captureBody(response);
140
- * throw RequestError.fromResponse(response, '/api/users', 'GET', body);
141
- * }
142
- * ```
143
- */
144
- static fromResponse(response: Response, url: string, method: string, body?: string): RequestError;
145
- /**
146
- * Creates a RequestError from a network-level error.
147
- * Automatically detects and categorizes common network errors (timeouts, DNS errors, connection errors).
148
- *
149
- * @param url - The URL that failed
150
- * @param method - The HTTP method that was used
151
- * @param originalError - The original error that occurred (e.g., from fetch)
152
- * @returns A RequestError with enhanced error message and context
153
- *
154
- * @example
155
- * ```typescript
156
- * try {
157
- * await fetch('/api/data');
158
- * } catch (error) {
159
- * if (error instanceof Error) {
160
- * throw RequestError.networkError('/api/data', 'GET', error);
161
- * }
162
- * }
163
- * ```
164
- */
165
- static networkError(url: string, method: string, originalError: Error): RequestError;
166
- /**
167
- * Creates a RequestError for an aborted (cancelled) request.
168
- *
169
- * @param url - The URL that was aborted
170
- * @param method - The HTTP method that was used
171
- * @returns A RequestError with `isAborted` set to `true`
172
- *
173
- * @example
174
- * ```typescript
175
- * const controller = new AbortController();
176
- * controller.abort();
177
- * throw RequestError.abortError('/api/data', 'GET');
178
- * ```
179
- */
180
- static abortError(url: string, method: string): RequestError;
181
- }
@@ -1,193 +0,0 @@
1
- import type { GraphQLOptions } from "./types.js";
2
- /**
3
- * Wrapper for HTTP responses with methods to transform the response data.
4
- * Provides convenient methods to parse the response body in different formats.
5
- * Response bodies are cached after the first read, so you can call multiple methods
6
- * (e.g., `getJson()` and `getText()`) on the same response.
7
- *
8
- * @example
9
- * ```typescript
10
- * const response = await create.get('/api/users').getResponse();
11
- * console.log(response.status); // 200
12
- * console.log(response.ok); // true
13
- * const data = await response.getJson();
14
- * ```
15
- */
16
- export declare class ResponseWrapper {
17
- /** The URL that was requested (if available) */
18
- readonly url?: string;
19
- /** The HTTP method that was used (if available) */
20
- readonly method?: string;
21
- private readonly _res;
22
- private _gqlOpts?;
23
- private _blob?;
24
- private _text?;
25
- private _json?;
26
- private _buf?;
27
- constructor(response: Response, url?: string, method?: string, graphQLOptions?: GraphQLOptions);
28
- /**
29
- * HTTP status code (e.g., 200, 404, 500)
30
- */
31
- get status(): number;
32
- /**
33
- * HTTP status text (e.g., "OK", "Not Found", "Internal Server Error")
34
- */
35
- get statusText(): string;
36
- /**
37
- * Response headers as a Headers object
38
- */
39
- get headers(): Headers;
40
- /**
41
- * Whether the response status is in the 200-299 range (successful)
42
- */
43
- get ok(): boolean;
44
- /**
45
- * The raw Response object from the fetch API.
46
- * Use this if you need direct access to the underlying Response.
47
- */
48
- get raw(): Response;
49
- /**
50
- * Create a RequestError carrying this response's context
51
- * @param message - The error message
52
- * @param withBody - Whether to attach the cached body text to the error
53
- */
54
- private _err;
55
- /**
56
- * Read the response body via the given reader, wrapping failures in a RequestError
57
- * @throws RequestError if the body has already been consumed or reading fails
58
- */
59
- private _read;
60
- /**
61
- * Check if the response body has already been consumed and throw an error if so
62
- * @throws RequestError if the body has already been consumed
63
- */
64
- private _checkUsed;
65
- /**
66
- * Check for GraphQL errors and throw if throwOnError is enabled
67
- * @param data - The parsed JSON data
68
- * @throws RequestError if GraphQL response contains errors and throwOnError is enabled
69
- */
70
- private _checkGql;
71
- /**
72
- * Parse the response body as JSON
73
- * If GraphQL options are set with throwOnError=true, will check for GraphQL errors and throw.
74
- *
75
- * Returns `null` for empty responses (204 No Content, content-length: 0, or empty body).
76
- * This handles common API patterns where PUT/DELETE operations return no content on success.
77
- *
78
- * @returns The parsed JSON data, or `null` for empty responses
79
- * @throws {RequestError} When the request fails, JSON parsing fails, or GraphQL errors occur (if throwOnError enabled).
80
- *
81
- * @example
82
- * const data = await response.getJson();
83
- * if (data !== null) {
84
- * console.log(data.items);
85
- * }
86
- *
87
- * @example
88
- * // Error handling - errors are always RequestError
89
- * try {
90
- * const data = await response.getJson();
91
- * } catch (error) {
92
- * if (error instanceof RequestError) {
93
- * console.log(error.status, error.url, error.method);
94
- * }
95
- * }
96
- */
97
- getJson<T = unknown>(): Promise<T | null>;
98
- /**
99
- * Get the response body as text.
100
- * The result is cached, so subsequent calls return the same value without re-reading the body.
101
- *
102
- * @returns A promise that resolves to the response body as a string
103
- * @throws {RequestError} When the body has already been consumed or reading fails
104
- *
105
- * @example
106
- * ```typescript
107
- * const text = await response.getText();
108
- * console.log(text); // "Hello, world!"
109
- * ```
110
- */
111
- getText(): Promise<string>;
112
- /**
113
- * Get the response body as a Blob.
114
- * Useful for downloading files or handling binary data.
115
- * The result is cached, so subsequent calls return the same value without re-reading the body.
116
- *
117
- * @returns A promise that resolves to the response body as a Blob
118
- * @throws {RequestError} When the body has already been consumed or reading fails
119
- *
120
- * @example
121
- * ```typescript
122
- * const blob = await response.getBlob();
123
- * const url = URL.createObjectURL(blob);
124
- * // Use the blob URL for downloading or displaying
125
- * ```
126
- */
127
- getBlob(): Promise<Blob>;
128
- /**
129
- * Get the response body as an ArrayBuffer.
130
- * Useful for processing binary data at a low level.
131
- * The result is cached, so subsequent calls return the same value without re-reading the body.
132
- *
133
- * @returns A promise that resolves to the response body as an ArrayBuffer
134
- * @throws {RequestError} When the body has already been consumed or reading fails
135
- *
136
- * @example
137
- * ```typescript
138
- * const buffer = await response.getArrayBuffer();
139
- * const uint8Array = new Uint8Array(buffer);
140
- * // Process the binary data
141
- * ```
142
- */
143
- getArrayBuffer(): Promise<ArrayBuffer>;
144
- /**
145
- * Get the raw response body as a ReadableStream
146
- * Note: This consumes the response body and should only be called once.
147
- * Unlike other methods, streams cannot be cached, so this will throw if the body is already consumed.
148
- *
149
- * @returns The response body as a ReadableStream or null
150
- * @throws {RequestError} When the response body has already been consumed
151
- *
152
- * @example
153
- * const stream = response.getBody();
154
- * if (stream) {
155
- * const reader = stream.getReader();
156
- * // Process the stream
157
- * }
158
- */
159
- getBody(): ReadableStream<Uint8Array> | null;
160
- /**
161
- * Extract specific data using a selector function
162
- * If no selector is provided, returns the full JSON response.
163
- *
164
- * Returns `null` for empty responses (204 No Content, content-length: 0, or empty body).
165
- * If a selector is provided and data is `null`, the selector will receive `null`.
166
- *
167
- * @param selector - Optional function to extract and transform data
168
- * @returns A promise that resolves to the selected data, or `null` for empty responses
169
- * @throws {RequestError} When the request fails, JSON parsing fails, or the selector throws an error
170
- *
171
- * @example
172
- * // Get full response
173
- * const data = await response.getData();
174
- * if (data !== null) {
175
- * console.log(data.items);
176
- * }
177
- *
178
- * @example
179
- * // Extract specific data (use null-safe selector for empty responses)
180
- * const users = await response.getData(data => data?.results?.users);
181
- *
182
- * @example
183
- * // Error handling - errors are always RequestError
184
- * try {
185
- * const data = await response.getData();
186
- * } catch (error) {
187
- * if (error instanceof RequestError) {
188
- * console.log(error.status, error.url, error.method);
189
- * }
190
- * }
191
- */
192
- getData<T = unknown, R = T>(selector?: (data: T | null) => R): Promise<T | R | null>;
193
- }