create-request 0.0.1-beta.2
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/LICENSE +21 -0
- package/README.md +575 -0
- package/dist/library/BaseRequest.d.ts +119 -0
- package/dist/library/BodyRequest.d.ts +8 -0
- package/dist/library/RequestError.d.ts +18 -0
- package/dist/library/ResponseWrapper.d.ts +54 -0
- package/dist/library/enums.d.ts +56 -0
- package/dist/library/index.d.ts +16 -0
- package/dist/library/index.esm.js +616 -0
- package/dist/library/index.js +635 -0
- package/dist/library/requestFactories.d.ts +30 -0
- package/dist/library/requestMethods.d.ts +24 -0
- package/dist/library/types.d.ts +19 -0
- package/package.json +56 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.createRequest = {}));
|
|
5
|
+
})(this, (function (exports) { 'use strict';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Enum for HTTP methods
|
|
9
|
+
*/
|
|
10
|
+
exports.HttpMethod = void 0;
|
|
11
|
+
(function (HttpMethod) {
|
|
12
|
+
HttpMethod["GET"] = "GET";
|
|
13
|
+
HttpMethod["POST"] = "POST";
|
|
14
|
+
HttpMethod["PUT"] = "PUT";
|
|
15
|
+
HttpMethod["DELETE"] = "DELETE";
|
|
16
|
+
HttpMethod["PATCH"] = "PATCH";
|
|
17
|
+
HttpMethod["HEAD"] = "HEAD";
|
|
18
|
+
HttpMethod["OPTIONS"] = "OPTIONS";
|
|
19
|
+
})(exports.HttpMethod || (exports.HttpMethod = {}));
|
|
20
|
+
/**
|
|
21
|
+
* Enum for request priorities
|
|
22
|
+
*/
|
|
23
|
+
exports.RequestPriority = void 0;
|
|
24
|
+
(function (RequestPriority) {
|
|
25
|
+
RequestPriority["HIGH"] = "high";
|
|
26
|
+
RequestPriority["LOW"] = "low";
|
|
27
|
+
RequestPriority["AUTO"] = "auto";
|
|
28
|
+
})(exports.RequestPriority || (exports.RequestPriority = {}));
|
|
29
|
+
/**
|
|
30
|
+
* Enum for credentials policies
|
|
31
|
+
*/
|
|
32
|
+
exports.CredentialsPolicy = void 0;
|
|
33
|
+
(function (CredentialsPolicy) {
|
|
34
|
+
CredentialsPolicy["INCLUDE"] = "include";
|
|
35
|
+
CredentialsPolicy["SAME_ORIGIN"] = "same-origin";
|
|
36
|
+
CredentialsPolicy["OMIT"] = "omit";
|
|
37
|
+
})(exports.CredentialsPolicy || (exports.CredentialsPolicy = {}));
|
|
38
|
+
/**
|
|
39
|
+
* Enum for request modes
|
|
40
|
+
*/
|
|
41
|
+
exports.RequestMode = void 0;
|
|
42
|
+
(function (RequestMode) {
|
|
43
|
+
RequestMode["CORS"] = "cors";
|
|
44
|
+
RequestMode["NO_CORS"] = "no-cors";
|
|
45
|
+
RequestMode["SAME_ORIGIN"] = "same-origin";
|
|
46
|
+
RequestMode["NAVIGATE"] = "navigate";
|
|
47
|
+
})(exports.RequestMode || (exports.RequestMode = {}));
|
|
48
|
+
/**
|
|
49
|
+
* Enum for redirect modes
|
|
50
|
+
*/
|
|
51
|
+
exports.RedirectMode = void 0;
|
|
52
|
+
(function (RedirectMode) {
|
|
53
|
+
RedirectMode["FOLLOW"] = "follow";
|
|
54
|
+
RedirectMode["ERROR"] = "error";
|
|
55
|
+
RedirectMode["MANUAL"] = "manual";
|
|
56
|
+
})(exports.RedirectMode || (exports.RedirectMode = {}));
|
|
57
|
+
/**
|
|
58
|
+
* Enum for cache modes
|
|
59
|
+
*/
|
|
60
|
+
exports.CacheMode = void 0;
|
|
61
|
+
(function (CacheMode) {
|
|
62
|
+
CacheMode["DEFAULT"] = "default";
|
|
63
|
+
CacheMode["NO_STORE"] = "no-store";
|
|
64
|
+
CacheMode["RELOAD"] = "reload";
|
|
65
|
+
CacheMode["NO_CACHE"] = "no-cache";
|
|
66
|
+
CacheMode["FORCE_CACHE"] = "force-cache";
|
|
67
|
+
CacheMode["ONLY_IF_CACHED"] = "only-if-cached";
|
|
68
|
+
})(exports.CacheMode || (exports.CacheMode = {}));
|
|
69
|
+
|
|
70
|
+
class RequestError extends Error {
|
|
71
|
+
constructor(message, url, method, options = {}) {
|
|
72
|
+
super(message);
|
|
73
|
+
this.name = "RequestError";
|
|
74
|
+
this.url = url;
|
|
75
|
+
this.method = method;
|
|
76
|
+
this.status = options.status;
|
|
77
|
+
this.response = options.response;
|
|
78
|
+
this.timeoutError = options.timeoutError;
|
|
79
|
+
// For better stack traces in modern environments
|
|
80
|
+
if (Error.captureStackTrace) {
|
|
81
|
+
Error.captureStackTrace(this, RequestError);
|
|
82
|
+
}
|
|
83
|
+
// Maintains proper prototype chain for instanceof checks
|
|
84
|
+
Object.setPrototypeOf(this, RequestError.prototype);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Static methods for creating specific types of RequestError
|
|
88
|
+
*/
|
|
89
|
+
static timeout(url, method, timeoutMs) {
|
|
90
|
+
return new RequestError(`Request timed out after ${timeoutMs}ms`, url, method, {
|
|
91
|
+
timeoutError: true,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
static fromResponse(response, url, method) {
|
|
95
|
+
return new RequestError(`Request failed with status ${response.status}`, url, method, {
|
|
96
|
+
status: response.status,
|
|
97
|
+
response,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
static networkError(url, method, originalError) {
|
|
101
|
+
const error = new RequestError(`Network error: ${originalError.message}`, url, method);
|
|
102
|
+
error.stack = originalError.stack;
|
|
103
|
+
return error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Wrapper for HTTP responses with methods to transform the response data
|
|
109
|
+
*/
|
|
110
|
+
class ResponseWrapper {
|
|
111
|
+
constructor(response) {
|
|
112
|
+
this.response = response;
|
|
113
|
+
this.ok = response.status >= 200 && response.status < 300; // Standard Fetch API behavior
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get the raw Response object
|
|
117
|
+
*/
|
|
118
|
+
get raw() {
|
|
119
|
+
return this.response;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the HTTP status code
|
|
123
|
+
*/
|
|
124
|
+
get status() {
|
|
125
|
+
return this.response.status;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get the HTTP status text
|
|
129
|
+
*/
|
|
130
|
+
get statusText() {
|
|
131
|
+
return this.response.statusText;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get response headers
|
|
135
|
+
*/
|
|
136
|
+
get headers() {
|
|
137
|
+
return this.response.headers;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Parse response as JSON
|
|
141
|
+
*/
|
|
142
|
+
async json() {
|
|
143
|
+
return this.response.json();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get response as text
|
|
147
|
+
*/
|
|
148
|
+
async text() {
|
|
149
|
+
return this.response.text();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get response as Blob
|
|
153
|
+
*/
|
|
154
|
+
async blob() {
|
|
155
|
+
return this.response.blob();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get response as ArrayBuffer
|
|
159
|
+
*/
|
|
160
|
+
async arrayBuffer() {
|
|
161
|
+
return this.response.arrayBuffer();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get response as ReadableStream
|
|
165
|
+
*/
|
|
166
|
+
body() {
|
|
167
|
+
return this.response.body;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Base class with common functionality for all request types
|
|
172
|
+
class BaseRequest {
|
|
173
|
+
constructor() {
|
|
174
|
+
this.requestOptions = {};
|
|
175
|
+
this.queryParams = new URLSearchParams();
|
|
176
|
+
}
|
|
177
|
+
withHeaders(headers) {
|
|
178
|
+
this.requestOptions.headers = {
|
|
179
|
+
...(this.requestOptions.headers || {}),
|
|
180
|
+
...headers,
|
|
181
|
+
};
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
withTimeout(timeout) {
|
|
185
|
+
this.requestOptions.timeout = timeout;
|
|
186
|
+
return this;
|
|
187
|
+
}
|
|
188
|
+
withRetries(retries) {
|
|
189
|
+
this.requestOptions.retries = retries;
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
onRetry(callback) {
|
|
193
|
+
this.requestOptions.onRetry = callback;
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Sets the credentials policy for the request
|
|
198
|
+
* @param credentialsPolicy - Can be 'omit', 'same-origin', or 'include'
|
|
199
|
+
* @returns The instance for chaining
|
|
200
|
+
*/
|
|
201
|
+
withCredentials(credentialsPolicy = exports.CredentialsPolicy.SAME_ORIGIN) {
|
|
202
|
+
this.requestOptions.credentials = credentialsPolicy;
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Allows providing an external AbortController to cancel the request
|
|
207
|
+
* @param controller - The AbortController to use for this request
|
|
208
|
+
* @returns The instance for chaining
|
|
209
|
+
*/
|
|
210
|
+
withAbortController(controller) {
|
|
211
|
+
this.abortController = controller;
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Sets the referrer for the request
|
|
216
|
+
* @param referrer - The referrer URL or policy
|
|
217
|
+
* @returns The instance for chaining
|
|
218
|
+
*/
|
|
219
|
+
withReferrer(referrer) {
|
|
220
|
+
this.requestOptions.referrer = referrer;
|
|
221
|
+
return this;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Sets the redirect policy for the request
|
|
225
|
+
* @param redirect - Can be 'follow', 'error', or 'manual'
|
|
226
|
+
* @returns The instance for chaining
|
|
227
|
+
*/
|
|
228
|
+
withRedirect(redirect) {
|
|
229
|
+
this.requestOptions.redirect = redirect;
|
|
230
|
+
return this;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Sets the keepalive flag for the request
|
|
234
|
+
* @param keepalive - Whether to allow the request to outlive the page
|
|
235
|
+
* @returns The instance for chaining
|
|
236
|
+
*/
|
|
237
|
+
withKeepAlive(keepalive) {
|
|
238
|
+
this.requestOptions.keepalive = keepalive;
|
|
239
|
+
return this;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Sets the priority of the request
|
|
243
|
+
* @param priority - Can be 'high', 'low', or 'auto'
|
|
244
|
+
* @returns The instance for chaining
|
|
245
|
+
*/
|
|
246
|
+
withPriority(priority) {
|
|
247
|
+
this.requestOptions.priority = priority;
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Adds query parameters to the request URL
|
|
252
|
+
* @param params - An object containing the query parameters
|
|
253
|
+
* @returns The instance for chaining
|
|
254
|
+
*/
|
|
255
|
+
withQueryParams(params) {
|
|
256
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
257
|
+
if (value === null || value === undefined) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (Array.isArray(value)) {
|
|
261
|
+
// Handle array values - add multiple entries with the same key
|
|
262
|
+
value.forEach(v => this.queryParams.append(key, String(v)));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
this.queryParams.append(key, String(value));
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Adds a single query parameter
|
|
272
|
+
* @param key - The parameter name
|
|
273
|
+
* @param value - The parameter value
|
|
274
|
+
* @returns The instance for chaining
|
|
275
|
+
*/
|
|
276
|
+
withQueryParam(key, value) {
|
|
277
|
+
if (value !== null && value !== undefined) {
|
|
278
|
+
this.queryParams.append(key, String(value));
|
|
279
|
+
}
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Sets the mode of the request
|
|
284
|
+
* @param mode - The mode for the request (cors, no-cors, same-origin, navigate)
|
|
285
|
+
* @returns The instance for chaining
|
|
286
|
+
*/
|
|
287
|
+
withMode(mode) {
|
|
288
|
+
this.requestOptions.mode = mode;
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Shorthand for setting the Content-Type header
|
|
293
|
+
* @param contentType - The content type
|
|
294
|
+
* @returns The instance for chaining
|
|
295
|
+
*/
|
|
296
|
+
withContentType(contentType) {
|
|
297
|
+
return this.withHeaders({
|
|
298
|
+
"Content-Type": contentType,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Shorthand for setting the Authorization header
|
|
303
|
+
* @param authValue - The authorization value
|
|
304
|
+
* @returns The instance for chaining
|
|
305
|
+
*/
|
|
306
|
+
withAuthorization(authValue) {
|
|
307
|
+
return this.withHeaders({
|
|
308
|
+
Authorization: authValue,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Shorthand for setting up Basic authentication
|
|
313
|
+
* @param username - The username
|
|
314
|
+
* @param password - The password
|
|
315
|
+
* @returns The instance for chaining
|
|
316
|
+
*/
|
|
317
|
+
withBasicAuth(username, password) {
|
|
318
|
+
const credentials = btoa(`${username}:${password}`);
|
|
319
|
+
return this.withAuthorization(`Basic ${credentials}`);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Sets the bearer token for authentication
|
|
323
|
+
* @param token - The bearer token
|
|
324
|
+
* @returns The instance for chaining
|
|
325
|
+
*/
|
|
326
|
+
withBearerToken(token) {
|
|
327
|
+
return this.withAuthorization(`Bearer ${token}`);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Sets cookies for the request
|
|
331
|
+
* @param cookies - An object containing cookie name-value pairs
|
|
332
|
+
* @returns The instance for chaining
|
|
333
|
+
*/
|
|
334
|
+
withCookies(cookies) {
|
|
335
|
+
const cookieEntries = Object.entries(cookies);
|
|
336
|
+
if (cookieEntries.length === 0) {
|
|
337
|
+
return this;
|
|
338
|
+
}
|
|
339
|
+
// Format cookies as name=value pairs
|
|
340
|
+
const cookieString = cookieEntries
|
|
341
|
+
.map(([name, value]) => `${encodeURIComponent(name)}=${encodeURIComponent(value)}`)
|
|
342
|
+
.join("; ");
|
|
343
|
+
// Get current headers or initialize empty object
|
|
344
|
+
const currentHeaders = this.requestOptions.headers || {};
|
|
345
|
+
// If there's already a Cookie header, append to it; otherwise create a new one
|
|
346
|
+
const existingCookies = currentHeaders["Cookie"] || "";
|
|
347
|
+
const newCookieValue = existingCookies ? `${existingCookies}; ${cookieString}` : cookieString;
|
|
348
|
+
// Set the Cookie header
|
|
349
|
+
return this.withHeaders({
|
|
350
|
+
Cookie: newCookieValue,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Send the request to the specified URL
|
|
355
|
+
* @param url The URL to send the request to
|
|
356
|
+
*/
|
|
357
|
+
sendTo(url) {
|
|
358
|
+
// Format the URL with query parameters
|
|
359
|
+
url = this.formatUrlWithQueryParams(url);
|
|
360
|
+
// Cast the request options to RequestInit to ensure compatibility
|
|
361
|
+
const fetchOptions = {
|
|
362
|
+
...this.requestOptions,
|
|
363
|
+
method: this.method,
|
|
364
|
+
};
|
|
365
|
+
// Create the base promise
|
|
366
|
+
const basePromise = !this.requestOptions.retries
|
|
367
|
+
? this.executeRequest(url, fetchOptions)
|
|
368
|
+
: this.executeWithRetries(url, fetchOptions);
|
|
369
|
+
// Enhance the promise with response methods
|
|
370
|
+
const responsePromise = basePromise.then(response => response);
|
|
371
|
+
// Attach convenience methods to the promise
|
|
372
|
+
responsePromise.json = async () => {
|
|
373
|
+
const response = await basePromise;
|
|
374
|
+
return response.json();
|
|
375
|
+
};
|
|
376
|
+
responsePromise.text = async () => {
|
|
377
|
+
const response = await basePromise;
|
|
378
|
+
return response.text();
|
|
379
|
+
};
|
|
380
|
+
responsePromise.blob = async () => {
|
|
381
|
+
const response = await basePromise;
|
|
382
|
+
return response.blob();
|
|
383
|
+
};
|
|
384
|
+
responsePromise.arrayBuffer = async () => {
|
|
385
|
+
const response = await basePromise;
|
|
386
|
+
return response.arrayBuffer();
|
|
387
|
+
};
|
|
388
|
+
responsePromise.body = async () => {
|
|
389
|
+
const response = await basePromise;
|
|
390
|
+
return response.body();
|
|
391
|
+
};
|
|
392
|
+
return responsePromise;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Formats the URL with any query parameters
|
|
396
|
+
* @param url The base URL
|
|
397
|
+
* @returns The URL with query parameters appended
|
|
398
|
+
*/
|
|
399
|
+
formatUrlWithQueryParams(url) {
|
|
400
|
+
if (!this.queryParams.toString()) {
|
|
401
|
+
return url;
|
|
402
|
+
}
|
|
403
|
+
const urlObj = new URL(url);
|
|
404
|
+
// Merge our query params with any that might be in the URL already
|
|
405
|
+
this.queryParams.forEach((value, key) => {
|
|
406
|
+
urlObj.searchParams.append(key, value);
|
|
407
|
+
});
|
|
408
|
+
return urlObj.toString();
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Executes a request with configured retry logic
|
|
412
|
+
* @param url The formatted URL to send the request to
|
|
413
|
+
* @param fetchOptions The fetch options to use
|
|
414
|
+
* @returns A wrapped response object
|
|
415
|
+
*/
|
|
416
|
+
async executeWithRetries(url, fetchOptions) {
|
|
417
|
+
let retryCount = 0;
|
|
418
|
+
const maxRetries = this.requestOptions.retries || 0;
|
|
419
|
+
// eslint-disable-next-line no-constant-condition
|
|
420
|
+
while (true) {
|
|
421
|
+
try {
|
|
422
|
+
return await this.executeRequest(url, fetchOptions);
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
const requestError = error instanceof RequestError
|
|
426
|
+
? error
|
|
427
|
+
: RequestError.networkError(url, fetchOptions.method, error);
|
|
428
|
+
if (retryCount >= maxRetries || requestError.timeoutError) {
|
|
429
|
+
throw requestError;
|
|
430
|
+
}
|
|
431
|
+
retryCount++;
|
|
432
|
+
if (this.requestOptions.onRetry) {
|
|
433
|
+
await this.requestOptions.onRetry({ retryCount, error: requestError });
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
async executeRequest(url, fetchOptions) {
|
|
439
|
+
// Create a request controller for timeout if needed, or use the provided one
|
|
440
|
+
const controller = this.abortController || new AbortController();
|
|
441
|
+
const { signal } = controller;
|
|
442
|
+
// Use the controller signal for the fetch request, but don't overwrite an existing signal
|
|
443
|
+
// that might have been set in requestOptions if it exists
|
|
444
|
+
fetchOptions.signal = fetchOptions.signal || signal;
|
|
445
|
+
let timeoutId;
|
|
446
|
+
// If we have a timeout and we're using our own controller (not provided externally)
|
|
447
|
+
if (this.requestOptions.timeout && !this.abortController) {
|
|
448
|
+
timeoutId = setTimeout(() => {
|
|
449
|
+
controller.abort();
|
|
450
|
+
}, this.requestOptions.timeout);
|
|
451
|
+
}
|
|
452
|
+
try {
|
|
453
|
+
let response;
|
|
454
|
+
try {
|
|
455
|
+
response = await fetch(url, fetchOptions);
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
// Check if this is an abort error from our timeout
|
|
459
|
+
if (error instanceof DOMException && error.name === "AbortError" && timeoutId) {
|
|
460
|
+
throw RequestError.timeout(url, fetchOptions.method, this.requestOptions.timeout);
|
|
461
|
+
}
|
|
462
|
+
// Otherwise it's a network error
|
|
463
|
+
throw RequestError.networkError(url, fetchOptions.method, error);
|
|
464
|
+
}
|
|
465
|
+
if (!response.ok) {
|
|
466
|
+
throw RequestError.fromResponse(response, url, fetchOptions.method);
|
|
467
|
+
}
|
|
468
|
+
// Return a wrapped response instead of parsing it
|
|
469
|
+
return new ResponseWrapper(response);
|
|
470
|
+
}
|
|
471
|
+
finally {
|
|
472
|
+
if (timeoutId) {
|
|
473
|
+
clearTimeout(timeoutId);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// An extension of BaseRequest for methods that support request bodies
|
|
480
|
+
class BodyRequest extends BaseRequest {
|
|
481
|
+
/**
|
|
482
|
+
* Sets the request body with appropriate content type handling
|
|
483
|
+
*/
|
|
484
|
+
withBody(body) {
|
|
485
|
+
if (body === undefined || body === null) {
|
|
486
|
+
this.requestOptions.body = null;
|
|
487
|
+
return this;
|
|
488
|
+
}
|
|
489
|
+
// Handle special body types that don't need transformation
|
|
490
|
+
if (body instanceof Blob ||
|
|
491
|
+
body instanceof FormData ||
|
|
492
|
+
body instanceof URLSearchParams ||
|
|
493
|
+
body instanceof ArrayBuffer ||
|
|
494
|
+
body instanceof ReadableStream) {
|
|
495
|
+
this.requestOptions.body = body;
|
|
496
|
+
// For FormData, make sure to NOT explicitly set Content-Type
|
|
497
|
+
// The browser will set it automatically with the correct boundary
|
|
498
|
+
// If we set it manually, it would be missing the boundary parameter
|
|
499
|
+
return this;
|
|
500
|
+
}
|
|
501
|
+
// Handle strings
|
|
502
|
+
if (typeof body === "string") {
|
|
503
|
+
this.requestOptions.body = body;
|
|
504
|
+
return this;
|
|
505
|
+
}
|
|
506
|
+
// For objects and other types, stringify and set JSON content-type
|
|
507
|
+
try {
|
|
508
|
+
this.requestOptions.body = JSON.stringify(body);
|
|
509
|
+
this.requestOptions.headers = {
|
|
510
|
+
"Content-Type": "application/json",
|
|
511
|
+
...(this.requestOptions.headers || {}),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
catch (error) {
|
|
515
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
516
|
+
throw new Error(`Failed to stringify request body: ${errorMessage}`);
|
|
517
|
+
}
|
|
518
|
+
return this;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Methods without body
|
|
523
|
+
class GetRequest extends BaseRequest {
|
|
524
|
+
constructor() {
|
|
525
|
+
super(...arguments);
|
|
526
|
+
this.method = exports.HttpMethod.GET;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
class HeadRequest extends BaseRequest {
|
|
530
|
+
constructor() {
|
|
531
|
+
super(...arguments);
|
|
532
|
+
this.method = exports.HttpMethod.HEAD;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
class OptionsRequest extends BaseRequest {
|
|
536
|
+
constructor() {
|
|
537
|
+
super(...arguments);
|
|
538
|
+
this.method = exports.HttpMethod.OPTIONS;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
class DeleteRequest extends BaseRequest {
|
|
542
|
+
constructor() {
|
|
543
|
+
super(...arguments);
|
|
544
|
+
this.method = exports.HttpMethod.DELETE;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
// Methods with body
|
|
548
|
+
class PostRequest extends BodyRequest {
|
|
549
|
+
constructor() {
|
|
550
|
+
super(...arguments);
|
|
551
|
+
this.method = exports.HttpMethod.POST;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
class PutRequest extends BodyRequest {
|
|
555
|
+
constructor() {
|
|
556
|
+
super(...arguments);
|
|
557
|
+
this.method = exports.HttpMethod.PUT;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
class PatchRequest extends BodyRequest {
|
|
561
|
+
constructor() {
|
|
562
|
+
super(...arguments);
|
|
563
|
+
this.method = exports.HttpMethod.PATCH;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Create a GET request
|
|
569
|
+
*/
|
|
570
|
+
function get() {
|
|
571
|
+
return new GetRequest();
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Create a POST request
|
|
575
|
+
*/
|
|
576
|
+
function post() {
|
|
577
|
+
return new PostRequest();
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Create a PUT request
|
|
581
|
+
*/
|
|
582
|
+
function put() {
|
|
583
|
+
return new PutRequest();
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Create a DELETE request
|
|
587
|
+
* Note: We use 'del' to avoid JS keyword conflict
|
|
588
|
+
*/
|
|
589
|
+
function del() {
|
|
590
|
+
return new DeleteRequest();
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Create a PATCH request
|
|
594
|
+
*/
|
|
595
|
+
function patch() {
|
|
596
|
+
return new PatchRequest();
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Create a HEAD request
|
|
600
|
+
*/
|
|
601
|
+
function head() {
|
|
602
|
+
return new HeadRequest();
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Create an OPTIONS request
|
|
606
|
+
*/
|
|
607
|
+
function options() {
|
|
608
|
+
return new OptionsRequest();
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Create the main API object
|
|
612
|
+
const create = {
|
|
613
|
+
get,
|
|
614
|
+
post,
|
|
615
|
+
put,
|
|
616
|
+
del,
|
|
617
|
+
patch,
|
|
618
|
+
head,
|
|
619
|
+
options,
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
exports.DeleteRequest = DeleteRequest;
|
|
623
|
+
exports.GetRequest = GetRequest;
|
|
624
|
+
exports.HeadRequest = HeadRequest;
|
|
625
|
+
exports.OptionsRequest = OptionsRequest;
|
|
626
|
+
exports.PatchRequest = PatchRequest;
|
|
627
|
+
exports.PostRequest = PostRequest;
|
|
628
|
+
exports.PutRequest = PutRequest;
|
|
629
|
+
exports.RequestError = RequestError;
|
|
630
|
+
exports.ResponseWrapper = ResponseWrapper;
|
|
631
|
+
exports["default"] = create;
|
|
632
|
+
|
|
633
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
634
|
+
|
|
635
|
+
}));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { GetRequest, PostRequest, PutRequest, DeleteRequest, PatchRequest, HeadRequest, OptionsRequest } from "./requestMethods";
|
|
2
|
+
/**
|
|
3
|
+
* Create a GET request
|
|
4
|
+
*/
|
|
5
|
+
export declare function get(): GetRequest;
|
|
6
|
+
/**
|
|
7
|
+
* Create a POST request
|
|
8
|
+
*/
|
|
9
|
+
export declare function post(): PostRequest;
|
|
10
|
+
/**
|
|
11
|
+
* Create a PUT request
|
|
12
|
+
*/
|
|
13
|
+
export declare function put(): PutRequest;
|
|
14
|
+
/**
|
|
15
|
+
* Create a DELETE request
|
|
16
|
+
* Note: We use 'del' to avoid JS keyword conflict
|
|
17
|
+
*/
|
|
18
|
+
export declare function del(): DeleteRequest;
|
|
19
|
+
/**
|
|
20
|
+
* Create a PATCH request
|
|
21
|
+
*/
|
|
22
|
+
export declare function patch(): PatchRequest;
|
|
23
|
+
/**
|
|
24
|
+
* Create a HEAD request
|
|
25
|
+
*/
|
|
26
|
+
export declare function head(): HeadRequest;
|
|
27
|
+
/**
|
|
28
|
+
* Create an OPTIONS request
|
|
29
|
+
*/
|
|
30
|
+
export declare function options(): OptionsRequest;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseRequest } from "./BaseRequest";
|
|
2
|
+
import { BodyRequest } from "./BodyRequest";
|
|
3
|
+
import { HttpMethod } from "./enums";
|
|
4
|
+
export declare class GetRequest extends BaseRequest {
|
|
5
|
+
protected method: HttpMethod;
|
|
6
|
+
}
|
|
7
|
+
export declare class HeadRequest extends BaseRequest {
|
|
8
|
+
protected method: HttpMethod;
|
|
9
|
+
}
|
|
10
|
+
export declare class OptionsRequest extends BaseRequest {
|
|
11
|
+
protected method: HttpMethod;
|
|
12
|
+
}
|
|
13
|
+
export declare class DeleteRequest extends BaseRequest {
|
|
14
|
+
protected method: HttpMethod;
|
|
15
|
+
}
|
|
16
|
+
export declare class PostRequest extends BodyRequest {
|
|
17
|
+
protected method: HttpMethod;
|
|
18
|
+
}
|
|
19
|
+
export declare class PutRequest extends BodyRequest {
|
|
20
|
+
protected method: HttpMethod;
|
|
21
|
+
}
|
|
22
|
+
export declare class PatchRequest extends BodyRequest {
|
|
23
|
+
protected method: HttpMethod;
|
|
24
|
+
}
|