aspi 1.1.0-beta.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.
@@ -0,0 +1,1285 @@
1
+ /**
2
+ * Standard HTTP /**
3
+ * Common HTTP error status codes with their numeric values.
4
+ * @readonly
5
+ * @enum {number}
6
+ * @property {number} BAD_REQUEST - 400 Bad Request
7
+ * @property {number} UNAUTHORIZED - 401 Unauthorized
8
+ * @property {number} FORBIDDEN - 403 Forbidden
9
+ * @property {number} NOT_FOUND - 404 Not Found
10
+ * @property {number} METHOD_NOT_ALLOWED - 405 Method Not Allowed
11
+ * @property {number} CONFLICT - 409 Conflict
12
+ * @property {number} LARGE - 413 Payload Too Large
13
+ * @property {number} UNS {number} * @property
14
+ - 413Request entity too largeUPPORTED_MEDIA_TYPE - 415 Unsupported Media Type
15
+ *@property {number} } UNPROCESSABLE_ENTITY - 422 Unprocessable Entity
16
+ * @property {number} TO_MANY_REQUESTS - 429 Too Many Requests
17
+ * @property {number} * @property
18
+ Too many requests made - 429 {number} INTERNAL_SERVER_ERROR - 500 Internal Server Error
19
+ * @property {number} *
20
+ 500Generic server error -@property {number} NOT_IMPLEMENTED - 501 Not Implemented
21
+ * @property {number} *
22
+ 501Functionality not implemented -@property {number} BAD_GATEWAY - 502 Bad Gateway
23
+ * @property {number} UNAVAILABLE - 503 Service Unavailable
24
+ * @property {number} * @property {number
25
+ temporarily unavailable - 503Server} GATEWAY_TIMEOUT - 504 Gateway Timeout
26
+ */
27
+ declare const httpErrors: {
28
+ readonly BAD_REQUEST: 400;
29
+ readonly UNAUTHORIZED: 401;
30
+ readonly FORBIDDEN: 403;
31
+ readonly NOT_FOUND: 404;
32
+ readonly METHOD_NOT_ALLOWED: 405;
33
+ readonly CONFLICT: 409;
34
+ readonly PAYLOAD_TOO_LARGE: 413;
35
+ readonly UNSUPPORTED_MEDIA_TYPE: 415;
36
+ readonly UNPROCESSABLE_ENTITY: 422;
37
+ readonly TOO_MANY_REQUESTS: 429;
38
+ readonly INTERNAL_SERVER_ERROR: 500;
39
+ readonly NOT_IMPLEMENTED: 501;
40
+ readonly BAD_GATEWAY: 502;
41
+ readonly SERVICE_UNAVAILABLE: 503;
42
+ readonly GATEWAY_TIMEOUT: 504;
43
+ };
44
+ /**
45
+ * Type representing the possible numeric HTTP error codes.
46
+ * Derived from the values in the `httpErrors` const.
47
+ */
48
+ type HttpErrorCodes = (typeof httpErrors)[keyof typeof httpErrors];
49
+ /**
50
+ * Type representing the possible HTTP error status keys.
51
+ * Derived from the keys in the `httpErrors` const.
52
+ */
53
+ type HttpErrorStatus = keyof typeof httpErrors;
54
+ /**
55
+ * Gets the string key representation of an HTTP error status code.
56
+ *
57
+ * @param {HttpErrorCodes} status - The numeric HTTP error status code
58
+ * @returns {HttpErrorStatus} The string key representing the status code
59
+ *
60
+ * @example
61
+ * getHttpErrorStatus(404) // returns 'NOT_FOUND'
62
+ * getHttpErrorStatus(500) // returns 'INTERNAL_SERVER_ERROR'
63
+ */
64
+ declare const getHttpErrorStatus: (status: HttpErrorCodes) => HttpErrorStatus;
65
+ /**
66
+ * Valid HTTP methods as defined in the HTTP/1.1 specification.
67
+ */
68
+ type HttpMethods = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'TRACE' | 'CONNECT';
69
+
70
+ type AspiConfigBase = {
71
+ baseUrl: string;
72
+ retryConfig?: AspiRetryConfig<AspiRequestInit>;
73
+ };
74
+ type AspiRetryConfig<TRequest extends AspiRequestInit> = {
75
+ retries?: number;
76
+ retryDelay?: number | ((remainingRetries: number, totalRetries: number, request: AspiRequest<TRequest>, response: AspiResponse) => number | Promise<number>);
77
+ retryOn?: Array<HttpErrorCodes>;
78
+ retryWhile?: (request: AspiRequest<TRequest>, response: AspiResponse) => boolean | Promise<boolean>;
79
+ onRetry?: (request: AspiRequest<TRequest>, response: AspiResponse) => void;
80
+ };
81
+ type AspiConfig = Pick<RequestInit, 'headers' | 'mode'> & AspiConfigBase;
82
+ type CustomErrorCb<T extends AspiRequestInit, A extends {}> = (input: {
83
+ request: AspiRequest<T>;
84
+ response: AspiResponse;
85
+ }) => A;
86
+ type Middleware<T extends RequestInit, U extends RequestInit> = (request: T) => U;
87
+ interface AspiRequestInit extends RequestInit, AspiConfigBase {
88
+ }
89
+ type RequestOptions<TRequest extends AspiRequestInit> = {
90
+ requestConfig: TRequest;
91
+ retryConfig?: AspiRetryConfig<TRequest>;
92
+ middlewares?: Middleware<TRequest, TRequest>[];
93
+ errorCbs?: ErrorCallbacks;
94
+ };
95
+ type ErrorCallbacks = Record<number, {
96
+ cb: (input: {
97
+ request: any;
98
+ response: any;
99
+ }) => any;
100
+ tag: unknown;
101
+ }>;
102
+ type AspiResultOk<TRequest extends AspiRequestInit, TData> = {
103
+ data: TData;
104
+ request: AspiRequest<TRequest>;
105
+ response: AspiResponse;
106
+ };
107
+
108
+ /**
109
+ * Response interface used in error handling
110
+ * @interface AspiResponse
111
+ * @property {HttpErrorCodes} status - The HTTP status code of the response
112
+ * @property {HttpErrorStatus} statusText - The HTTP status text of the response
113
+ * @property {Response} [response] - Optional raw Response object
114
+ * @property {any} [responseData] - Optional response data content
115
+ */
116
+ interface AspiResponse {
117
+ status: HttpErrorCodes;
118
+ statusText: HttpErrorStatus;
119
+ response?: Response;
120
+ responseData?: any;
121
+ }
122
+ /**
123
+ * Interface representing an API request configuration
124
+ * @interface AspiRequest
125
+ * @template T - Request initialization options type extending AspiRequestInit
126
+ * @property {string} baseUrl - Base URL for the API request
127
+ * @property {string} path - Request path to append to baseUrl
128
+ * @property {T} requestInit - Request initialization options
129
+ * @property {URLSearchParams | null} queryParams - URL query parameters, if any
130
+ * @property {AspiRetryConfig<T>} retryConfig - Retry configuration for failed requests
131
+ */
132
+ interface AspiRequest<T extends AspiRequestInit> {
133
+ baseUrl: string;
134
+ path: string;
135
+ requestInit: T;
136
+ queryParams: URLSearchParams | null;
137
+ retryConfig: AspiRetryConfig<T>;
138
+ }
139
+ /**
140
+ * Custom error class for API errors
141
+ * @class AspiError
142
+ * @extends {Error}
143
+ * @property {string} tag - Constant identifier for this error type
144
+ * @property {AspiRe} request - The original request configuration
145
+ * @property {AspiResponse} response - The error response details
146
+ */
147
+ declare class AspiError<TReq extends AspiRequestInit> extends Error {
148
+ tag: "aspiError";
149
+ request: AspiRequest<TReq>;
150
+ response: AspiResponse;
151
+ /**
152
+ * Creates an instance of AspiError
153
+ * @param {string} message - The error message
154
+ * @param {AspiRe} request - The request configuration
155
+ * @param {AspiResponse} response - The error response
156
+ */
157
+ constructor(message: string, request: AspiRequest<TReq>, response: AspiResponse);
158
+ /**
159
+ * Conditionally executes callback if status matches
160
+ * @template T
161
+ * @param {HttpErrorStatus} status - The status to match against
162
+ * @param {(args: { request: AspiRequest; response: AspiResponse }) => T} cb - Callback to execute on match
163
+ * @returns {T | undefined} Result of callback if status matches, undefined otherwise
164
+ */
165
+ ifMatch<T>(status: HttpErrorStatus, cb: (args: {
166
+ request: AspiRequest<TReq>;
167
+ response: AspiResponse;
168
+ }) => T): T | undefined;
169
+ }
170
+ /**
171
+ * Custom error class with generic tag and data fields
172
+ * @class CustomError
173
+ * @extends {Error}
174
+ * @template Tag - String literal type for the error tag
175
+ * @template A - Type of the error data
176
+ * @property {Tag} tag - Tag identifying the error type
177
+ * @property {A} data - Additional error data
178
+ */
179
+ declare class CustomError<Tag extends string, A> extends Error {
180
+ tag: Tag;
181
+ data: A;
182
+ /**
183
+ * Creates an instance of CustomError
184
+ * @param {Tag} tag - Tag identifying the error type
185
+ * @param {A} data - Additional error data
186
+ */
187
+ constructor(tag: Tag, data: A);
188
+ }
189
+ /**
190
+ * Interface representing a JSON parsing error
191
+ * @interface JSONParseError
192
+ * @extends {CustomError<'jsonParseError', { message: string }>}
193
+ */
194
+ interface JSONParseError extends CustomError<'jsonParseError', {
195
+ message: string;
196
+ }> {
197
+ }
198
+
199
+ type Ok<T> = {
200
+ __tag: 'ok';
201
+ value: T;
202
+ };
203
+ type Err<E> = {
204
+ __tag: 'err';
205
+ error: E;
206
+ };
207
+ /**
208
+ * Represents either a successful value of type T or an error of type E
209
+ * @example
210
+ * const success: Result<number, string> = { __tag: "ok", value: 42 };
211
+ * const failure: Result<number, string> = { __tag: "err", error: "not found" };
212
+ */
213
+ type Result<T, E> = Ok<T> | Err<E>;
214
+ /**
215
+ * Creates a successful Result
216
+ * @example
217
+ * const result = ok(42);
218
+ * // { __tag: "ok", value: 42 }
219
+ */
220
+ declare const ok: <T>(value: T) => Ok<T>;
221
+ /**
222
+ * Creates a failed Result
223
+ * @example
224
+ * const result = err("not found");
225
+ * // { __tag: "err", error: "not found" }
226
+ */
227
+ declare const err: <E>(error: E) => Err<E>;
228
+ /**
229
+ * Returns true if the result is a success
230
+ * @example
231
+ * const result = ok(42);
232
+ * isOk(result) // true
233
+ *
234
+ * const error = err("not found");
235
+ * isOk(error) // false
236
+ */
237
+ declare const isOk: <T, E>(result: Result<T, E>) => result is Ok<T>;
238
+ /**
239
+ * Returns true if the result is a failure
240
+ * @example
241
+ * const result = ok(42);
242
+ * isErr(result) // false
243
+ *
244
+ * const error = err("not found");
245
+ * isErr(error) // true
246
+ */
247
+ declare const isErr: <T, E>(result: Result<T, E>) => result is Err<E>;
248
+ /**
249
+ * Maps a function over the value of a successful Result
250
+ * @param fn - Function to map over the successful value
251
+ * @param self - The Result to map over
252
+ * @returns A new Result with the mapped value if successful, or the original error if failed
253
+ * @example
254
+ * // Direct style
255
+ * const result = ok(42);
256
+ * map(result, (x) => x * 2) // { __tag: "ok", value: 84 }
257
+ *
258
+ * const error = err("not found");
259
+ * map(error, (x) => x * 2) // { __tag: "err", error: "not found" }
260
+ *
261
+ * // Curried style
262
+ * const double = map((x: number) => x * 2);
263
+ * double(ok(42)) // { __tag: "ok", value: 84 }
264
+ * double(err("not found")) // { __tag: "err", error: "not found" }
265
+ */
266
+ declare function map<T, E, U>(fn: (value: T) => U): (self: Result<T, E>) => Result<U, E>;
267
+ declare function map<T, E, U>(self: Result<T, E>, fn: (value: T) => U): Result<U, E>;
268
+ /**
269
+ * Maps a function over the error of a failed Result
270
+ * @param fn - Function to map over the error value
271
+ * @param self - The Result to map over
272
+ * @returns A new Result with the mapped error if failed, or the original value if successful
273
+ * @example
274
+ * // Direct style
275
+ * const result = ok(42);
276
+ * mapErr(result, (e) => e.toUpperCase()) // { __tag: "ok", value: 42 }
277
+ *
278
+ * const error = err("not found");
279
+ * mapErr(error, (e) => e.toUpperCase()) // { __tag: "err", error: "NOT FOUND" }
280
+ *
281
+ * // Curried style
282
+ * const toUpper = mapErr((e: string) => e.toUpperCase());
283
+ * toUpper(ok(42)) // { __tag: "ok", value: 42 }
284
+ * toUpper(err("not found")) // { __tag: "err", error: "NOT FOUND" }
285
+ */
286
+ declare function mapErr<T, E, U>(fn: (error: E) => U): (self: Result<T, E>) => Result<T, U>;
287
+ declare function mapErr<T, E, U>(self: Result<T, E>, fn: (error: E) => U): Result<T, U>;
288
+ /**
289
+ * Pattern matches on a Result, calling onOk if successful or onErr if failed
290
+ * @example
291
+ * const result = ok(42);
292
+ * match(result, {
293
+ * onOk: (x) => `Got ${x}`,
294
+ * onErr: (e) => `Error: ${e}`
295
+ * }) // "Got 42"
296
+ *
297
+ * const error = err("not found");
298
+ * match(error, {
299
+ * onOk: (x) => `Got ${x}`,
300
+ * onErr: (e) => `Error: ${e}`
301
+ * }) // "Error: not found"
302
+ */
303
+ declare function match<T, E, U>(handlers: {
304
+ onOk: (value: T) => U;
305
+ onErr: (error: E) => U;
306
+ }): (self: Result<T, E>) => U;
307
+ declare function match<T, E, U, V>(self: Result<T, E>, handlers: {
308
+ onOk: (value: T) => U;
309
+ onErr: (error: E) => V;
310
+ }): U | V;
311
+ /**
312
+ * Returns the value of a successful Result, or null if it's a failure
313
+ * @example
314
+ * const result = ok(42);
315
+ * getOrNull(result) // 42
316
+ *
317
+ * const error = err("not found");
318
+ * getOrNull(error) // null
319
+ */
320
+ declare const getOrNull: <T, E>(result: Result<T, E>) => T | null;
321
+ /**
322
+ * Returns the error of a failed Result, or null if it's a success
323
+ * @example
324
+ * const result = ok(42);
325
+ * getErrorOrNull(result) // null
326
+ *
327
+ * const error = err("not found");
328
+ * getErrorOrNull(error) // "not found"
329
+ */
330
+ declare const getErrorOrNull: <T, E>(result: Result<T, E>) => E | null;
331
+ /**
332
+ * Returns the value of a successful Result, or a fallback value if it's a failure
333
+ * @example
334
+ * const result = ok(42);
335
+ * getOrElse(result, 0) // 42
336
+ *
337
+ * const error = err("not found");
338
+ * getOrElse(error, 0) // 0
339
+ */
340
+ declare const getOrElse: <T, E>(result: Result<T, E>, fallback: T) => T;
341
+ /**
342
+ * Returns the value of a successful Result, or throws the error if it's a failure
343
+ * @example
344
+ * const result = ok(42);
345
+ * getOrThrow(result) // 42
346
+ *
347
+ * const error = err("not found");
348
+ * getOrThrow(error) // throws "not found"
349
+ */
350
+ declare const getOrThrow: <T, E>(result: Result<T, E>) => T;
351
+ /**
352
+ * Returns the value of a successful Result, or throws a transformed error if it's a failure
353
+ * @example
354
+ * const result = ok(42);
355
+ * getOrThrowWith(result, (e) => new Error(e)) // 42
356
+ *
357
+ * const error = err("not found");
358
+ * getOrThrowWith(error, (e) => new Error(e)) // throws Error("not found")
359
+ */
360
+ declare function getOrThrowWith<T, E, R>(fn: (error: E) => R): (self: Result<T, E>) => T;
361
+ declare function getOrThrowWith<T, E, R>(self: Result<T, E>, fn: (error: E) => R): T;
362
+ /**
363
+ * Handles an error with a specific tag by running a callback function
364
+ * @example
365
+ * type NetworkError = { tag: "timeout"; duration: number } | { tag: "offline" };
366
+ *
367
+ * const error: NetworkError = { tag: "timeout", duration: 5000 };
368
+ * catchError(error, "timeout", (e) => {
369
+ * console.log(`Request timed out after ${e.duration}ms`);
370
+ * });
371
+ *
372
+ * const result = err<number, NetworkError>({ tag: "offline" });
373
+ * catchError(result, "offline", () => {
374
+ * console.log("No internet connection");
375
+ * }); // { __tag: "ok", value: null }
376
+ */
377
+ declare function catchError<T, E extends {
378
+ tag: string;
379
+ }, Tag extends E['tag']>(result: Result<T, E>, tag: Tag, fn: (error: Extract<E, {
380
+ tag: Tag;
381
+ }>) => void): Result<T, Exclude<E, {
382
+ tag: Tag;
383
+ }>>;
384
+ declare function catchError<T, E extends {
385
+ tag: string;
386
+ }, Tag extends E['tag']>(error: E, tag: Tag, fn: (error: Extract<E, {
387
+ tag: Tag;
388
+ }>) => void): void;
389
+ declare function catchError<T, E extends {
390
+ tag: string;
391
+ }, Tag extends E['tag']>(tag: Tag, fn: (error: Extract<E, {
392
+ tag: Tag;
393
+ }>) => void): (result: Result<T, E>) => Result<T, Exclude<E, {
394
+ tag: Tag;
395
+ }>>;
396
+ declare function catchError<T, E extends {
397
+ tag: string;
398
+ }, Tag extends E['tag']>(tag: Tag, fn: (error: Extract<E, {
399
+ tag: Tag;
400
+ }>) => void): (error: E) => void;
401
+ /**
402
+ * Catches all errors in a Result by running a callback function
403
+ * @param result - The Result to handle errors for
404
+ * @param fn - Function to handle any error
405
+ * @returns The original Result
406
+ * @example
407
+ * const result = err<number, string>("not found");
408
+ *
409
+ * // Direct style
410
+ * catchAllErrors(result, (e) => {
411
+ * console.log(`Error occurred: ${e}`);
412
+ * }); // { __tag: "ok", value: null }
413
+ *
414
+ * // Curried style
415
+ * const handleError = catchAllErrors((e: string) => {
416
+ * console.log(`Error occurred: ${e}`);
417
+ * });
418
+ * handleError(result); // { __tag: "ok", value: null }
419
+ */
420
+ declare function catchAllErrors<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, never>;
421
+ declare function catchAllErrors<T, E>(fn: (error: E) => void): (result: Result<T, E>) => Result<T, never>;
422
+ /**
423
+ * Catches specific error tags using handler functions
424
+ * @param result - The Result to handle errors for
425
+ * @param handlers - Object mapping error tags to handler functions
426
+ * @returns Result with handled error tags excluded from error type
427
+ * @example
428
+ * type NetworkError = { tag: "timeout"; duration: number } | { tag: "offline" };
429
+ *
430
+ * const result = err<number, NetworkError>({ tag: "timeout", duration: 5000 });
431
+ * catchErrors(result, {
432
+ * timeout: (e) => console.log(`Timed out after ${e.duration}ms`),
433
+ * offline: () => console.log("No internet connection")
434
+ * }); // { __tag: "ok", value: null }
435
+ */
436
+ declare function catchErrors<T, E extends {
437
+ tag: string;
438
+ }, Key extends E['tag']>(result: Result<T, E>, handlers: {
439
+ [K in Key]?: (error: Extract<E, {
440
+ tag: K;
441
+ }>) => void;
442
+ }): Result<T, Exclude<E, {
443
+ tag: keyof typeof handlers;
444
+ }>>;
445
+ declare function catchErrors<T, E extends {
446
+ tag: string;
447
+ }, Key extends E['tag']>(handlers: {
448
+ [K in Key]?: (error: Extract<E, {
449
+ tag: K;
450
+ }>) => void;
451
+ }): (result: Result<T, E>) => Result<T, Exclude<E, {
452
+ tag: keyof typeof handlers;
453
+ }>>;
454
+ /**
455
+ * Creates a chainable pipeline to transform a Result through a series of operations.
456
+ * @param result - The initial Result to transform
457
+ * @param ab - First transformation function to apply to the Result
458
+ * @returns A chainable function with pipe() for adding more transformations and execute() to run the pipeline
459
+ * @example
460
+ * pipe(
461
+ * ok(5),
462
+ * (a) => ok(a.value * 2)
463
+ * )
464
+ * .pipe(b => ok(b.value + 1))
465
+ * .execute() // { __tag: "ok", value: 11 }
466
+ */
467
+ declare const pipe: <AI, AE, BI, BE>(result: Result<AI, AE>, ab: (a: Result<AI, AE>) => Result<BI, BE>) => {
468
+ (a: Result<AI, AE>): Result<BI, BE>;
469
+ pipe<CI, CE>(bc: (b: Result<BI, BE>) => Result<CI, CE>): {
470
+ (a: Result<AI, AE>): Result<CI, CE>;
471
+ pipe<CI_1, CE_1>(bc: (b: Result<CI, CE>) => Result<CI_1, CE_1>): {
472
+ (a: Result<AI, AE>): Result<CI_1, CE_1>;
473
+ pipe<CI_2, CE_2>(bc: (b: Result<CI_1, CE_1>) => Result<CI_2, CE_2>): {
474
+ (a: Result<AI, AE>): Result<CI_2, CE_2>;
475
+ pipe<CI_3, CE_3>(bc: (b: Result<CI_2, CE_2>) => Result<CI_3, CE_3>): {
476
+ (a: Result<AI, AE>): Result<CI_3, CE_3>;
477
+ pipe<CI_4, CE_4>(bc: (b: Result<CI_3, CE_3>) => Result<CI_4, CE_4>): {
478
+ (a: Result<AI, AE>): Result<CI_4, CE_4>;
479
+ pipe<CI_5, CE_5>(bc: (b: Result<CI_4, CE_4>) => Result<CI_5, CE_5>): {
480
+ (a: Result<AI, AE>): Result<CI_5, CE_5>;
481
+ pipe<CI_6, CE_6>(bc: (b: Result<CI_5, CE_5>) => Result<CI_6, CE_6>): {
482
+ (a: Result<AI, AE>): Result<CI_6, CE_6>;
483
+ pipe<CI_7, CE_7>(bc: (b: Result<CI_6, CE_6>) => Result<CI_7, CE_7>): {
484
+ (a: Result<AI, AE>): Result<CI_7, CE_7>;
485
+ pipe<CI_8, CE_8>(bc: (b: Result<CI_7, CE_7>) => Result<CI_8, CE_8>): {
486
+ (a: Result<AI, AE>): Result<CI_8, CE_8>;
487
+ pipe<CI_9, CE_9>(bc: (b: Result<CI_8, CE_8>) => Result<CI_9, CE_9>): {
488
+ (a: Result<AI, AE>): Result<CI_9, CE_9>;
489
+ pipe<CI_10, CE_10>(bc: (b: Result<CI_9, CE_9>) => Result<CI_10, CE_10>): /*elided*/ any;
490
+ execute(): Result<CI_9, CE_9>;
491
+ };
492
+ execute(): Result<CI_8, CE_8>;
493
+ };
494
+ execute(): Result<CI_7, CE_7>;
495
+ };
496
+ execute(): Result<CI_6, CE_6>;
497
+ };
498
+ execute(): Result<CI_5, CE_5>;
499
+ };
500
+ execute(): Result<CI_4, CE_4>;
501
+ };
502
+ execute(): Result<CI_3, CE_3>;
503
+ };
504
+ execute(): Result<CI_2, CE_2>;
505
+ };
506
+ execute(): Result<CI_1, CE_1>;
507
+ };
508
+ execute(): Result<CI, CE>;
509
+ };
510
+ execute(): Result<BI, BE>;
511
+ };
512
+
513
+ type result_Err<E> = Err<E>;
514
+ type result_Ok<T> = Ok<T>;
515
+ type result_Result<T, E> = Result<T, E>;
516
+ declare const result_catchAllErrors: typeof catchAllErrors;
517
+ declare const result_catchError: typeof catchError;
518
+ declare const result_catchErrors: typeof catchErrors;
519
+ declare const result_err: typeof err;
520
+ declare const result_getErrorOrNull: typeof getErrorOrNull;
521
+ declare const result_getOrElse: typeof getOrElse;
522
+ declare const result_getOrNull: typeof getOrNull;
523
+ declare const result_getOrThrow: typeof getOrThrow;
524
+ declare const result_getOrThrowWith: typeof getOrThrowWith;
525
+ declare const result_isErr: typeof isErr;
526
+ declare const result_isOk: typeof isOk;
527
+ declare const result_map: typeof map;
528
+ declare const result_mapErr: typeof mapErr;
529
+ declare const result_match: typeof match;
530
+ declare const result_ok: typeof ok;
531
+ declare const result_pipe: typeof pipe;
532
+ declare namespace result {
533
+ export { type result_Err as Err, type result_Ok as Ok, type result_Result as Result, result_catchAllErrors as catchAllErrors, result_catchError as catchError, result_catchErrors as catchErrors, result_err as err, result_getErrorOrNull as getErrorOrNull, result_getOrElse as getOrElse, result_getOrNull as getOrNull, result_getOrThrow as getOrThrow, result_getOrThrowWith as getOrThrowWith, result_isErr as isErr, result_isOk as isOk, result_map as map, result_mapErr as mapErr, result_match as match, result_ok as ok, result_pipe as pipe };
534
+ }
535
+
536
+ /**
537
+ * Standard Schema is a common interface designed to be implemented by JavaScript and TypeScript schema libraries.
538
+ * Will support multiple schema validators including Zod, Valibot, and ArkType
539
+ * https://standardschema.dev/
540
+ */
541
+ /** The Standard Schema interface. */
542
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
543
+ /** The Standard Schema properties. */
544
+ readonly '~standard': StandardSchemaV1.Props<Input, Output>;
545
+ }
546
+ declare namespace StandardSchemaV1 {
547
+ /** The Standard Schema properties interface. */
548
+ interface Props<Input = unknown, Output = Input> {
549
+ /** The version number of the standard. */
550
+ readonly version: 1;
551
+ /** The vendor name of the schema library. */
552
+ readonly vendor: string;
553
+ /** Validates unknown input values. */
554
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
555
+ /** Inferred types associated with the schema. */
556
+ readonly types?: Types<Input, Output> | undefined;
557
+ }
558
+ /** The result interface of the validate function. */
559
+ type Result<Output> = SuccessResult<Output> | FailureResult;
560
+ /** The result interface if validation succeeds. */
561
+ interface SuccessResult<Output> {
562
+ /** The typed output value. */
563
+ readonly value: Output;
564
+ /** The non-existent issues. */
565
+ readonly issues?: undefined;
566
+ }
567
+ /** The result interface if validation fails. */
568
+ interface FailureResult {
569
+ /** The issues of failed validation. */
570
+ readonly issues: ReadonlyArray<Issue>;
571
+ }
572
+ /** The issue interface of the failure output. */
573
+ interface Issue {
574
+ /** The error message of the issue. */
575
+ readonly message: string;
576
+ /** The path of the issue, if any. */
577
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
578
+ }
579
+ /** The path segment interface of the issue. */
580
+ interface PathSegment {
581
+ /** The key representing a path segment. */
582
+ readonly key: PropertyKey;
583
+ }
584
+ /** The Standard Schema types interface. */
585
+ interface Types<Input = unknown, Output = Input> {
586
+ /** The input type of the schema. */
587
+ readonly input: Input;
588
+ /** The output type of the schema. */
589
+ readonly output: Output;
590
+ }
591
+ /** Infers the input type of a Standard Schema. */
592
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
593
+ /** Infers the output type of a Standard Schema. */
594
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
595
+ }
596
+
597
+ /**
598
+ * A class for building and executing HTTP requests with customizable options and error handling.
599
+ * @template Method The HTTP method type (GET, POST, etc.)
600
+ * @template TRequest The request configuration type extending RequestInit
601
+ * @template Opts Additional options type for custom configurations
602
+ * @example
603
+ * // Create a new request instance
604
+ * const request = new Request('/api/users', {
605
+ * baseUrl: 'https://example.com',
606
+ * headers: { 'Content-Type': 'application/json' }
607
+ * });
608
+ *
609
+ * // Configure and execute the request
610
+ * const result = await request
611
+ * .setQueryParams({ page: '1' })
612
+ * .setBearer('token123')
613
+ * .notFound(() => ({ message: 'Not found' }))
614
+ * .withResult()
615
+ * .json<User>();
616
+ */
617
+ declare class Request<Method extends HttpMethods, TRequest extends AspiRequestInit = AspiRequestInit, Opts extends Record<any, any> = {
618
+ error: {};
619
+ }> {
620
+ #private;
621
+ constructor(method: HttpMethods, path: string, { requestConfig, retryConfig, middlewares, errorCbs, }: RequestOptions<TRequest>);
622
+ /**
623
+ * Sets the base URL for the request.
624
+ * @param url The base URL to set
625
+ * @returns The request instance for chaining
626
+ * @example
627
+ * const request = new Request('/users', config);
628
+ * request.setBaseUrl('https://api.example.com');
629
+ */
630
+ setBaseUrl(url: string): this;
631
+ /**
632
+ * Sets the retry configuration for the request.
633
+ * @param retry The retry configuration object
634
+ * @returns The request instance for chaining
635
+ * @example
636
+ * const request = new Request('/users', config);
637
+ * request.setRetry({
638
+ * retries: 3, // Number of retry attempts
639
+ * retryDelay: 1000, // Delay between retries in ms
640
+ * retryOn: [500, 502, 503], // Status codes to retry on
641
+ * retryWhile: (request, response) => response.status >= 500 // Custom retry condition
642
+ * });
643
+ */
644
+ setRetry(retry: AspiRetryConfig<TRequest>): this;
645
+ /**
646
+ * Sets multiple headers for the request.
647
+ * @param headers An object containing header key-value pairs
648
+ * @returns The request instance for chaining
649
+ * @example
650
+ * const request = new Request('/users', config);
651
+ * request.setHeaders({
652
+ * 'Content-Type': 'application/json',
653
+ * 'Accept': 'application/json'
654
+ * });
655
+ */
656
+ setHeaders(headers: Record<string, string>): this;
657
+ /**
658
+ * Sets a single header for the request.
659
+ * @param key The header key
660
+ * @param value The header value
661
+ * @returns The request instance for chaining
662
+ * @example
663
+ * const request = new Request('/users', config);
664
+ * request.setHeader('Content-Type', 'application/json');
665
+ */
666
+ setHeader(key: string, value: string): this;
667
+ /**
668
+ * Sets the Authorization header with a bearer token.
669
+ * @param token The bearer token to set
670
+ * @returns The request instance for chaining
671
+ * @example
672
+ * const request = new Request('/users', config);
673
+ * request.setBearer('my-auth-token');
674
+ */
675
+ setBearer(token: string): this;
676
+ /**
677
+ * Sets a validation schema for the request body using a StandardSchemaV1 schema.
678
+ * @template TSchema Type parameter extending StandardSchemaV1
679
+ * @param schema The schema to validate the body against
680
+ * @returns The request instance for chaining with updated error type
681
+ * @example
682
+ * const userSchema = z.object({
683
+ * name: z.string(),
684
+ * email: z.string().email()
685
+ * });
686
+ *
687
+ * const request = new Request('/users', config);
688
+ * request
689
+ * .bodySchema(userSchema)
690
+ * .bodyJson({
691
+ * name: 'John',
692
+ * email: 'john@example.com'
693
+ * });
694
+ */
695
+ bodySchema<TSchema extends StandardSchemaV1>(schema: TSchema): Request<Method, TRequest, Omit<Opts, "bodySchema"> & {
696
+ bodySchema: TSchema;
697
+ error: Opts["error"] & {
698
+ parseError: CustomError<"parseError", StandardSchemaV1.FailureResult["issues"]>;
699
+ };
700
+ }>;
701
+ /**
702
+ * Sets the request body as JSON by automatically stringifying the provided object.
703
+ * @param body The object to be stringified and sent as the request body
704
+ * @returns The request instance for chaining
705
+ * @example
706
+ * const request = new Request('/users', config);
707
+ * request.bodyJson({
708
+ * name: 'John Doe',
709
+ * email: 'john@example.com',
710
+ * age: 30
711
+ * });
712
+ */
713
+ bodyJson<Body extends StandardSchemaV1.InferInput<Opts['bodySchema']>>(body: Body): Request<Method, TRequest, Omit<Opts, "body"> & {
714
+ body: Body;
715
+ }>;
716
+ /**
717
+ * Sets the raw request body (unsafe, use with caution).
718
+ * @param body The body content to send with the request
719
+ * @returns The request instance for chaining
720
+ * @example
721
+ * const request = new Request('/users', config);
722
+ * request.unsafeBody(new FormData());
723
+ *
724
+ * // or with raw text
725
+ * request.unsafeBody('Hello World');
726
+ *
727
+ * // or with URLSearchParams
728
+ * request.unsafeBody(new URLSearchParams({ key: 'value' }));
729
+ */
730
+ unsafeBody(body: BodyInit): Request<Method, TRequest, Omit<Opts, "body"> & {
731
+ body: BodyInit;
732
+ }>;
733
+ /**
734
+ * Handles 404 Not Found errors with a custom callback.
735
+ * @param cb The callback function to handle the error
736
+ * @returns The request instance for chaining
737
+ * @example
738
+ * const request = new Request('/users', config);
739
+ * request.notFound((error) => {
740
+ * console.log('Resource not found:', error);
741
+ * return { message: 'Custom not found message' };
742
+ * });
743
+ */
744
+ notFound<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
745
+ error: { [K in "notFoundError" | keyof Opts["error"]]: K extends "notFoundError" ? CustomError<"notFoundError", A> : Opts["error"][K]; };
746
+ }>;
747
+ /**
748
+ * Handles 429 Too Many Requests errors with a custom callback.
749
+ * @param cb The callback function to handle the error
750
+ * @returns The request instance for chaining
751
+ * @example
752
+ * const request = new Request('/users', config);
753
+ * request.tooManyRequests((error) => {
754
+ * console.log('Rate limited:', error);
755
+ * return { message: 'Please try again later' };
756
+ * });
757
+ */
758
+ tooManyRequests<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
759
+ error: { [K in keyof Opts["error"] | "tooManyRequestsError"]: K extends "tooManyRequestsError" ? CustomError<"tooManyRequestsError", A> : Opts["error"][K]; };
760
+ }>;
761
+ /**
762
+ * Handles 400 Bad Request errors with a custom callback.
763
+ * @param cb The callback function to handle the error
764
+ * @returns The request instance for chaining
765
+ * @example
766
+ * const request = new Request('/users', config);
767
+ * request.badRequest((error) => {
768
+ * console.log('Bad request error:', error);
769
+ * return { message: 'Invalid request parameters' };
770
+ * });
771
+ */
772
+ badRequest<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
773
+ error: { [K in keyof Opts["error"] | "badRequestError"]: K extends "badRequestError" ? CustomError<"badRequestError", A> : Opts["error"][K]; };
774
+ }>;
775
+ /**
776
+ * Handles 409 Conflict errors with a custom callback.
777
+ * @param cb The callback function to handle the error
778
+ * @returns The request instance for chaining
779
+ * @example
780
+ * const request = new Request('/users', config);
781
+ * request.conflict((error) => {
782
+ * console.log('Conflict error:', error);
783
+ * return { message: 'Resource conflict detected' };
784
+ * });
785
+ */
786
+ conflict<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
787
+ error: { [K in keyof Opts["error"] | "conflictError"]: K extends "conflictError" ? CustomError<"conflictError", A> : Opts["error"][K]; };
788
+ }>;
789
+ /**
790
+ * Handles 401 Unauthorized errors with a custom callback.
791
+ * @param cb The callback function to handle the error
792
+ * @returns The request instance for chaining
793
+ * @example
794
+ * const request = new Request('/users', config);
795
+ * request.unauthorised((error) => {
796
+ * console.log('Unauthorized access:', error);
797
+ * return { message: 'Please login first' };
798
+ * });
799
+ */
800
+ unauthorised<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
801
+ error: { [K in keyof Opts["error"] | "unauthorisedError"]: K extends "unauthorisedError" ? CustomError<"unauthorisedError", A> : Opts["error"][K]; };
802
+ }>;
803
+ /**
804
+ * Handles 403 Forbidden errors with a custom callback.
805
+ * @param cb The callback function to handle the error
806
+ * @returns The request instance for chaining
807
+ * @example
808
+ * const request = new Request('/users', config);
809
+ * request.forbidden((error) => {
810
+ * console.log('Access forbidden:', error);
811
+ * return { message: 'You do not have permission' };
812
+ * });
813
+ */
814
+ forbidden<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
815
+ error: { [K in keyof Opts["error"] | "forbiddenError"]: K extends "forbiddenError" ? CustomError<"forbiddenError", A> : Opts["error"][K]; };
816
+ }>;
817
+ /**
818
+ * Handles 501 Not Implemented errors with a custom callback.
819
+ * @param cb The callback function to handle the error
820
+ * @returns The request instance for chaining
821
+ * @example
822
+ * const request = new Request('/users', config);
823
+ * request.notImplemented((error) => {
824
+ * console.log('Not implemented:', error);
825
+ * return { message: 'This feature is not implemented yet' };
826
+ * });
827
+ */
828
+ notImplemented<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
829
+ error: { [K in keyof Opts["error"] | "notImplementedError"]: K extends "notImplementedError" ? CustomError<"notImplementedError", A> : Opts["error"][K]; };
830
+ }>;
831
+ /**
832
+ * Handles 500 Internal Server Error errors with a custom callback.
833
+ * @param cb The callback function to handle the error
834
+ * @returns The request instance for chaining
835
+ * @example
836
+ * const request = new Request('/users', config);
837
+ * request.internalServerError((error) => {
838
+ * console.log('Server error:', error);
839
+ * return { message: 'An unexpected error occurred' };
840
+ * });
841
+ */
842
+ internalServerError<A extends {}>(cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
843
+ error: { [K in keyof Opts["error"] | "internalServerError"]: K extends "internalServerError" ? CustomError<"internalServerError", A> : Opts["error"][K]; };
844
+ }>;
845
+ /**
846
+ * Sets a custom error handler for a specific HTTP status code.
847
+ * @param tag A string identifier for the error type
848
+ * @param status The HTTP error status to handle
849
+ * @param cb The callback function to handle the error
850
+ * @returns The request instance for chaining
851
+ * @example
852
+ * const request = new Request('/users', config);
853
+ * request
854
+ .withResult()
855
+ .error('customError', 'BAD_REQUEST', (error) => {
856
+ * console.log('Bad request error:', error);
857
+ * return {
858
+ * message: 'Invalid input',
859
+ * details: error.response.responseData
860
+ * };
861
+ * });
862
+ *
863
+ * // Later when making the request:
864
+ * const result = await request.json();
865
+ * if (Result.isErr(result)) {
866
+ * if(result.tag === 'customError') {
867
+ * console.log(result.error.data.message); // 'Invalid input'
868
+ * }
869
+ */
870
+ error<Tag extends string, A extends {}>(tag: Tag, status: HttpErrorStatus, cb: CustomErrorCb<TRequest, A>): Request<Method, TRequest, Omit<Opts, "error"> & {
871
+ error: { [K in Tag | keyof Opts["error"]]: K extends Tag ? CustomError<Tag, A> : Opts["error"][K]; };
872
+ }>;
873
+ /**
874
+ * Sets query parameters for the request URL.
875
+ * @param params An object containing query parameter key-value pairs
876
+ * @returns The request instance for chaining
877
+ * @example
878
+ * const request = new Request('/users', config);
879
+ * request.setQueryParams({
880
+ * page: '1',
881
+ * limit: '10',
882
+ * sort: 'desc'
883
+ * });
884
+ */
885
+ setQueryParams<T extends Record<string, string> | string[][] | string | URLSearchParams>(params: T): Request<Method, TRequest, Omit<Opts, "queryParams"> & {
886
+ qyeryParams: T;
887
+ }>;
888
+ /**
889
+ * Sets the output schema for validating the response data using Zod.
890
+ * @param schema The Zod schema to validate the response
891
+ * @returns The request instance for chaining
892
+ * @example
893
+ * import { z } from 'zod';
894
+ *
895
+ * const userSchema = z.object({
896
+ * id: z.number(),
897
+ * name: z.string(),
898
+ * email: z.string().email()
899
+ * });
900
+ *
901
+ * const request = new Request('/users', config);
902
+ * const result = await request
903
+ * .withResult()
904
+ * .output(userSchema)
905
+ * .json();
906
+ *
907
+ * if (Result.isOk(result)) {
908
+ * const user = result.value; // Typed and validated user data
909
+ * }
910
+ */
911
+ schema<TSchema extends StandardSchemaV1>(schema: TSchema): Request<Method, TRequest, Omit<Opts, "schema"> & {
912
+ schema: TSchema;
913
+ error: Opts["error"] & {
914
+ parseError: CustomError<"parseError", StandardSchemaV1.FailureResult["issues"]>;
915
+ };
916
+ }>;
917
+ /**
918
+ * Executes the request and returns the JSON response.
919
+ * @returns A Promise containing the Result type with either successful data or error information
920
+ * @example
921
+ * const request = new Request('/users', config);
922
+ * const result = await request
923
+ * .setQueryParams({ id: '123' })
924
+ * .withResult()
925
+ * .notFound((error) => ({ message: 'User not found' }))
926
+ * .json<User>();
927
+ *
928
+ * if (Result.isOk(result)) {
929
+ * const user = result.value; // User data
930
+ * } else {
931
+ * console.error(result.error); // Error handling
932
+ * }
933
+ */
934
+ json<T extends StandardSchemaV1.InferOutput<Opts['schema']>>(): Promise<Opts['withResult'] extends true ? Result<AspiResultOk<TRequest, T>, AspiError<TRequest> | (Opts extends {
935
+ error: any;
936
+ } ? Opts['error'][keyof Opts['error']] : never) | JSONParseError> : [
937
+ AspiResultOk<TRequest, T> | null,
938
+ ((AspiError<TRequest> | (Opts extends {
939
+ error: any;
940
+ } ? Opts['error'][keyof Opts['error']] : never) | JSONParseError) | null)
941
+ ]>;
942
+ /**
943
+ * Executes the request and returns the response as plain text.
944
+ * @returns A Promise containing the Result type with either successful text data or error information
945
+ * @example
946
+ * const request = new Request('/data.txt', config);
947
+ * const result = await request
948
+ * .setQueryParams({ version: '1' })
949
+ * .withResult()
950
+ * .notFound((error) => ({ message: 'Text file not found' }))
951
+ * .text();
952
+ *
953
+ * if (Result.isOk(result)) {
954
+ * const text = result.value; // Plain text content
955
+ * } else {
956
+ * console.error(result.error); // Error handling
957
+ * }
958
+ */
959
+ text(): Promise<Opts['withResult'] extends true ? Result<AspiResultOk<TRequest, string>, AspiError<TRequest> | (Opts extends {
960
+ error: any;
961
+ } ? Opts['error'][keyof Opts['error']] : never)> : [
962
+ AspiResultOk<TRequest, string> | null,
963
+ ((AspiError<TRequest> | (Opts extends {
964
+ error: any;
965
+ } ? Opts['error'][keyof Opts['error']] : never)) | null)
966
+ ]>;
967
+ /**
968
+ * Executes the request and returns the response as a Blob.
969
+ * @returns A Promise containing the Result type with either successful Blob data or error information
970
+ * @example
971
+ * const request = new Request('/image.jpg', config);
972
+ * const result = await request
973
+ * .setQueryParams({ size: 'large' })
974
+ * .withResult()
975
+ * .notFound((error) => ({ message: 'Image not found' }))
976
+ * .blob();
977
+ *
978
+ * if (Result.isOk(result)) {
979
+ * const imageBlob = result.value; // Blob data
980
+ * } else {
981
+ * console.error(result.error); // Error handling
982
+ * }
983
+ */
984
+ blob(): Promise<Opts['withResult'] extends true ? Result<AspiResultOk<TRequest, Blob>, AspiError<TRequest> | (Opts extends {
985
+ error: any;
986
+ } ? Opts['error'][keyof Opts['error']] : never)> : [
987
+ AspiResultOk<TRequest, Blob> | null,
988
+ ((AspiError<TRequest> | (Opts extends {
989
+ error: any;
990
+ } ? Opts['error'][keyof Opts['error']] : never)) | null)
991
+ ]>;
992
+ /**
993
+ * Returns the complete URL for the request including base URL, path, and query parameters.
994
+ * @returns The complete URL string
995
+ * @example
996
+ * const request = new Request('/users', config);
997
+ * request.setBaseUrl('https://api.example.com');
998
+ * request.setQueryParams({ id: '123' });
999
+ * console.log(request.url()); // 'https://api.example.com/users?id=123'
1000
+ */
1001
+ url(): string;
1002
+ /**
1003
+ * Configures the request to return a Result type instead of a tuple.
1004
+ * @returns The request instance for chaining with Result type return value
1005
+ * @example
1006
+ * const request = new Request('/users', config);
1007
+ * const result = await request
1008
+ * .withResult()
1009
+ * .json<User>();
1010
+ *
1011
+ * // Returns Result type instead of tuple
1012
+ * if (Result.isOk(result)) {
1013
+ * const user = result.value;
1014
+ * }
1015
+ */
1016
+ withResult(): Request<Method, TRequest, Omit<Opts, "withResult"> & {
1017
+ withResult: true;
1018
+ }>;
1019
+ }
1020
+
1021
+ /**
1022
+ * A class for making API requests with a base URL and configurable options
1023
+ * @template TRequest - Type extending RequestInit for request configuration
1024
+ * @example
1025
+ * const api = new Aspi({
1026
+ * baseUrl: 'https://api.example.com',
1027
+ * headers: {
1028
+ * 'Content-Type': 'application/json'
1029
+ * }
1030
+ * });
1031
+ *
1032
+ * // Make requests
1033
+ * const users = await api.get('/users').json();
1034
+ * const user = await api.post('/users', { name: 'John' }).json();
1035
+ */
1036
+ declare class Aspi<TRequest extends AspiRequestInit = AspiRequestInit, Opts extends Record<any, any> = {}> {
1037
+ #private;
1038
+ constructor(config: AspiConfig);
1039
+ /**
1040
+ * Sets the base URL for all API requests
1041
+ * @param {string} url - The base URL to be set
1042
+ * @returns {Aspi} The Aspi instance for chaining
1043
+ * @example
1044
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1045
+ * api.setBaseUrl('https://api.newdomain.com');
1046
+ */
1047
+ setBaseUrl(url: string): this;
1048
+ /**
1049
+ * Sets the retry configuration for failed requests
1050
+ * @param {AspiRetryConfig<TRequest>} retry - The retry configuration object
1051
+ * @returns {Aspi} The Aspi instance for chaining
1052
+ * @example
1053
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1054
+ * api.setRetry({
1055
+ * retries: 3,
1056
+ * retryDelay: 1000,
1057
+ * retryOn: [500, 502],
1058
+ * retryWhile: (req, res) => res.status === 500
1059
+ * });
1060
+ */
1061
+ setRetry(retry: AspiRetryConfig<TRequest>): this;
1062
+ /**
1063
+ * Makes a GET request to the specified path
1064
+ * @param {string} path - The path to make the request to
1065
+ * @returns {Request} A Request instance for chaining
1066
+ * @example
1067
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1068
+ * const response = await api.get('/users').json();
1069
+ */
1070
+ get(path: string): Request<"GET", TRequest, Opts>;
1071
+ /**
1072
+ * Makes a POST request to the specified path with an optional body
1073
+ * @param {string} path - The path to make the request to
1074
+ * @param {BodyInit} [body] - The body of the request
1075
+ * @returns {Request} A Request instance for chaining
1076
+ * @example
1077
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1078
+ * const response = await api.post('/users', { name: 'John' }).json();
1079
+ */
1080
+ post(path: string, body?: BodyInit): Request<"POST", TRequest, Opts>;
1081
+ /**
1082
+ * Makes a PUT request to the specified path with an optional body
1083
+ * @param {string} path - The path to make the request to
1084
+ * @param {BodyInit} [body] - The body of the request
1085
+ * @returns {Request} A Request instance for chaining
1086
+ * @example
1087
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1088
+ * const response = await api.put('/users/1', { name: 'John' }).json();
1089
+ */
1090
+ put(path: string, body?: BodyInit): Request<"PUT", TRequest, Opts>;
1091
+ /**
1092
+ * Makes a PATCH request to the specified path with an optional body
1093
+ * @param {string} path - The path to make the request to
1094
+ * @param {BodyInit} [body] - The body of the request
1095
+ * @returns {Request} A Request instance for chaining
1096
+ * @example
1097
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1098
+ * const response = await api.patch('/users/1', { name: 'John' }).json();
1099
+ */
1100
+ patch(path: string, body?: BodyInit): Request<"PATCH", TRequest, Opts>;
1101
+ /**
1102
+ * Makes a DELETE request to the specified path
1103
+ * @param {string} path - The path to make the request to
1104
+ * @returns {Request} A Request instance for chaining
1105
+ * @example
1106
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1107
+ * const response = await api.delete('/users/1').json();
1108
+ */
1109
+ delete(path: string): Request<"DELETE", TRequest, Opts>;
1110
+ /**
1111
+ * Makes a HEAD request to the specified path
1112
+ * @param {string} path - The path to make the request to
1113
+ * @returns {Request} A Request instance for chaining
1114
+ * @example
1115
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1116
+ * const response = await api.head('/users').json();
1117
+ */
1118
+ head(path: string): Request<"HEAD", TRequest, Opts>;
1119
+ /**
1120
+ * Makes an OPTIONS request to the specified path
1121
+ * @param {string} path - The path to make the request to
1122
+ * @returns {Request} A Request instance for chaining
1123
+ * @example
1124
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1125
+ * const response = await api.options('/users').json();
1126
+ */
1127
+ options(path: string): Request<"OPTIONS", TRequest, Opts>;
1128
+ /**
1129
+ * Sets multiple headers for all API requests
1130
+ * @param {Record<string, string>} headers - An object containing header key-value pairs
1131
+ * @returns {Aspi} The Aspi instance for chaining
1132
+ * @example
1133
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1134
+ * api.setHeaders({
1135
+ * 'Content-Type': 'application/json',
1136
+ * 'Accept': 'application/json'
1137
+ * });
1138
+ */
1139
+ setHeaders(headers: Record<string, string>): this;
1140
+ /**
1141
+ * Sets a single header for all API requests
1142
+ * @param {string} key - The header key
1143
+ * @param {string} value - The header value
1144
+ * @returns {Aspi} The Aspi instance for chaining
1145
+ * @example
1146
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1147
+ * api.setHeader('Content-Type', 'application/json');
1148
+ */
1149
+ setHeader(key: string, value: string): this;
1150
+ /**
1151
+ * Sets the Authorization header with a Bearer token
1152
+ * @param {string} token - The Bearer token
1153
+ * @returns {Aspi} The Aspi instance for chaining
1154
+ * @example
1155
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1156
+ * api.setBearer('myAuthToken123');
1157
+ */
1158
+ setBearer(token: string): this;
1159
+ /**
1160
+ * Use a middleware function to transform requests
1161
+ * @param {Middleware<T, U>} fn - The middleware function to apply
1162
+ * @returns {Aspi<U>} A new Aspi instance with the applied middleware
1163
+ * @example
1164
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1165
+ * api.use((req) => {
1166
+ * // Add custom headers
1167
+ * req.headers = {
1168
+ * ...req.headers,
1169
+ * 'x-custom-header': 'custom-value'
1170
+ * };
1171
+ * return req;
1172
+ * });
1173
+ */
1174
+ use<T extends TRequest, U extends TRequest>(fn: Middleware<T, U>): Aspi<U>;
1175
+ /**
1176
+ * Registers a custom error handler for a specific HTTP status
1177
+ * @param {string} tag - The error tag identifier
1178
+ * @param {HttpErrorStatus} status - The HTTP status code to handle
1179
+ * @param {CustomErrorCb<TRequest, A>} cb - The callback function to handle the error
1180
+ * @returns {Aspi} The Aspi instance for chaining
1181
+ * @example
1182
+ * const api = new Aspi({ baseUrl: 'https://api.example.com' });
1183
+ * api.error('customError', 'BAD_REQUEST', (req, res) => {
1184
+ * console.log('Bad request error occurred');
1185
+ * return { message: 'Invalid input' };
1186
+ * });
1187
+ */
1188
+ error<Tag extends string, A extends {}>(tag: Tag, status: HttpErrorStatus, cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1189
+ error: { [K in Tag | keyof Opts["error"]]: K extends Tag ? CustomError<Tag, A> : Opts["error"][K]; };
1190
+ }>;
1191
+ /**
1192
+ * Handles 404 Not Found errors with a custom callback.
1193
+ * @param cb The callback function to handle the error
1194
+ * @returns The request instance for chaining
1195
+ * @example
1196
+ * const request = new Request('/users', config);
1197
+ * request.notFound((error) => {
1198
+ * console.log('Not found:', error);
1199
+ * return { message: 'Resource not found' };
1200
+ * });
1201
+ */
1202
+ notFound<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1203
+ error: { [K in "notFoundError" | keyof Opts["error"]]: K extends "notFoundError" ? CustomError<"notFoundError", A> : Opts["error"][K]; };
1204
+ }>;
1205
+ /**
1206
+ * Handles 429 Too Many Requests errors with a custom callback.
1207
+ * @param cb The callback function to handle the error
1208
+ * @returns The request instance for chaining
1209
+ * @example
1210
+ * const request = new Request('/users', config);
1211
+ * request.tooManyRequests((error) => {
1212
+ * console.log('Rate limited:', error);
1213
+ * return { message: 'Please try again later' };
1214
+ * });
1215
+ */
1216
+ tooManyRequests<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1217
+ error: { [K in "tooManyRequestsError" | keyof Opts["error"]]: K extends "tooManyRequestsError" ? CustomError<"tooManyRequestsError", A> : Opts["error"][K]; };
1218
+ }>;
1219
+ /**
1220
+ * Handles 409 Conflict errors with a custom callback.
1221
+ * @param cb The callback function to handle the error
1222
+ * @returns The request instance for chaining
1223
+ * @example
1224
+ * const request = new Request('/users', config);
1225
+ * request.conflict((error) => {
1226
+ * console.log('Conflict error:', error);
1227
+ * return { message: 'Resource conflict detected' };
1228
+ * });
1229
+ */
1230
+ conflict<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1231
+ error: { [K in "conflictError" | keyof Opts["error"]]: K extends "conflictError" ? CustomError<"conflictError", A> : Opts["error"][K]; };
1232
+ }>;
1233
+ /**
1234
+ * Registers a handler for 400 Bad Request errors
1235
+ * @param {CustomErrorCb<TRequest, A>} cb - The callback function to handle the error
1236
+ * @returns {Aspi} The Aspi instance for chaining
1237
+ * @example
1238
+ * api.badRequest((req, res) => ({ message: 'Invalid request parameters' }));
1239
+ */
1240
+ badRequest<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1241
+ error: { [K in "badRequestError" | keyof Opts["error"]]: K extends "badRequestError" ? CustomError<"badRequestError", A> : Opts["error"][K]; };
1242
+ }>;
1243
+ /**
1244
+ * Registers a handler for 401 Unauthorized errors
1245
+ * @param {CustomErrorCb<TRequest, A>} cb - The callback function to handle the error
1246
+ * @returns {Aspi} The Aspi instance for chaining
1247
+ * @example
1248
+ * api.unauthorized((req, res) => ({ message: 'Authentication required' }));
1249
+ */
1250
+ unauthorized<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1251
+ error: { [K in keyof Opts["error"] | "unauthorizedError"]: K extends "unauthorizedError" ? CustomError<"unauthorizedError", A> : Opts["error"][K]; };
1252
+ }>;
1253
+ /**
1254
+ * Registers a handler for 403 Forbidden errors
1255
+ * @param {CustomErrorCb<TRequest, A>} cb - The callback function to handle the error
1256
+ * @returns {Aspi} The Aspi instance for chaining
1257
+ * @example
1258
+ * api.forbidden((req, res) => ({ message: 'Access denied' }));
1259
+ */
1260
+ forbidden<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1261
+ error: { [K in "forbiddenError" | keyof Opts["error"]]: K extends "forbiddenError" ? CustomError<"forbiddenError", A> : Opts["error"][K]; };
1262
+ }>;
1263
+ /**
1264
+ * Registers a handler for 501 Not Implemented errors
1265
+ * @param {CustomErrorCb<TRequest, A>} cb - The callback function to handle the error
1266
+ * @returns {Aspi} The Aspi instance for chaining
1267
+ * @example
1268
+ * api.notImplemented((req, res) => ({ message: 'Feature not implemented' }));
1269
+ */
1270
+ notImplemented<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1271
+ error: { [K in "notImplementedError" | keyof Opts["error"]]: K extends "notImplementedError" ? CustomError<"notImplementedError", A> : Opts["error"][K]; };
1272
+ }>;
1273
+ /**
1274
+ * Registers a handler for 500 Internal Server errors
1275
+ * @param {CustomErrorCb<TRequest, A>} cb - The callback function to handle the error
1276
+ * @returns {Aspi} The Aspi instance for chaining
1277
+ * @example
1278
+ * api.internalServerError((req, res) => ({ message: 'Server error occurred' }));
1279
+ */
1280
+ internalServerError<A extends {}>(cb: CustomErrorCb<TRequest, A>): Aspi<TRequest, Opts & {
1281
+ error: { [K in keyof Opts["error"] | "internalServerErrorError"]: K extends "internalServerErrorError" ? CustomError<"internalServerErrorError", A> : Opts["error"][K]; };
1282
+ }>;
1283
+ }
1284
+
1285
+ export { Aspi, type AspiConfig, type AspiConfigBase, AspiError, type AspiRequest, type AspiRequestInit, type AspiResponse, type AspiResultOk, type AspiRetryConfig, CustomError, type CustomErrorCb, type ErrorCallbacks, type HttpErrorCodes, type HttpErrorStatus, type HttpMethods, type JSONParseError, type Middleware, Request, type RequestOptions, result as Result, getHttpErrorStatus, httpErrors };